Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QsqlDatabase & QsqlQuery managed in a class -Error removeDatabase: connection 'qt_sql_default_connection' is still in use
Forum Updated to NodeBB v4.3 + New Features

QsqlDatabase & QsqlQuery managed in a class -Error removeDatabase: connection 'qt_sql_default_connection' is still in use

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 5 Posters 384 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Kamigi
    wrote on 9 Feb 2022, 12:47 last edited by Kamigi 2 Sept 2022, 14:52
    #1

    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.h

    namespace 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 !

    1 Reply Last reply
    0
    • C Online
      C Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 9 Feb 2022, 13:01 last edited by
      #2

      You have a QSqlQuery lingering around somewhere (not in the code you showed us).

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      0
      • K Offline
        K Offline
        Kamigi
        wrote on 9 Feb 2022, 13:41 last edited by Kamigi 2 Sept 2022, 13:57
        #3

        mmm ok, then the only thing i do it's to call QSqlQuery instance (q) inside the same method ( query::createDb(QSqlDatabase db)) in a for 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.cpp

        sql::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

        C 1 Reply Last reply 9 Feb 2022, 14:29
        0
        • hskoglundH Offline
          hskoglundH Offline
          hskoglund
          wrote on 9 Feb 2022, 13:54 last edited by
          #4

          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;
          
          1 Reply Last reply
          0
          • K Kamigi
            9 Feb 2022, 13:41

            mmm ok, then the only thing i do it's to call QSqlQuery instance (q) inside the same method ( query::createDb(QSqlDatabase db)) in a for 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.cpp

            sql::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

            C Online
            C Online
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on 9 Feb 2022, 14:29 last edited by Christian Ehrlicher 2 Sept 2022, 14:29
            #5

            @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)

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            1 Reply Last reply
            0
            • NevezN Offline
              NevezN Offline
              Nevez
              wrote on 9 Feb 2022, 14:37 last edited by
              #6

              did it work? I do not think so

              1 Reply Last reply
              0
              • K Offline
                K Offline
                Kamigi
                wrote on 9 Feb 2022, 14:38 last edited by Kamigi 2 Sept 2022, 14:40
                #7

                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 ...

                KroMignonK 1 Reply Last reply 9 Feb 2022, 14:46
                0
                • K Kamigi
                  9 Feb 2022, 14:38

                  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 ...

                  KroMignonK Offline
                  KroMignonK Offline
                  KroMignon
                  wrote on 9 Feb 2022, 14:46 last edited by KroMignon 2 Sept 2022, 14:46
                  #8

                  @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 do QSqlDatabase::removeDatabase(_dbConnectionName); ?
                  Or insure that no QSqlDatabase is in use:

                  this->closeDb(QSqlDatabase::database(_dbConnectionName));
                  QSqlDatabase::removeDatabase(_dbConnectionName);
                  

                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                  1 Reply Last reply
                  2
                  • K Offline
                    K Offline
                    Kamigi
                    wrote on 9 Feb 2022, 14:50 last edited by
                    #9

                    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 Reply Last reply
                    0

                    1/9

                    9 Feb 2022, 12:47

                    • Login

                    • Login or register to search.
                    1 out of 9
                    • First post
                      1/9
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved