[Qt-interest] QSqlDatabase
Robert Hairgrove
evorgriahr at hispeed.ch
Thu Oct 1 13:27:56 CEST 2009
Riccardo Roasio wrote:
> Hi,
>
> i have a probelm with a QSqlDatabase object, it gives me this warning :
>
> QSqlDatabasePrivate::addDatabase: duplicate connection name
> 'qt_sql_default_connection', old connection removed.
>
> How can i solve this issue?
>
> The class that use the QSqlDatabase object is this one:
>
> #ifndef MYSQLCONNECTION_H
> #define MYSQLCONNECTION_H
>
> #include <QtSql>
> #include <QString>
> #include <QCoreApplication>
> #include <QSqlDatabase>
> #include <QSqlError>
> #include <QStringList>
> #include <QtDebug>
> #include <iostream>
>
> #include "logger.h"
>
> class MysqlConnection
> {
>
> public:
> MysqlConnection(QString host,QString database,QString
> username,QString password);
> void close();
> QSqlQuery query(QString q);
> bool opened();
>
> private:
> QString username;
> QString password;
> QString database;
> QString host;
> QString connection;
> QSqlDatabase db;
> bool op;
>
> Logger *logger;
> };
>
> #endif // MYSQLCONNECTION_H
>
>
> #include "mysqlconnection.h"
>
> MysqlConnection::MysqlConnection(QString h,QString d,QString u,QString p)
> {
> std::cout<<"1"<<std::endl;
> logger=new Logger();
>
> logger->logOnFile(" MysqlConnection","MysqlConnection","Opening
> connection.");
>
> host=h;
> database=d;
> username=u;
> password=p;
>
> logger->logOnFile(" MysqlConnection","MysqlConnection","Adding database.");
> db = QSqlDatabase::addDatabase("QMYSQL");
(rest snipped)
Please read this:
http://doc.trolltech.com/4.5/qsqldatabase.html#addDatabase
It says:
"Warning: If you add a connection with the same name as an existing
connection, the new connection replaces the old one. If you call this
function more than once without specifying connectionName, the default
connection will be the one replaced."
You have declared an object of QSqlDatabase as a member variable. It is
initialized, i.e. default constructed, by the time the body of your
constructor starts, as an invalid object since you have no constructor
initialization list. Inside the body of the constructor, you assign a
new database object to db which has the same effect as if you had called
QSqlDatabase::addDatabase twice.
It is possible to get around this by initializing the member variable in
the constructor's initialization list, i.e.:
MysqlConnection::MysqlConnection(QString h,QString d,
QString u,QString p)
: db(QSqlDatabase::addDatabase("QMYSQL", "my_connection"))
{
std::cout<<"1"<<std::endl;
logger=new Logger();
etc. Note that the default connection is not replaced here since you
have given it a name. It would also work to leave off the name, but then
the MySQL connection becomes the default connection; and if your
MysqlConnection object is ever destroyed and created again, you would
get the same error as before.
Unfortunately, there are other issues to worry about. You will need to
call QSqlDatabase::removeDatabase("my_connection") AFTER the member
object db is destroyed, which means you cannot do it inside the class
(not even in the destructor since member variables are destroyed only
after the destructor has run). Please refer to this document for details:
http://doc.trolltech.com/4.5/qsqldatabase.html#removeDatabase
Therefore, I think the only way to handle this properly is to make your
internal member a pointer, create it with new and destroy it with
delete. That way, you can handle the addDatabase() and removeDatabase()
calls in the proper order. But maybe there is an easier way ... for
example, you could probably make the member a static member, let it
become the default connection, and just call open() and close() on it as
you need to. When the application closes, I assume that the library
would clean up things properly, but I'm not sure if there would be a
leak somewhere. You would have to test it.
More information about the Qt-interest-old
mailing list