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 }