From c1c168aae98bb4ae4a488b1e47860a72216f094b Mon Sep 17 00:00:00 2001 From: David Rosca Date: Mon, 18 Dec 2017 13:06:42 +0100 Subject: [PATCH] Create every QSqlQuery with correct database for current thread Queries are now always executed on correct database instance. Databases are also stored in thread local storage instead of in hash table with mutex. Closes #2498 --- src/lib/app/browserwindow.cpp | 1 - src/lib/app/profilemanager.cpp | 3 +- src/lib/autofill/autofill.cpp | 12 ++--- .../databaseencryptedpasswordbackend.cpp | 47 ++++++++----------- .../databasepasswordbackend.cpp | 26 +++++----- .../bookmarksimport/firefoximporter.cpp | 5 +- src/lib/bookmarks/bookmarkstools.cpp | 4 +- src/lib/history/history.cpp | 25 +++++----- src/lib/history/historymenu.cpp | 6 +-- src/lib/history/historymodel.cpp | 8 ++-- .../completer/locationcompletermodel.cpp | 9 ++-- .../completer/locationcompleterrefreshjob.cpp | 8 ++-- src/lib/opensearch/searchenginesmanager.cpp | 10 ++-- src/lib/other/clearprivatedata.cpp | 3 +- src/lib/other/iconchooser.cpp | 6 +-- src/lib/other/siteinfowidget.cpp | 6 +-- src/lib/preferences/autofillmanager.cpp | 10 ++-- src/lib/tools/iconprovider.cpp | 17 +++---- src/lib/tools/sqldatabase.cpp | 38 ++++++--------- src/lib/tools/sqldatabase.h | 12 ++--- 20 files changed, 118 insertions(+), 138 deletions(-) diff --git a/src/lib/app/browserwindow.cpp b/src/lib/app/browserwindow.cpp index 3eb6ca040..be0815000 100644 --- a/src/lib/app/browserwindow.cpp +++ b/src/lib/app/browserwindow.cpp @@ -68,7 +68,6 @@ #include #include #include -#include #include #include #include diff --git a/src/lib/app/profilemanager.cpp b/src/lib/app/profilemanager.cpp index 2a364611c..65d32fa9d 100644 --- a/src/lib/app/profilemanager.cpp +++ b/src/lib/app/profilemanager.cpp @@ -22,8 +22,9 @@ #include "qztools.h" #include -#include #include +#include +#include #include #include #include diff --git a/src/lib/autofill/autofill.cpp b/src/lib/autofill/autofill.cpp index 55ae94ad2..e81bd23d1 100644 --- a/src/lib/autofill/autofill.cpp +++ b/src/lib/autofill/autofill.cpp @@ -32,7 +32,6 @@ #include #include #include - #include AutoFill::AutoFill(QObject* parent) @@ -85,7 +84,7 @@ bool AutoFill::isStoringEnabled(const QUrl &url) server = url.toString(); } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT count(id) FROM autofill_exceptions WHERE server=?"); query.addBindValue(server); query.exec(); @@ -104,7 +103,7 @@ void AutoFill::blockStoringforUrl(const QUrl &url) server = url.toString(); } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("INSERT INTO autofill_exceptions (server) VALUES (?)"); query.addBindValue(server); @@ -260,8 +259,9 @@ QByteArray AutoFill::exportPasswords() stream.writeEndElement(); } - QSqlQuery query; - query.exec("SELECT server FROM autofill_exceptions"); + QSqlQuery query(SqlDatabase::instance()->database()); + query.prepare("SELECT server FROM autofill_exceptions"); + query.exec(); while (query.next()) { stream.writeStartElement("exception"); stream.writeTextElement("server", query.value(0).toString()); @@ -336,7 +336,7 @@ bool AutoFill::importPasswords(const QByteArray &data) } if (!server.isEmpty()) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id FROM autofill_exceptions WHERE server=?"); query.addBindValue(server); query.exec(); diff --git a/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.cpp b/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.cpp index 2cda02b94..ef7834314 100644 --- a/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.cpp +++ b/src/lib/autofill/passwordbackends/databaseencryptedpasswordbackend.cpp @@ -1,7 +1,7 @@ /* ============================================================ * Falkon - Qt web browser * Copyright (C) 2013-2014 S. Razi Alavizadeh -* Copyright (C) 2013-2016 David Rosca +* Copyright (C) 2013-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,9 +22,9 @@ #include "aesinterface.h" #include "browserwindow.h" #include "ui_masterpassworddialog.h" +#include "sqldatabase.h" #include -#include #include #define INTERNAL_SERVER_ID QLatin1String("falkon.internal") @@ -35,7 +35,7 @@ DatabaseEncryptedPasswordBackend::DatabaseEncryptedPasswordBackend() , m_askPasswordDialogVisible(false) , m_askMasterPassword(false) { - QSqlDatabase db = QSqlDatabase::database(); + QSqlDatabase db = SqlDatabase::instance()->database(); if (!db.tables().contains(QLatin1String("autofill_encrypted"))) { db.exec("CREATE TABLE autofill_encrypted (data_encrypted TEXT, id INTEGER PRIMARY KEY," "password_encrypted TEXT, server TEXT, username_encrypted TEXT, last_used NUMERIC)"); @@ -55,7 +55,7 @@ QVector DatabaseEncryptedPasswordBackend::getEntries(const QUrl & const QString host = PasswordManager::createHost(url); - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id, username_encrypted, password_encrypted, data_encrypted FROM autofill_encrypted " "WHERE server=? ORDER BY last_used DESC"); query.addBindValue(host); @@ -86,8 +86,9 @@ QVector DatabaseEncryptedPasswordBackend::getAllEntries() AesInterface aesDecryptor; - QSqlQuery query; - query.exec("SELECT id, server, username_encrypted, password_encrypted, data_encrypted FROM autofill_encrypted"); + QSqlQuery query(SqlDatabase::instance()->database()); + query.prepare("SELECT id, server, username_encrypted, password_encrypted, data_encrypted FROM autofill_encrypted"); + query.exec(); if (query.next() && hasPermission()) { do { @@ -140,7 +141,7 @@ void DatabaseEncryptedPasswordBackend::addEntry(const PasswordEntry &entry) // Data is empty only for HTTP/FTP authorization if (entry.data.isEmpty()) { // Multiple-usernames for HTTP/FTP authorization not supported - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT username_encrypted FROM autofill_encrypted WHERE server=?"); query.addBindValue(entry.host); query.exec(); @@ -154,14 +155,13 @@ void DatabaseEncryptedPasswordBackend::addEntry(const PasswordEntry &entry) AesInterface aesEncryptor; if (hasPermission() && encryptPasswordEntry(encryptedEntry, &aesEncryptor)) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("INSERT INTO autofill_encrypted (server, data_encrypted, username_encrypted, password_encrypted, last_used) " "VALUES (?,?,?,?,strftime('%s', 'now'))"); query.bindValue(0, encryptedEntry.host); query.bindValue(1, encryptedEntry.data); query.bindValue(2, encryptedEntry.username); query.bindValue(3, encryptedEntry.password); - query.exec(); } } @@ -172,7 +172,7 @@ bool DatabaseEncryptedPasswordBackend::updateEntry(const PasswordEntry &entry) PasswordEntry encryptedEntry = entry; if (hasPermission() && encryptPasswordEntry(encryptedEntry, &aesEncryptor)) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); // Data is empty only for HTTP/FTP authorization if (entry.data.isEmpty()) { @@ -197,10 +197,9 @@ bool DatabaseEncryptedPasswordBackend::updateEntry(const PasswordEntry &entry) void DatabaseEncryptedPasswordBackend::updateLastUsed(PasswordEntry &entry) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("UPDATE autofill_encrypted SET last_used=strftime('%s', 'now') WHERE id=?"); query.addBindValue(entry.id); - query.exec(); } @@ -210,10 +209,9 @@ void DatabaseEncryptedPasswordBackend::removeEntry(const PasswordEntry &entry) return; } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("DELETE FROM autofill_encrypted WHERE id=?"); query.addBindValue(entry.id); - query.exec(); m_stateOfMasterPassword = UnKnownState; @@ -228,9 +226,8 @@ void DatabaseEncryptedPasswordBackend::removeAll() return; } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("DELETE FROM autofill_encrypted"); - query.exec(); m_stateOfMasterPassword = PasswordIsSetted; @@ -377,8 +374,7 @@ void DatabaseEncryptedPasswordBackend::encryptDataBaseTableOnFly(const QByteArra return; } - QSqlQuery query; - + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id, data_encrypted, password_encrypted, username_encrypted, server FROM autofill_encrypted"); query.exec(); @@ -408,14 +404,13 @@ void DatabaseEncryptedPasswordBackend::encryptDataBaseTableOnFly(const QByteArra username = encryptor.encrypt(username, encryptorPassword); } - QSqlQuery updateQuery; + QSqlQuery updateQuery(SqlDatabase::instance()->database()); updateQuery.prepare("UPDATE autofill_encrypted SET data_encrypted = ?, password_encrypted = ?, username_encrypted = ? WHERE id = ?"); updateQuery.addBindValue(data); updateQuery.addBindValue(password); updateQuery.addBindValue(username); updateQuery.addBindValue(id); - - updateQuery.exec(); + query.exec(); } } @@ -425,8 +420,7 @@ QByteArray DatabaseEncryptedPasswordBackend::someDataFromDatabase() return m_someDataStoredOnDataBase; } - QSqlQuery query; - + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT password_encrypted, data_encrypted, username_encrypted FROM autofill_encrypted"); query.exec(); @@ -454,8 +448,7 @@ QByteArray DatabaseEncryptedPasswordBackend::someDataFromDatabase() void DatabaseEncryptedPasswordBackend::updateSampleData(const QByteArray &password) { - QSqlQuery query; - + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id FROM autofill_encrypted WHERE server = ?"); query.addBindValue(INTERNAL_SERVER_ID); query.exec(); @@ -473,14 +466,14 @@ void DatabaseEncryptedPasswordBackend::updateSampleData(const QByteArray &passwo query.addBindValue(QString::fromUtf8(m_someDataStoredOnDataBase)); query.addBindValue(INTERNAL_SERVER_ID); - query.exec(); + SqlDatabase::instance()->exec(query); m_stateOfMasterPassword = PasswordIsSetted; } else if (query.next()) { query.prepare("DELETE FROM autofill_encrypted WHERE server = ?"); query.addBindValue(INTERNAL_SERVER_ID); - query.exec(); + SqlDatabase::instance()->exec(query); m_stateOfMasterPassword = PasswordIsNotSetted; m_someDataStoredOnDataBase.clear(); diff --git a/src/lib/autofill/passwordbackends/databasepasswordbackend.cpp b/src/lib/autofill/passwordbackends/databasepasswordbackend.cpp index d51b52e47..c2db3b66b 100644 --- a/src/lib/autofill/passwordbackends/databasepasswordbackend.cpp +++ b/src/lib/autofill/passwordbackends/databasepasswordbackend.cpp @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2013-2014 David Rosca +* Copyright (C) 2013-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,9 +18,9 @@ #include "databasepasswordbackend.h" #include "mainapplication.h" #include "autofill.h" +#include "sqldatabase.h" #include -#include DatabasePasswordBackend::DatabasePasswordBackend() : PasswordBackend() @@ -36,7 +36,7 @@ QVector DatabasePasswordBackend::getEntries(const QUrl &url) { const QString host = PasswordManager::createHost(url); - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id, username, password, data FROM autofill " "WHERE server=? ORDER BY last_used DESC"); query.addBindValue(host); @@ -62,8 +62,9 @@ QVector DatabasePasswordBackend::getAllEntries() { QVector list; - QSqlQuery query; - query.exec("SELECT id, server, username, password, data FROM autofill"); + QSqlQuery query(SqlDatabase::instance()->database()); + query.prepare("SELECT id, server, username, password, data FROM autofill"); + query.exec(); while (query.next()) { PasswordEntry data; @@ -84,7 +85,7 @@ void DatabasePasswordBackend::addEntry(const PasswordEntry &entry) // Data is empty only for HTTP/FTP authorization if (entry.data.isEmpty()) { // Multiple-usernames for HTTP/FTP authorization not supported - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT username FROM autofill WHERE server=?"); query.addBindValue(entry.host); query.exec(); @@ -94,7 +95,7 @@ void DatabasePasswordBackend::addEntry(const PasswordEntry &entry) } } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("INSERT INTO autofill (server, data, username, password, last_used) " "VALUES (?,?,?,?,strftime('%s', 'now'))"); query.bindValue(0, entry.host); @@ -106,7 +107,7 @@ void DatabasePasswordBackend::addEntry(const PasswordEntry &entry) bool DatabasePasswordBackend::updateEntry(const PasswordEntry &entry) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); // Data is empty only for HTTP/FTP authorization if (entry.data.isEmpty()) { @@ -128,7 +129,7 @@ bool DatabasePasswordBackend::updateEntry(const PasswordEntry &entry) void DatabasePasswordBackend::updateLastUsed(PasswordEntry &entry) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("UPDATE autofill SET last_used=strftime('%s', 'now') WHERE id=?"); query.addBindValue(entry.id); query.exec(); @@ -136,7 +137,7 @@ void DatabasePasswordBackend::updateLastUsed(PasswordEntry &entry) void DatabasePasswordBackend::removeEntry(const PasswordEntry &entry) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("DELETE FROM autofill WHERE id=?"); query.addBindValue(entry.id); query.exec(); @@ -144,7 +145,6 @@ void DatabasePasswordBackend::removeEntry(const PasswordEntry &entry) void DatabasePasswordBackend::removeAll() { - QSqlQuery query; - query.prepare("DELETE FROM autofill"); - query.exec(); + QSqlQuery query(SqlDatabase::instance()->database()); + query.exec("DELETE FROM autofill"); } diff --git a/src/lib/bookmarks/bookmarksimport/firefoximporter.cpp b/src/lib/bookmarks/bookmarksimport/firefoximporter.cpp index 9e3b3e79c..b2c7e277d 100644 --- a/src/lib/bookmarks/bookmarksimport/firefoximporter.cpp +++ b/src/lib/bookmarks/bookmarksimport/firefoximporter.cpp @@ -20,9 +20,9 @@ #include #include -#include #include #include +#include #include #define CONNECTION "firefox-places-import" @@ -89,7 +89,8 @@ BookmarkItem* FirefoxImporter::importBookmarks() root->setTitle("Firefox Import"); QSqlQuery query(QSqlDatabase::database(CONNECTION)); - query.exec("SELECT id, parent, type, title, fk FROM moz_bookmarks WHERE fk NOT NULL OR type = 3"); + query.prepare("SELECT id, parent, type, title, fk FROM moz_bookmarks WHERE fk NOT NULL OR type = 3"); + query.exec(); while (query.next()) { Item item; diff --git a/src/lib/bookmarks/bookmarkstools.cpp b/src/lib/bookmarks/bookmarkstools.cpp index cd4347510..ae72e11cb 100644 --- a/src/lib/bookmarks/bookmarkstools.cpp +++ b/src/lib/bookmarks/bookmarkstools.cpp @@ -24,9 +24,9 @@ #include "tabwidget.h" #include "qzsettings.h" #include "browserwindow.h" +#include "sqldatabase.h" #include -#include #include #include #include @@ -438,7 +438,7 @@ void BookmarksTools::addFolderContentsToMenu(QObject *receiver, Menu *menu, Book bool BookmarksTools::migrateBookmarksIfNecessary(Bookmarks* bookmarks) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.exec("SELECT name FROM sqlite_master WHERE type='table' AND name='folders'"); if (!query.next()) { diff --git a/src/lib/history/history.cpp b/src/lib/history/history.cpp index 55e7b9e38..f4fe31a8f 100644 --- a/src/lib/history/history.cpp +++ b/src/lib/history/history.cpp @@ -22,9 +22,8 @@ #include "iconprovider.h" #include "settings.h" #include "mainapplication.h" +#include "sqldatabase.h" -#include -#include #include History::History(QObject* parent) @@ -86,7 +85,7 @@ void History::addHistoryEntry(const QUrl &url, QString title) title = tr("Empty Page"); } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id, count, date, title FROM history WHERE url=?"); query.bindValue(0, url); query.exec(); @@ -147,15 +146,16 @@ void History::deleteHistoryEntry(int index) void History::deleteHistoryEntry(const QList &list) { - QSqlDatabase db = QSqlDatabase::database(); + QSqlDatabase db = SqlDatabase::instance()->database(); db.transaction(); foreach (int index, list) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT count, date, url, title FROM history WHERE id=?"); query.addBindValue(index); + query.exec(); - if (!query.exec() || !query.next()) { + if (!query.isActive() || !query.next()) { continue; } @@ -183,7 +183,7 @@ void History::deleteHistoryEntry(const QList &list) void History::deleteHistoryEntry(const QString &url, const QString &title) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id FROM history WHERE url=? AND title=?"); query.bindValue(0, url); query.bindValue(1, title); @@ -202,7 +202,7 @@ QList History::indexesFromTimeRange(qint64 start, qint64 end) return list; } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id FROM history WHERE date BETWEEN ? AND ?"); query.addBindValue(end); query.addBindValue(start); @@ -217,7 +217,7 @@ QList History::indexesFromTimeRange(qint64 start, qint64 end) bool History::urlIsStored(const QString &url) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id FROM history WHERE url=?"); query.bindValue(0, url); query.exec(); @@ -227,8 +227,9 @@ bool History::urlIsStored(const QString &url) QVector History::mostVisited(int count) { QVector list; - QSqlQuery query; - query.exec(QString("SELECT count, date, id, title, url FROM history ORDER BY count DESC LIMIT %1").arg(count)); + QSqlQuery query(SqlDatabase::instance()->database()); + query.prepare(QString("SELECT count, date, id, title, url FROM history ORDER BY count DESC LIMIT %1").arg(count)); + query.exec(); while (query.next()) { HistoryEntry entry; entry.count = query.value(0).toInt(); @@ -243,7 +244,7 @@ QVector History::mostVisited(int count) void History::clearHistory() { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.exec(QSL("DELETE FROM history")); query.exec(QSL("VACUUM")); diff --git a/src/lib/history/historymenu.cpp b/src/lib/history/historymenu.cpp index f1880b495..8b1f3d43b 100644 --- a/src/lib/history/historymenu.cpp +++ b/src/lib/history/historymenu.cpp @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2014 David Rosca +* Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,10 +25,10 @@ #include "qztools.h" #include "history.h" #include "qzsettings.h" +#include "sqldatabase.h" #include #include -#include HistoryMenu::HistoryMenu(QWidget* parent) : Menu(parent) @@ -90,7 +90,7 @@ void HistoryMenu::aboutToShow() addSeparator(); - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.exec(QSL("SELECT title, url FROM history ORDER BY date DESC LIMIT 10")); while (query.next()) { diff --git a/src/lib/history/historymodel.cpp b/src/lib/history/historymodel.cpp index 01c1e7c69..630a20e95 100644 --- a/src/lib/history/historymodel.cpp +++ b/src/lib/history/historymodel.cpp @@ -18,9 +18,9 @@ #include "historymodel.h" #include "historyitem.h" #include "iconprovider.h" +#include "sqldatabase.h" #include -#include #include #include @@ -293,7 +293,7 @@ void HistoryModel::fetchMore(const QModelIndex &parent) idList.append(parentItem->child(i)->historyEntry.id); } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id, count, title, url, date FROM history WHERE date BETWEEN ? AND ? ORDER BY date DESC"); query.addBindValue(parentItem->endTimestamp()); query.addBindValue(parentItem->startTimestamp()); @@ -443,7 +443,7 @@ void HistoryModel::checkEmptyParentItem(HistoryItem* item) void HistoryModel::init() { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.exec("SELECT MIN(date) FROM history"); if (!query.next()) { return; @@ -489,7 +489,7 @@ void HistoryModel::init() itemName = QString("%1 %2").arg(History::titleCaseLocalizedMonth(timestampDate.month()), QString::number(timestampDate.year())); } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id FROM history WHERE date BETWEEN ? AND ? LIMIT 1"); query.addBindValue(endTimestamp); query.addBindValue(timestamp); diff --git a/src/lib/navigation/completer/locationcompletermodel.cpp b/src/lib/navigation/completer/locationcompletermodel.cpp index 33d0f1baf..d3daa3670 100644 --- a/src/lib/navigation/completer/locationcompletermodel.cpp +++ b/src/lib/navigation/completer/locationcompletermodel.cpp @@ -23,8 +23,7 @@ #include "qzsettings.h" #include "browserwindow.h" #include "tabwidget.h" - -#include +#include "sqldatabase.h" LocationCompleterModel::LocationCompleterModel(QObject* parent) : QStandardItemModel(parent) @@ -64,7 +63,7 @@ QList LocationCompleterModel::suggestionItems() const QSqlQuery LocationCompleterModel::createDomainQuery(const QString &text) { if (text.isEmpty() || text == QLatin1String("www.")) { - return QSqlQuery(); + return QSqlQuery(SqlDatabase::instance()->database()); } bool withoutWww = text.startsWith(QLatin1Char('w')) && !text.startsWith(QLatin1String("www.")); @@ -79,7 +78,7 @@ QSqlQuery LocationCompleterModel::createDomainQuery(const QString &text) query.append(QLatin1String("(url LIKE ? OR url LIKE ?) ORDER BY date DESC LIMIT 1")); - QSqlQuery sqlQuery; + QSqlQuery sqlQuery(SqlDatabase::instance()->database()); sqlQuery.prepare(query); if (withoutWww) { @@ -119,7 +118,7 @@ QSqlQuery LocationCompleterModel::createHistoryQuery(const QString &searchString query.append(QLatin1String("ORDER BY date DESC LIMIT ?")); - QSqlQuery sqlQuery; + QSqlQuery sqlQuery(SqlDatabase::instance()->database()); sqlQuery.prepare(query); if (exactMatch) { diff --git a/src/lib/navigation/completer/locationcompleterrefreshjob.cpp b/src/lib/navigation/completer/locationcompleterrefreshjob.cpp index b8ce24b67..36ac2ea06 100644 --- a/src/lib/navigation/completer/locationcompleterrefreshjob.cpp +++ b/src/lib/navigation/completer/locationcompleterrefreshjob.cpp @@ -117,7 +117,7 @@ void LocationCompleterRefreshJob::runJob() if (!m_searchString.isEmpty() && qzSettings->useInlineCompletion) { QSqlQuery domainQuery = LocationCompleterModel::createDomainQuery(m_searchString); if (!domainQuery.lastQuery().isEmpty()) { - SqlDatabase::instance()->exec(domainQuery); + domainQuery.exec(); if (domainQuery.next()) { m_domainCompletion = createDomainCompletion(domainQuery.value(0).toUrl().host()); } @@ -178,7 +178,7 @@ void LocationCompleterRefreshJob::completeFromHistory() if (showType == HistoryAndBookmarks || showType == History) { const int historyLimit = 20; QSqlQuery query = LocationCompleterModel::createHistoryQuery(m_searchString, historyLimit); - SqlDatabase::instance()->exec(query); + query.exec(); while (query.next()) { const QUrl url = query.value(1).toUrl(); @@ -203,8 +203,8 @@ void LocationCompleterRefreshJob::completeFromHistory() void LocationCompleterRefreshJob::completeMostVisited() { - QSqlQuery query(QSL("SELECT id, url, title FROM history ORDER BY count DESC LIMIT 15")); - SqlDatabase::instance()->exec(query); + QSqlQuery query(SqlDatabase::instance()->database()); + query.exec(QSL("SELECT id, url, title FROM history ORDER BY count DESC LIMIT 15")); while (query.next()) { QStandardItem* item = new QStandardItem(); diff --git a/src/lib/opensearch/searchenginesmanager.cpp b/src/lib/opensearch/searchenginesmanager.cpp index 7f1a7071f..e634d28aa 100644 --- a/src/lib/opensearch/searchenginesmanager.cpp +++ b/src/lib/opensearch/searchenginesmanager.cpp @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2010-2014 David Rosca +* Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,10 +26,10 @@ #include "settings.h" #include "qzsettings.h" #include "webview.h" +#include "sqldatabase.h" #include #include -#include #include #include @@ -82,7 +82,7 @@ void SearchEnginesManager::loadSettings() { m_settingsLoaded = true; - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.exec("SELECT name, icon, url, shortcut, suggestionsUrl, suggestionsParameters, postData FROM search_engines"); while (query.next()) { @@ -449,7 +449,7 @@ void SearchEnginesManager::removeEngine(const Engine &engine) return; } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("DELETE FROM search_engines WHERE name=? AND url=?"); query.bindValue(0, engine.name); query.bindValue(1, engine.url); @@ -493,7 +493,7 @@ void SearchEnginesManager::saveSettings() // // But as long as user is not playing with search engines every run it is acceptable. - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.exec("DELETE FROM search_engines"); foreach (const Engine &en, m_allEngines) { diff --git a/src/lib/other/clearprivatedata.cpp b/src/lib/other/clearprivatedata.cpp index c41e30fc1..00f5ab614 100644 --- a/src/lib/other/clearprivatedata.cpp +++ b/src/lib/other/clearprivatedata.cpp @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2010-2015 David Rosca +* Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/src/lib/other/iconchooser.cpp b/src/lib/other/iconchooser.cpp index ea7099e30..ba66e6fbe 100644 --- a/src/lib/other/iconchooser.cpp +++ b/src/lib/other/iconchooser.cpp @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2010-2016 David Rosca +* Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,9 +20,9 @@ #include "mainapplication.h" #include "proxystyle.h" #include "qztools.h" +#include "sqldatabase.h" #include -#include IconChooser::IconChooser(QWidget* parent) : QDialog(parent), @@ -64,7 +64,7 @@ void IconChooser::searchIcon(const QString &string) ui->iconList->clear(); - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare(QSL("SELECT icon FROM icons WHERE url GLOB ? LIMIT 20")); query.addBindValue(QString(QL1S("*%1*")).arg(QzTools::escapeSqlGlobString(string))); query.exec(); diff --git a/src/lib/other/siteinfowidget.cpp b/src/lib/other/siteinfowidget.cpp index 5ae26b016..7859408af 100644 --- a/src/lib/other/siteinfowidget.cpp +++ b/src/lib/other/siteinfowidget.cpp @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2010-2014 David Rosca +* Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,9 +22,9 @@ #include "mainapplication.h" #include "webpage.h" #include "tabbedwebview.h" +#include "sqldatabase.h" #include -#include SiteInfoWidget::SiteInfoWidget(BrowserWindow* window, QWidget* parent) : LocationBarPopup(parent) @@ -48,9 +48,9 @@ SiteInfoWidget::SiteInfoWidget(BrowserWindow* window, QWidget* parent) } QString scheme = view->url().scheme(); - QSqlQuery query; QString host = view->url().host(); + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT sum(count) FROM history WHERE url LIKE ?"); query.addBindValue(QString("%1://%2%").arg(scheme, host)); query.exec(); diff --git a/src/lib/preferences/autofillmanager.cpp b/src/lib/preferences/autofillmanager.cpp index d3f76666b..9a2fbccd5 100644 --- a/src/lib/preferences/autofillmanager.cpp +++ b/src/lib/preferences/autofillmanager.cpp @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2010-2016 David Rosca +* Copyright (C) 2010-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,11 +23,11 @@ #include "mainapplication.h" #include "settings.h" #include "qztools.h" +#include "sqldatabase.h" #include #include #include -#include #include #include #include @@ -97,7 +97,7 @@ void AutoFillManager::loadPasswords() ui->treePass->addTopLevelItem(item); } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.exec("SELECT server, id FROM autofill_exceptions"); ui->treeExcept->clear(); while (query.next()) { @@ -275,7 +275,7 @@ void AutoFillManager::removeExcept() return; } QString id = curItem->data(0, Qt::UserRole + 10).toString(); - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("DELETE FROM autofill_exceptions WHERE id=?"); query.addBindValue(id); query.exec(); @@ -285,7 +285,7 @@ void AutoFillManager::removeExcept() void AutoFillManager::removeAllExcept() { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.exec("DELETE FROM autofill_exceptions"); ui->treeExcept->clear(); diff --git a/src/lib/tools/iconprovider.cpp b/src/lib/tools/iconprovider.cpp index 6abcaf96c..ae1c92487 100644 --- a/src/lib/tools/iconprovider.cpp +++ b/src/lib/tools/iconprovider.cpp @@ -192,10 +192,10 @@ QImage IconProvider::imageForUrl(const QUrl &url, bool allowNull) } } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare(QSL("SELECT icon FROM icons WHERE url GLOB ? LIMIT 1")); query.addBindValue(QString("%1*").arg(QzTools::escapeSqlGlobString(QString::fromUtf8(encodedUrl)))); - SqlDatabase::instance()->exec(query); + query.exec(); if (query.next()) { return QImage::fromData(query.value(0).toByteArray()); @@ -221,11 +221,10 @@ QImage IconProvider::imageForDomain(const QUrl &url, bool allowNull) } } - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare(QSL("SELECT icon FROM icons WHERE url GLOB ? LIMIT 1")); - query.addBindValue(QString("*%1*").arg(QzTools::escapeSqlGlobString(url.host()))); - SqlDatabase::instance()->exec(query); + query.exec(); if (query.next()) { return QImage::fromData(query.value(0).toByteArray()); @@ -242,7 +241,7 @@ IconProvider* IconProvider::instance() void IconProvider::saveIconsToDatabase() { foreach (const BufferedIcon &ic, m_iconBuffer) { - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare("SELECT id FROM icons WHERE url = ?"); query.bindValue(0, ic.first.toEncoded(QUrl::RemoveFragment)); query.exec(); @@ -272,13 +271,15 @@ void IconProvider::clearOldIconsInDatabase() // Delete icons for entries older than 6 months const QDateTime date = QDateTime::currentDateTime().addMonths(-6); - QSqlQuery query; + QSqlQuery query(SqlDatabase::instance()->database()); query.prepare(QSL("DELETE FROM icons WHERE url IN (SELECT url FROM history WHERE date < ?)")); query.addBindValue(date.toMSecsSinceEpoch()); query.exec(); query.clear(); - query.exec(QSL("VACUUM")); + + query.prepare(QSL("VACUUM")); + SqlDatabase::instance()->exec(query); } QIcon IconProvider::iconFromImage(const QImage &image) diff --git a/src/lib/tools/sqldatabase.cpp b/src/lib/tools/sqldatabase.cpp index b0203c7ac..8d843eaee 100644 --- a/src/lib/tools/sqldatabase.cpp +++ b/src/lib/tools/sqldatabase.cpp @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2014 David Rosca +* Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,12 +17,13 @@ * ============================================================ */ #include "sqldatabase.h" -#include -#include #include +#include #include +QThreadStorage s_databases; + Q_GLOBAL_STATIC(SqlDatabase, qz_sql_database) // SqlDatabase @@ -33,36 +34,27 @@ SqlDatabase::SqlDatabase(QObject* parent) SqlDatabase::~SqlDatabase() { - QMutableHashIterator i(m_databases); - while (i.hasNext()) { - i.next(); - i.value().close(); - } } -QSqlDatabase SqlDatabase::databaseForThread(QThread* thread) +QSqlDatabase SqlDatabase::database() { - QMutexLocker lock(&m_mutex); - - if (!m_databases.contains(thread)) { - const QString threadStr = QString::number((quintptr) thread); - m_databases[thread] = QSqlDatabase::cloneDatabase(QSqlDatabase::database(), QL1S("Falkon/") + threadStr); - m_databases[thread].open(); + if (QThread::currentThread() == qApp->thread()) { + return QSqlDatabase::database(); } - Q_ASSERT(m_databases[thread].isOpen()); + if (!s_databases.hasLocalData()) { + const QString threadStr = QString::number((quintptr) QThread::currentThread()); + QSqlDatabase db = QSqlDatabase::cloneDatabase(QSqlDatabase::database(), QL1S("Falkon/") + threadStr); + db.open(); + s_databases.setLocalData(db); + } - return m_databases[thread]; + return s_databases.localData(); } QSqlQuery SqlDatabase::exec(QSqlQuery &query) { - if (QThread::currentThread() == qApp->thread()) { - query.exec(); - return query; - } - - QSqlQuery out(databaseForThread(QThread::currentThread())); + QSqlQuery out(database()); out.prepare(query.lastQuery()); const QList boundValues = query.boundValues().values(); diff --git a/src/lib/tools/sqldatabase.h b/src/lib/tools/sqldatabase.h index 3fa443040..ad146bf0c 100644 --- a/src/lib/tools/sqldatabase.h +++ b/src/lib/tools/sqldatabase.h @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2014 David Rosca +* Copyright (C) 2014-2017 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,8 +23,6 @@ #include #include -#include // Fix build with Qt 4.7 - #include "qzcommon.h" class FALKON_EXPORT SqlDatabase : public QObject @@ -35,8 +33,8 @@ public: explicit SqlDatabase(QObject* parent = 0); ~SqlDatabase(); - // Returns database connection for thread, creates new connection if not exists - QSqlDatabase databaseForThread(QThread* thread); + // Returns database connection for current thread + QSqlDatabase database(); // Executes query using correct database for current thread QSqlQuery exec(QSqlQuery &query); @@ -45,10 +43,6 @@ public: QFuture execAsync(const QSqlQuery &query); static SqlDatabase* instance(); - -private: - QHash m_databases; - QMutex m_mutex; }; #endif // SQLDATABASE_H