diff --git a/runners/bookmarks/fetchsqlite.cpp b/runners/bookmarks/fetchsqlite.cpp index acf2f19fc..d5a25df60 100644 --- a/runners/bookmarks/fetchsqlite.cpp +++ b/runners/bookmarks/fetchsqlite.cpp @@ -1,104 +1,131 @@ /* * Copyright 2007 Glenn Ergeerts * Copyright 2012 Glenn Ergeerts * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "fetchsqlite.h" #include #include +#include "bookmarks_debug.h" #include "bookmarksrunner_defs.h" #include #include #include #include +#include +#include FetchSqlite::FetchSqlite(const QString &originalFilePath, const QString ©To, QObject *parent) : QObject(parent), m_databaseFile(copyTo) { - m_db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), originalFilePath); - m_db.setHostName(QStringLiteral("localhost")); - QFile originalFile(originalFilePath); QFile(copyTo).remove(); bool couldCopy = originalFile.copy(copyTo); if(!couldCopy) { //qDebug() << "error copying favicon database from " << originalFile.fileName() << " to " << copyTo; //qDebug() << originalFile.errorString(); } } FetchSqlite::~FetchSqlite() { - if(m_db.isOpen()) m_db.close(); QFile(m_databaseFile).remove(); } void FetchSqlite::prepare() { - QMutexLocker lock(&m_mutex); - m_db.setDatabaseName(m_databaseFile); - bool ok = m_db.open(); - //qDebug() << "Sqlite Database " << m_databaseFile << " was opened: " << ok; - if(!ok) { - //qDebug() << "Error: " << m_db.lastError().text(); - } } void FetchSqlite::teardown() { - QMutexLocker lock(&m_mutex); - m_db.close(); + QString connectionPrefix = m_databaseFile + "-"; + + const auto connections = QSqlDatabase::connectionNames(); + for (auto c : connections) { + if (c.startsWith(connectionPrefix)) { + qCDebug(RUNNER_BOOKMARKS) << "Closing connection" << c; + QSqlDatabase::removeDatabase(c); + } + } +} + +static QSqlDatabase openDbConnection(const QString& databaseFile) { + // create a thread unique connection name based on the DB filename and thread id + auto connection = databaseFile + "-"; + std::stringstream s; + s << std::this_thread::get_id(); + connection += QString::fromStdString(s.str()); + + // Try to reuse the previous connection + auto db = QSqlDatabase::database(connection); + if (db.isValid()) { + qCDebug(RUNNER_BOOKMARKS) << "Reusing connection" << connection; + return db; + } + + // Otherwise, create, configure and open a new one + db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), connection); + db.setHostName(QStringLiteral("localhost")); + db.setDatabaseName(databaseFile); + db.open(); + qCDebug(RUNNER_BOOKMARKS) << "Opened connection" << connection; + + return db; } QList FetchSqlite::query(const QString &sql, QMap bindObjects) { QMutexLocker lock(&m_mutex); + auto db = openDbConnection(m_databaseFile); + //qDebug() << "query: " << sql; - QSqlQuery query(m_db); + QSqlQuery query(db); query.prepare(sql); foreach(const QString &variableName, bindObjects.keys()) { query.bindValue(variableName, bindObjects.value(variableName)); //qDebug() << "* Bound " << variableName << " to " << query.boundValue(variableName); } if(!query.exec()) { - QSqlError error = m_db.lastError(); + QSqlError error = db.lastError(); //qDebug() << "query failed: " << error.text() << " (" << error.type() << ", " << error.number() << ")"; //qDebug() << query.lastQuery(); } QList result; while(query.next()) { QVariantMap recordValues; QSqlRecord record = query.record(); for(int field=0; field * Copyright 2012 Glenn Ergeerts * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef FETCHSQLITE_H #define FETCHSQLITE_H #include #include #include #include #include #include #include class FetchSqlite : public QObject { Q_OBJECT public: explicit FetchSqlite(const QString &originalFile, const QString ©To, QObject *parent = nullptr); ~FetchSqlite() override; void prepare(); void teardown(); QList query(const QString &sql, QMap bindObjects); QList query(const QString &sql); QStringList tables(QSql::TableType type = QSql::Tables); private: QString const m_databaseFile; QMutex m_mutex; - QSqlDatabase m_db; }; #endif // FETCHSQLITE_H