QsqlDatabase & QsqlQuery managed in a class -Error removeDatabase: connection 'qt_sql_default_connection' is still in use
-
wrote on 9 Feb 2022, 12:47 last edited by Kamigi 2 Sept 2022, 14:52
Hello Everyone,
I would like to create a class which can manage my sqlite db.
I've read already almost all topics regarding this error, but i still can't use it well.
- I tried to execute every QSqlQuery class declaration in the same scope than the db manager ( QsqlDatabase object ).
- I tried also to use pointers, local Member, no member of class ( declared each time by a QsqlDatabase::database(connectionName)
Please find a bit of code to do this :
file: query.hnamespace sql { /// Query Class : used to manage Database Structures, Queries, and DB Manipulation(create,update,open/close) class query : public QObject { Q_OBJECT public: explicit query(QObject *parent = nullptr); ~query(); [...] private: [...] void initDb(QSqlDatabase db); bool openDb(QSqlDatabase db); void closeDb(QSqlDatabase db); bool createDb(QSqlDatabase db); bool updateDb(QSqlDatabase db); signals: }; }
file : query.cpp
using namespace sql; query::query(QObject *parent) : QObject{parent} { // create db structure from JSON File _dbStruct = new skel::database(); // Custom Class to manage db structure // Init QSqlDatabase based on _dbStruct information QSqlDatabase sqlDb = QSqlDatabase::addDatabase(skel::database::TYPE[_dbStruct->type()]); // skel::database::TYPE[_dbStruct->type()] = "QSQLITE" sqlDb.setDatabaseName(_dbStruct->path() + _dbStruct->name()); // set up the sqlite file path & name _dbConnectionName = sqlDb.connectionName(); // retrieve connection Name (not in use in this version of implementation) qDebug() << "Qsql DB Connection Name : " << _dbConnectionName; } query::~query() { QSqlDatabase sqlDb = QSqlDatabase::database(_dbConnectionName); this->closeDb(sqlDb); QSqlDatabase::removeDatabase(sqlDb.connectionName()); } bool query::createDb(QsqlDatabase db) { [...] QSqlQuery q = QSqlQuery(db); [...] // Loop on all tables to create it in database for(int i=0;i<_dbStruct->tables()->count(); i++) { // Execute Query CREATE TABLE (...) isCreated = q.exec(_dbStruct->tables()->at(i)->sql()); if(!isCreated) { qDebug() << "query::createDb():[ERROR]Table -> " << q.lastError(); return isCreated; } qDebug().noquote().nospace() << _dbStruct->tables()->at(i)->sql(); } [...] q.clear(); q.prepare("INSERT INTO version ( \"database\", \"application\" ) VALUES ( :dbVal, :appVal )"); q.bindValue(":dbVal", _dbStruct->version()); q.bindValue(":appVal", "1"); // Exec Insert Prepared Query if(!(isCreated = q.exec())) { qDebug() << "query::createDb():[ERROR] Unable to Insert Version : " << q.lastError(); } } void query::closeDb(QSqlDatabase db) { int count = 0; while(db.isOpen() && count < 3) { count++; qDebug() << "query::closeDb():[INFO]Closing Database ! Attempt " << count << " of 3"; db.close(); } return isCreated; }
file main.cpp
[...] sql::query *query = new sql::query(); // Delete query object; delete query; // <--- !!! ERROR happens here !!! [...]
When executed, i have still this same error ( for all type of implementations described at the beginning of this thread ) ->
query::closeDb():[INFO]Closing Database ! Attempt 1 of 3 QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
N.B. : all my code isn't pasted here, but i think ift's enough to understand how i want to proceed, if there is some missing information, ask me i will share it!
EDIT : post updated with all modifications and remarks done in replies
LAST EDIT : SOLVED ! the problem was in the destructor, here is the correction :
query::~query() { this->closeDb(QSqlDatabase::database(_dbConnectionName)); QSqlDatabase::removeDatabase(_dbConnectionName); }
Thanks to everyone for their help !
-
You have a QSqlQuery lingering around somewhere (not in the code you showed us).
-
wrote on 9 Feb 2022, 13:41 last edited by Kamigi 2 Sept 2022, 13:57
mmm ok, then the only thing i do it's to call QSqlQuery instance (
q
) inside the same method (query::createDb(QSqlDatabase db)
) in afor
loop, so maybe the scope isn't clear for QSqlDatabase, cause i called the QsqlQuery in a sub scope, else i don't call it at all :QSqlQuery q = QSqlQuery(db); [...] // Loop on all tables to create it in database for(int i=0;i<_dbStruct->tables()->count(); i++) { // Execute Query CREATE TABLE (...) isCreated = q.exec(_dbStruct->tables()->at(i)->sql()); if(!isCreated) { qDebug() << "query::createDb():[ERROR]Table -> " << q.lastError(); return isCreated; } qDebug().noquote().nospace() << _dbStruct->tables()->at(i)->sql(); } [...] // Insert Database Current Version q.clear(); q.prepare("INSERT INTO :tbl ( \":dbCol\", \"appCol\" ) VALUES ( \":dbVal\", \":appVal\" )"); q.bindValue(":tbl", "version"); q.bindValue(":dbCol", "database"); q.bindValue(":appCol", "application"); q.bindValue(":dbVal", "1"); q.bindValue(":appVal", "1"); // Exec Insert Prepared Query if(!(isCreated = q.exec())) { qDebug() << "query::createDb():[ERROR] Unable to Insert Version : " << q.lastError(); } return isCreated;
EDIT : Oh i am really sorry , i forgot to mention the error happens when i try to delete the query pointer :
file:main.cppsql::query *query = new sql::query(); // Delete query object; delete query; // the error shows on this call (it calls query::~query())
file query.cpp
query::~query() { QSqlDatabase sqlDb = QSqlDatabase::database(_dbConnectionName); this->closeDb(sqlDb); sqlDb.removeDatabase(sqlDb.connectionName()); }
N.B. : i updated first post with all these infos
-
wrote on 9 Feb 2022, 13:54 last edited by
Hi, perhaps your query (the 2nd one) with "INSERT INTO..." is still in an active state, try doing a next() or a finish() at the end, say like this:
// Exec Insert Prepared Query if(!(isCreated = q.exec())) { qDebug() << "query::createDb():[ERROR] Unable to Insert Version : " << q.lastError(); } q.finish(); // here return isCreated;
-
mmm ok, then the only thing i do it's to call QSqlQuery instance (
q
) inside the same method (query::createDb(QSqlDatabase db)
) in afor
loop, so maybe the scope isn't clear for QSqlDatabase, cause i called the QsqlQuery in a sub scope, else i don't call it at all :QSqlQuery q = QSqlQuery(db); [...] // Loop on all tables to create it in database for(int i=0;i<_dbStruct->tables()->count(); i++) { // Execute Query CREATE TABLE (...) isCreated = q.exec(_dbStruct->tables()->at(i)->sql()); if(!isCreated) { qDebug() << "query::createDb():[ERROR]Table -> " << q.lastError(); return isCreated; } qDebug().noquote().nospace() << _dbStruct->tables()->at(i)->sql(); } [...] // Insert Database Current Version q.clear(); q.prepare("INSERT INTO :tbl ( \":dbCol\", \"appCol\" ) VALUES ( \":dbVal\", \":appVal\" )"); q.bindValue(":tbl", "version"); q.bindValue(":dbCol", "database"); q.bindValue(":appCol", "application"); q.bindValue(":dbVal", "1"); q.bindValue(":appVal", "1"); // Exec Insert Prepared Query if(!(isCreated = q.exec())) { qDebug() << "query::createDb():[ERROR] Unable to Insert Version : " << q.lastError(); } return isCreated;
EDIT : Oh i am really sorry , i forgot to mention the error happens when i try to delete the query pointer :
file:main.cppsql::query *query = new sql::query(); // Delete query object; delete query; // the error shows on this call (it calls query::~query())
file query.cpp
query::~query() { QSqlDatabase sqlDb = QSqlDatabase::database(_dbConnectionName); this->closeDb(sqlDb); sqlDb.removeDatabase(sqlDb.connectionName()); }
N.B. : i updated first post with all these infos
Lifetime Qt Championwrote on 9 Feb 2022, 14:29 last edited by Christian Ehrlicher 2 Sept 2022, 14:29@Kamigi said in QsqlDatabase & QsqlQuery managed in a class -Error removeDatabase: connection 'qt_sql_default_connection' is still in use:
QSqlDatabase sqlDb = QSqlDatabase::database(_dbConnectionName); this->closeDb(sqlDb); sqlDb.removeDatabase(sqlDb.connectionName());
This is wrong. removeDabase is static and therefore needs no instance (which is the one which is tirggering the warning)
-
wrote on 9 Feb 2022, 14:37 last edited by
did it work? I do not think so
-
wrote on 9 Feb 2022, 14:38 last edited by Kamigi 2 Sept 2022, 14:40
Hi again,
First many thanks for your time !
How could i not see that, i know already all these methods are statics (that is what annoying me in fact :D) ...
so i replace by the static method:
QSqlDatabase sqlDb = QSqlDatabase::database(_dbConnectionName); this->closeDb(sqlDb); QSqlDatabase::removeDatabase(sqlDb.connectionName());
i still have the same error, maybe i should use open and close static methods also ? (i don't know if those two are static ones...)
I will check this, many thanks , i think you got me on the good way !EDIT : according to Qt Documentation ( QSqlDatabase Class ), open and close are not statics, they are public ...
-
Hi again,
First many thanks for your time !
How could i not see that, i know already all these methods are statics (that is what annoying me in fact :D) ...
so i replace by the static method:
QSqlDatabase sqlDb = QSqlDatabase::database(_dbConnectionName); this->closeDb(sqlDb); QSqlDatabase::removeDatabase(sqlDb.connectionName());
i still have the same error, maybe i should use open and close static methods also ? (i don't know if those two are static ones...)
I will check this, many thanks , i think you got me on the good way !EDIT : according to Qt Documentation ( QSqlDatabase Class ), open and close are not statics, they are public ...
wrote on 9 Feb 2022, 14:46 last edited by KroMignon 2 Sept 2022, 14:46@Kamigi said in QsqlDatabase & QsqlQuery managed in a class -Error removeDatabase: connection 'qt_sql_default_connection' is still in use:
so i replace by the static method:
QSqlDatabase sqlDb = QSqlDatabase::database(_dbConnectionName); this->closeDb(sqlDb); QSqlDatabase::removeDatabase(sqlDb.connectionName());
The problem here is that an instance of the DB still exists!
Why you do not simply doQSqlDatabase::removeDatabase(_dbConnectionName);
?
Or insure that noQSqlDatabase
is in use:this->closeDb(QSqlDatabase::database(_dbConnectionName)); QSqlDatabase::removeDatabase(_dbConnectionName);
-
wrote on 9 Feb 2022, 14:50 last edited by
You really are the best !!!
many thanks error disappear !
here is the code for the destructor as you suggested :
query::~query() { this->closeDb(QSqlDatabase::database(_dbConnectionName)); QSqlDatabase::removeDatabase(_dbConnectionName); }
I guess topic is closed !!! , i update the first post with answer and mark it as solved !!!
Many thanks once again!
1/9