'QSqlDatabasePrivate::removeDatabase: connection 'myConnectionName' is still in use, all queries will cease to work

I have a folder where i have a many databases. Some times may be deleted or added database to the folder. So I use QTimer and read all databases.

It is a my code:

this->timer = new QTimer(this);
this->timer->setInterval(15000);
connect(this->timer, &QTimer::timeout, this, [=]() {
    QString path = "C:\\Users\\User\\Desktop\\DAXI SMS SENDER\\SMSSenderAllBASE";
    //QString path = qApp->applicationDirPath() + "\\SMSSenderAllBASE";
    QDir recoredDir(path);
    QStringList allFiles = recoredDir.entryList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden  | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
    for (int i = 0; i < allFiles.size(); i++) {
        QString fullPath = path + "\\" + allFiles[i];
        QString connectionName = allFiles[i];
        connectionName = connectionName.remove(connectionName.size() - 4, 4);
        QSqlDatabase db = QSqlDatabase::addDatabase("QIBASE", connectionName);
        db.setDatabaseName(fullPath);
        db.setHostName("localhost");
        db.setPort(3050);
        db.setUserName("SYSDBA");
        db.setPassword("masterkey");

        thrdHelperSendSMS *help = new thrdHelperSendSMS(db, this);
        connect(help, &thrdHelperSendSMS::helperFinished, this, [=](QString connectionName){
            QSqlDatabase t_db = QSqlDatabase::database(connectionName);
            t_db.close();
            QSqlDatabase::removeDatabase(connectionName);
            delete help;
        });
        help->run();
    }
});
this->timer->start();

Yes I'm sure that the helperFinished signal will happen and this time I will not have any connection with this base.

EDIT: If i remove

   thrdHelperSendSMS *help = new thrdHelperSendSMS(db, this);
   connect(help, &thrdHelperSendSMS::helperFinished, this, [=](QString connectionName){
       QSqlDatabase t_db = QSqlDatabase::database(connectionName);
       t_db.close();
       QSqlDatabase::removeDatabase(connectionName);
       delete help;
   });
   help->run();

example:

for (int i = 0; i < allFiles.size(); i++) {
    QString fullPath = path + "\\" + allFiles[i];
    QString connectionName = allFiles[i];
    connectionName = connectionName.remove(connectionName.size() - 4, 4);
    QSqlDatabase db = QSqlDatabase::addDatabase("QIBASE", connectionName);
    db.setDatabaseName(fullPath);
    db.setHostName("localhost");
    db.setPort(3050);
    db.setUserName("SYSDBA");
    db.setPassword("masterkey");

    QSqlDatabase::removeDatabase(connectionName);
}

I have the same error.



Solution 1:[1]

@user3606329's answer is right, but I add this possibility:

QSqlDatabase db = QSqlDatabase::database("sales");
{
    QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
    //use query
}
db = QSqlDatabase();
QSqlDatabase::removeDatabase("sales");

Solution 2:[2]

You can use std::swap to force it destruct on demand. I basically use BOOST_SCOPE_EXIT for cases when want to call a function on scope exit including not expected exit like through an exception throw.

#include <boost/scope_exit.hpp>

{
    QSqlDatabase db;

    BOOST_SCOPE_EXIT(this_, &db) { // by reference, otherwise it will copy a stack object
        // access object here through the this_ instead of this ...

        if (db.isOpen()) {
            db.close(); // closing if not yet closed before connection remove
        }

        std::swap(db, QSqlDatabase{}); // destruct via swap

        // CAUTION:
        //  From this point you must not call to `QSqlDatabase::database("MYDB", ...)`, otherwise it will return another constructed object!
        //

        QSqlDatabase::removeDatabase("MYDB");
    } BOOST_SCOPE_EXIT_END

    // ui change from here ...

    // accomplish last ui changes before long blocking operation
    qApp->processEvents();

    db = QSqlDatabase::addDatabase("...", "MYDB");

    // database access from here ...
}

Solution 3:[3]

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "conn_name");
db.open();
if (db.open())
    {
        qDebug()<<"DataBase is Open";
    }
    else
    {
        qDebug()<<"DataBase is Not Open";

    }
QSqlQueryModel * model = new QSqlQueryModel();
QSqlQuery query(QSqlDatabase::database("conn_name"));
query.exec("SMTHING")
if (query.exec())
{
   while (query.next())
      {
         ui->QTableView->setModel(model);
         model->setHeaderData(2, Qt::Horizontal, QObject::tr("????"));
      }
}
db.close();
QSqlDatabase::removeDatabase("conn_name");



Here is my code

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Albertino80
Solution 2 Andry
Solution 3 GKS