File indexing completed on 2024-05-05 17:45:00
0001 /* 0002 SPDX-FileCopyrightText: 2007 Glenn Ergeerts <glenn.ergeerts@telenet.be> 0003 SPDX-FileCopyrightText: 2012 Marco Gulino <marco.gulino@xpeppers.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "fetchsqlite.h" 0009 #include "bookmarks_debug.h" 0010 #include "bookmarksrunner_defs.h" 0011 #include <QDebug> 0012 #include <QFile> 0013 #include <QMutexLocker> 0014 #include <QSqlError> 0015 #include <QSqlQuery> 0016 #include <QSqlRecord> 0017 #include <sstream> 0018 #include <thread> 0019 0020 FetchSqlite::FetchSqlite(const QString &databaseFile, QObject *parent) 0021 : QObject(parent) 0022 , m_databaseFile(databaseFile) 0023 { 0024 } 0025 0026 FetchSqlite::~FetchSqlite() 0027 { 0028 } 0029 0030 void FetchSqlite::prepare() 0031 { 0032 } 0033 0034 void FetchSqlite::teardown() 0035 { 0036 const QString connectionPrefix = m_databaseFile + "-"; 0037 const auto connections = QSqlDatabase::connectionNames(); 0038 for (const auto &c : connections) { 0039 if (c.startsWith(connectionPrefix)) { 0040 qCDebug(RUNNER_BOOKMARKS) << "Closing connection" << c; 0041 QSqlDatabase::removeDatabase(c); 0042 } 0043 } 0044 } 0045 0046 static QSqlDatabase openDbConnection(const QString &databaseFile) 0047 { 0048 // create a thread unique connection name based on the DB filename and thread id 0049 auto connection = databaseFile + "-"; 0050 std::stringstream s; 0051 s << std::this_thread::get_id(); 0052 connection += QString::fromStdString(s.str()); 0053 0054 // Try to reuse the previous connection 0055 auto db = QSqlDatabase::database(connection); 0056 if (db.isValid()) { 0057 qCDebug(RUNNER_BOOKMARKS) << "Reusing connection" << connection; 0058 return db; 0059 } 0060 0061 // Otherwise, create, configure and open a new one 0062 db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), connection); 0063 db.setHostName(QStringLiteral("localhost")); 0064 db.setDatabaseName(databaseFile); 0065 db.open(); 0066 qCDebug(RUNNER_BOOKMARKS) << "Opened connection" << connection; 0067 0068 return db; 0069 } 0070 0071 QList<QVariantMap> FetchSqlite::query(const QString &sql, QMap<QString, QVariant> bindObjects) 0072 { 0073 QMutexLocker lock(&m_mutex); 0074 0075 auto db = openDbConnection(m_databaseFile); 0076 if (!db.isValid()) { 0077 return QList<QVariantMap>(); 0078 } 0079 0080 // qDebug() << "query: " << sql; 0081 QSqlQuery query(db); 0082 query.prepare(sql); 0083 for (auto entry = bindObjects.constKeyValueBegin(); entry != bindObjects.constKeyValueEnd(); ++entry) { 0084 query.bindValue((*entry).first, (*entry).second); 0085 // qDebug() << "* Bound " << variableName << " to " << query.boundValue(variableName); 0086 } 0087 0088 if (!query.exec()) { 0089 QSqlError error = db.lastError(); 0090 // qDebug() << "query failed: " << error.text() << " (" << error.type() << ", " << error.number() << ")"; 0091 // qDebug() << query.lastQuery(); 0092 } 0093 0094 QList<QVariantMap> result; 0095 while (query.next()) { 0096 QVariantMap recordValues; 0097 QSqlRecord record = query.record(); 0098 for (int field = 0; field < record.count(); field++) { 0099 QVariant value = record.value(field); 0100 recordValues.insert(record.fieldName(field), value); 0101 } 0102 result << recordValues; 0103 } 0104 0105 return result; 0106 } 0107 0108 QStringList FetchSqlite::tables(QSql::TableType type) 0109 { 0110 QMutexLocker lock(&m_mutex); 0111 0112 auto db = openDbConnection(m_databaseFile); 0113 return db.tables(type); 0114 }