Search code examples
c++databaseqtsqliteqsqldatabase

Copy tables between sqlite databases, qt, causes error


I want to write the contents of my SQlite database on user click to another SQlite database. For this I am trying to make connections to two databases and do select query from one db and in transaction do insert query to another. But I gets error on connection creation itself.

In header file:

private:
    QSqlDatabase database;
    QSqlDatabase mHistoryDB;

In source file:

    qDebug() << Q_FUNC_INFO << "Invoked";
    database = QSqlDatabase::addDatabase("QSQLITE");
    mHistoryDB = QSqlDatabase::addDatabase("QSQLITE");
#ifdef Q_OS_WIN
    database.setDatabaseName("C:/ANDROID_DATABASE/RestPos.sqlite");
    mHistoryDB.setDatabaseName("C:/ANDROID_DATABASE/History/RestPos.sqlite");
#else
    database.setDatabaseName("/mnt/sdcard/pos/RestPos.sqlite");
    mHistoryDB.setDatabaseName("/mnt/sdcard/pos/History/RestPos.sqlite");
#endif

While running I gets the following error:

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

QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.

If I use only database connection there occurs no error. I am not sure how to do copy with single connection.

My current copy code is as below:

bool readStatus     = false,
     writeStatus    = false;

if (database.isOpen() && mHistoryDB.open())
{
    QSqlQuery readQuery (database);
    QSqlQuery writeQuery(mHistoryDB);

    readStatus
            = readQuery.exec("SELECT costcentre_id, bill_no, bill_date "
                             "FROM BillHdr");
    qDebug() << Q_FUNC_INFO << getLastExecutedQuery(readQuery);

    if (readStatus)
    {
        mHistoryDB.transaction();
        writeQuery.prepare("INSERT INTO BillHdr "
                               "(costcentre_id, bill_no, bill_date) "
                           "VALUES (:costcentre_id, :bill_no, :bill_date)");

        while(readQuery.next())
        {
            if (readQuery.isValid())
            {
                BillHeader billHdr;
                billHdr.costCenterId = readQuery.value(0).toString();
                billHdr.billNumber   = readQuery.value(1).toDouble();
                billHdr.date         = readQuery.value(2).toDate();

                writeQuery.bindValue(":costcentre_id", billHdr.costCenterId);
                writeQuery.bindValue(":bill_no", billHdr.billNumber);
                writeQuery.bindValue(":bill_date", billHdr.date);

                writeStatus = writeQuery.exec();

                qDebug() << Q_FUNC_INFO << getLastExecutedQuery(writeQuery);

                if (!writeStatus)
                {
                    qDebug() << Q_FUNC_INFO << "error in write" <<
                                writeQuery.lastError().text();
                    mHistoryDB.rollback();
                    mHistoryDB.close();
                    break;
                }

            }
        }

        writeStatus = mHistoryDB.commit();
        qDebug() << Q_FUNC_INFO << "commit:" << writeStatus;

        if (!writeStatus)
        {
            mHistoryDB.rollback();
        }

        mHistoryDB.close();
    }
}

qDebug() << Q_FUNC_INFO << "Exits" << writeStatus;
return writeStatus;

Solution

  • We can read from the Qt documentation about QSqlDatabase :

    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.

    So when you add a database multiple times within a specific name or without specifying any (default connection), the connection is replaced and that warning appears.

    you should call QSqlDatabase::addDatabase() once for each of the databases with different connection names :

    database = QSqlDatabase::addDatabase("QSQLITE", "database_Connection");
    mHistoryDB = QSqlDatabase::addDatabase("QSQLITE", "mHistoryDB_Connection");