Falkon Develop
Cross-platform Qt-based web browser
sqldatabase.cpp
Go to the documentation of this file.
1/* ============================================================
2* Falkon - Qt web browser
3* Copyright (C) 2014-2018 David Rosca <nowrep@gmail.com>
4*
5* This program is free software: you can redistribute it and/or modify
6* it under the terms of the GNU General Public License as published by
7* the Free Software Foundation, either version 3 of the License, or
8* (at your option) any later version.
9*
10* This program is distributed in the hope that it will be useful,
11* but WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program. If not, see <http://www.gnu.org/licenses/>.
17* ============================================================ */
18#include "sqldatabase.h"
19
20#include <QApplication>
21#include <QThreadStorage>
22#include <QFutureWatcher>
23#include <QtConcurrent/QtConcurrentRun>
24
25QThreadStorage<QSqlDatabase> s_databases;
26
27Q_GLOBAL_STATIC(SqlDatabase, qz_sql_database)
28
29// SqlQueryJob
30SqlQueryJob::SqlQueryJob(QObject *parent)
31 : QObject(parent)
32{
33}
34
35SqlQueryJob::SqlQueryJob(const QString &query, QObject *parent)
36 : QObject(parent)
37{
38 setQuery(query);
39}
40
41void SqlQueryJob::setQuery(const QString &query)
42{
43 m_query = query;
44}
45
46void SqlQueryJob::addBindValue(const QVariant &value)
47{
48 m_boundValues.append(value);
49}
50
51QSqlError SqlQueryJob::error() const
52{
53 return m_error;
54}
55
57{
58 return m_lastInsertId;
59}
60
62{
63 return m_numRowsAffected;
64}
65
66QVector<QSqlRecord> SqlQueryJob::records() const
67{
68 return m_records;
69}
70
72{
73 struct Result {
74 QSqlError error;
75 QVariant lastInsertId;
77 QVector<QSqlRecord> records;
78 };
79
80 const QString query = m_query;
81 m_query.clear();
82 const QVector<QVariant> boundValues = m_boundValues;
83 m_boundValues.clear();
84
85 auto watcher = new QFutureWatcher<Result>(this);
86 connect(watcher, &QFutureWatcher<Result>::finished, this, [=]() {
87 deleteLater();
88 const auto result = watcher->result();
89 m_error = result.error;
90 m_lastInsertId = result.lastInsertId;
91 m_numRowsAffected = result.numRowsAffected;
92 m_records = result.records;
93 Q_EMIT finished(this);
94 });
95
96 watcher->setFuture(QtConcurrent::run([=]() {
97 QSqlQuery q(SqlDatabase::instance()->database());
98 q.prepare(query);
99 for (const QVariant &value : boundValues) {
100 q.addBindValue(value);
101 }
102 q.exec();
103 Result res;
104 res.error = q.lastError();
105 res.lastInsertId = q.lastInsertId();
106 res.numRowsAffected = q.numRowsAffected();
107 while (q.next()) {
108 res.records.append(q.record());
109 }
110 return res;
111 }));
112}
113
114// SqlDatabase
116 : QObject(parent)
117{
118}
119
121= default;
122
124{
125 if (QThread::currentThread() == qApp->thread()) {
126 return QSqlDatabase::database();
127 }
128
129 if (!s_databases.hasLocalData()) {
130 const QString threadStr = QStringLiteral("Falkon/%1").arg((quintptr) QThread::currentThread());
131 QSqlDatabase::removeDatabase(threadStr);
132 QSqlDatabase db = QSqlDatabase::addDatabase(QSL("QSQLITE"), threadStr);
133 db.setDatabaseName(m_databaseName);
134 db.setConnectOptions(m_connectOptions);
135 db.open();
136 s_databases.setLocalData(db);
137 }
138
139 return s_databases.localData();
140}
141
142void SqlDatabase::setDatabase(const QSqlDatabase &database)
143{
144 m_databaseName = database.databaseName();
145 m_connectOptions = database.connectOptions();
146}
147
148// instance
150{
151 return qz_sql_database();
152}
SqlDatabase(QObject *parent=nullptr)
static SqlDatabase * instance()
void setDatabase(const QSqlDatabase &database)
QSqlDatabase database()
QSqlError error() const
Definition: sqldatabase.cpp:51
QVariant lastInsertId() const
Definition: sqldatabase.cpp:56
void start()
Definition: sqldatabase.cpp:71
SqlQueryJob(QObject *parent=nullptr)
Definition: sqldatabase.cpp:30
void addBindValue(const QVariant &value)
Definition: sqldatabase.cpp:46
int numRowsAffected() const
Definition: sqldatabase.cpp:61
void setQuery(const QString &query)
Definition: sqldatabase.cpp:41
QVector< QSqlRecord > records() const
Definition: sqldatabase.cpp:66
void finished(SqlQueryJob *job)
int value(const QColor &c)
Definition: colors.cpp:238
#define QSL(x)
Definition: qzcommon.h:40
QThreadStorage< QSqlDatabase > s_databases
Definition: sqldatabase.cpp:25