File indexing completed on 2024-05-19 09:31:37
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 <QSqlError> 0014 #include <QSqlQuery> 0015 #include <QSqlRecord> 0016 #include <sstream> 0017 #include <thread> 0018 0019 FetchSqlite::FetchSqlite(const QString &databaseFile, QObject *parent) 0020 : QObject(parent) 0021 , m_databaseFile(databaseFile) 0022 { 0023 } 0024 0025 FetchSqlite::~FetchSqlite() 0026 { 0027 } 0028 0029 void FetchSqlite::prepare() 0030 { 0031 } 0032 0033 void FetchSqlite::teardown() 0034 { 0035 const QString connectionPrefix = m_databaseFile + "-"; 0036 const auto connections = QSqlDatabase::connectionNames(); 0037 for (const auto &c : connections) { 0038 if (c.startsWith(connectionPrefix)) { 0039 qCDebug(RUNNER_BOOKMARKS) << "Closing connection" << c; 0040 QSqlDatabase::removeDatabase(c); 0041 } 0042 } 0043 } 0044 0045 static QSqlDatabase openDbConnection(const QString &databaseFile) 0046 { 0047 // create a thread unique connection name based on the DB filename and 0048 // thread id 0049 QString 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 auto db = openDbConnection(m_databaseFile); 0074 if (!db.isValid()) { 0075 return QList<QVariantMap>(); 0076 } 0077 0078 // qDebug() << "query: " << sql; 0079 QSqlQuery query(db); 0080 query.prepare(sql); 0081 for (auto entry = bindObjects.constKeyValueBegin(); entry != bindObjects.constKeyValueEnd(); ++entry) { 0082 query.bindValue((*entry).first, (*entry).second); 0083 // qDebug() << "* Bound " << variableName << " to " << query.boundValue(variableName); 0084 } 0085 0086 if (!query.exec()) { 0087 QSqlError error = db.lastError(); 0088 // qDebug() << "query failed: " << error.text() << " (" << error.type() << ", " << error.number() << ")"; 0089 // qDebug() << query.lastQuery(); 0090 } 0091 0092 QList<QVariantMap> result; 0093 while (query.next()) { 0094 QVariantMap recordValues; 0095 QSqlRecord record = query.record(); 0096 for (int field = 0; field < record.count(); field++) { 0097 QVariant value = record.value(field); 0098 recordValues.insert(record.fieldName(field), value); 0099 } 0100 result << recordValues; 0101 } 0102 0103 return result; 0104 } 0105 0106 QStringList FetchSqlite::tables(QSql::TableType type) 0107 { 0108 auto db = openDbConnection(m_databaseFile); 0109 return db.tables(type); 0110 }