cutelyst 4.3.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
sql.cpp
1/*
2 * SPDX-FileCopyrightText: (C) 2015-2022 Daniel Nicoletti <dantti12@gmail.com>
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5#include "sql.h"
6
7#include <QJsonArray>
8#include <QJsonObject>
9#include <QJsonValue>
10#include <QLoggingCategory>
11#include <QThread>
12#include <QtSql/QSqlError>
13#include <QtSql/QSqlQuery>
14#include <QtSql/QSqlRecord>
15
16Q_LOGGING_CATEGORY(C_SQL, "cutelyst.utils.sql", QtWarningMsg)
17
18using namespace Cutelyst;
19
21{
22 QVariantHash ret;
23 if (query.next()) {
24 const QSqlRecord record = query.record();
25 const int columns = record.count();
26 for (int i = 0; i < columns; ++i) {
27 ret.insert(record.fieldName(i), query.value(i));
28 }
29 }
30 return ret;
31}
32
33QVariantList Sql::queryToHashList(QSqlQuery &query)
34{
35 QVariantList ret;
36 const QSqlRecord record = query.record();
37 const int columns = record.count();
38 QStringList cols;
39 for (int i = 0; i < columns; ++i) {
40 cols.append(record.fieldName(i));
41 }
42
43 while (query.next()) {
44 QVariantHash line;
45 for (int i = 0; i < columns; ++i) {
46 line.insert(cols.at(i), query.value(i));
47 }
48 ret.append(line);
49 }
50 return ret;
51}
52
54{
55 QVariantMap ret;
56 if (query.next()) {
57 const QSqlRecord record = query.record();
58 const int columns = record.count();
59 for (int i = 0; i < columns; ++i) {
60 ret.insert(record.fieldName(i), query.value(i));
61 }
62 }
63 return ret;
64}
65
67{
68 QJsonObject ret;
69 if (query.next()) {
70 const QSqlRecord record = query.record();
71 const int columns = record.count();
72 for (int i = 0; i < columns; ++i) {
73 ret.insert(record.fieldName(i), QJsonValue::fromVariant(query.value(i)));
74 }
75 }
76 return ret;
77}
78
79QVariantList Sql::queryToMapList(QSqlQuery &query)
80{
81 QVariantList ret;
82 const QSqlRecord record = query.record();
83 const int columns = record.count();
84 QStringList cols;
85 for (int i = 0; i < columns; ++i) {
86 cols.append(record.fieldName(i));
87 }
88
89 while (query.next()) {
90 QVariantMap line;
91 for (int i = 0; i < columns; ++i) {
92 line.insert(cols.at(i), query.value(i));
93 }
94 ret.append(line);
95 }
96 return ret;
97}
98
100{
101 QJsonArray ret;
102 const QSqlRecord record = query.record();
103 const int columns = record.count();
104 QStringList cols;
105 for (int i = 0; i < columns; ++i) {
106 cols.append(record.fieldName(i));
107 }
108
109 while (query.next()) {
110 QJsonObject line;
111 for (int i = 0; i < columns; ++i) {
112 line.insert(cols.at(i), QJsonValue::fromVariant(query.value(i)));
113 }
114 ret.append(line);
115 }
116 return ret;
117}
118
119QVariantList Sql::queryToList(QSqlQuery &query)
120{
121 QVariantList ret;
122
123 const int columns = query.record().count();
124 while (query.next()) {
125 QVariantList line;
126 for (int i = 0; i < columns; ++i) {
127 line.append(query.value(i));
128 }
129 ret.append(QVariant::fromValue(line));
130 }
131
132 return ret;
133}
134
136{
137 QJsonArray ret;
138
139 const int columns = query.record().count();
140 while (query.next()) {
141 QJsonArray array;
142 for (int i = 0; i < columns; ++i) {
143 array.append(QJsonValue::fromVariant(query.value(i)));
144 }
145 ret.append(array);
146 }
147
148 return ret;
149}
150
151QVariantHash Sql::queryToIndexedHash(QSqlQuery &query, const QString &key)
152{
153 QVariantHash ret;
154
155 const QSqlRecord record = query.record();
156 int index = record.indexOf(key);
157 if (index == -1) {
158 qCCritical(C_SQL) << "Field Name " << key << " not found in result set";
159 return ret;
160 }
161
162 const int columns = record.count();
163 QStringList cols;
164
165 for (int i = 0; i < columns; ++i) {
166 cols.append(record.fieldName(i));
167 }
168
169 while (query.next()) {
170 QVariantHash line;
171 for (int i = 0; i < columns; ++i) {
172 if (i != index) {
173 line.insert(cols.at(i), query.value(i));
174 }
175 }
176
177 ret.insert(query.value(index).toString(), line);
178 }
179
180 return ret;
181}
182
184{
185 QJsonObject ret;
186
187 const QSqlRecord record = query.record();
188 int index = record.indexOf(key);
189 if (index == -1) {
190 qCCritical(C_SQL) << "Field Name " << key << " not found in result set";
191 return ret;
192 }
193
194 const int columns = record.count();
195 QStringList cols;
196
197 for (int i = 0; i < columns; ++i) {
198 cols.append(record.fieldName(i));
199 }
200
201 while (query.next()) {
202 QJsonObject obj;
203 for (int i = 0; i < columns; ++i) {
204 if (i != index) {
205 obj.insert(cols.at(i), QJsonValue::fromVariant(query.value(i)));
206 }
207 }
208
209 ret.insert(query.value(index).toString(), obj);
210 }
211
212 return ret;
213}
214
216 const Cutelyst::ParamsMultiMap &params,
217 bool htmlEscaped)
218{
219 auto it = params.constBegin();
220 if (htmlEscaped) {
221 while (it != params.constEnd()) {
222 if (it.value().isNull()) {
223 query.bindValue(u':' + it.key(), QVariant());
224 } else {
225 query.bindValue(u':' + it.key(), it.value().toHtmlEscaped());
226 }
227 ++it;
228 }
229 } else {
230 while (it != params.constEnd()) {
231 if (it.value().isNull()) {
232 query.bindValue(u':' + it.key(), QVariant());
233 } else {
234 query.bindValue(u':' + it.key(), it.value());
235 }
236 ++it;
237 }
238 }
239}
240
241QSqlQuery Sql::preparedQuery(const QString &query, QSqlDatabase db, bool forwardOnly)
242{
243 QSqlQuery sqlQuery(db);
244 sqlQuery.setForwardOnly(forwardOnly);
245 if (!sqlQuery.prepare(query)) {
246 qCCritical(C_SQL) << "Failed to prepare query:" << query
247 << sqlQuery.lastError().databaseText();
248 }
249 return sqlQuery;
250}
251
252QSqlQuery Sql::preparedQueryThread(const QString &query, const QString &dbName, bool forwardOnly)
253{
255 sqlQuery.setForwardOnly(forwardOnly);
256 if (!sqlQuery.prepare(query)) {
257 qCCritical(C_SQL) << "Failed to prepare query:" << query
258 << sqlQuery.lastError().databaseText();
259 }
260 return sqlQuery;
261}
262
264{
265 return dbName + u'-' + QThread::currentThread()->objectName();
266}
267
272
274 : m_db(databaseThread(databaseName))
275{
276 m_transactionRunning = m_db.transaction();
277}
278
280 : m_db(database)
281{
282 m_transactionRunning = m_db.transaction();
283}
284
286{
287 if (m_transactionRunning) {
288 m_db.rollback();
289 }
290}
291
293{
294 return m_transactionRunning;
295}
296
298{
299 // In case we fail to commit we will still call rollback, not sure it's really needed
300 m_transactionRunning = !m_db.commit();
301 return !m_transactionRunning;
302}
303
305{
306 m_transactionRunning = false;
307 return m_db.rollback();
308}
bool transaction() const
Definition sql.cpp:292
Transaction(const QString &databaseName=QString())
Definition sql.cpp:273
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QVariantList queryToHashList(QSqlQuery &query)
Definition sql.cpp:33
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QVariantMap queryToMapObject(QSqlQuery &query)
Definition sql.cpp:53
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QVariantHash queryToHashObject(QSqlQuery &query)
Definition sql.cpp:20
CUTELYST_PLUGIN_UTILS_SQL_EXPORT void bindParamsToQuery(QSqlQuery &query, const Cutelyst::ParamsMultiMap &params, bool htmlEscaped=true)
Definition sql.cpp:215
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QJsonArray queryToJsonObjectArray(QSqlQuery &query)
Definition sql.cpp:99
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QString databaseNameThread(const QString &dbName=QString())
Definition sql.cpp:263
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QSqlQuery preparedQuery(const QString &query, QSqlDatabase db=QSqlDatabase(), bool forwardOnly=false)
Definition sql.cpp:241
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QVariantList queryToList(QSqlQuery &query)
Definition sql.cpp:119
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QJsonObject queryToIndexedJsonObject(QSqlQuery &query, const QString &key)
Definition sql.cpp:183
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QVariantList queryToMapList(QSqlQuery &query)
Definition sql.cpp:79
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QSqlDatabase databaseThread(const QString &dbName=QString())
Definition sql.cpp:268
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QVariantHash queryToIndexedHash(QSqlQuery &query, const QString &key)
Definition sql.cpp:151
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QJsonArray queryToJsonArray(QSqlQuery &query)
Definition sql.cpp:135
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QSqlQuery preparedQueryThread(const QString &query, const QString &dbName=QString(), bool forwardOnly=false)
Definition sql.cpp:252
CUTELYST_PLUGIN_UTILS_SQL_EXPORT QJsonObject queryToJsonObject(QSqlQuery &query)
Definition sql.cpp:66
The Cutelyst namespace holds all public Cutelyst API.
void append(const QJsonValue &value)
QJsonObject::iterator insert(QLatin1StringView key, const QJsonValue &value)
QJsonValue fromVariant(const QVariant &variant)
void append(QList::parameter_type value)
QList::const_reference at(qsizetype i) const const
QMultiMap::const_iterator constBegin() const const
QMultiMap::const_iterator constEnd() const const
QSqlDatabase database(const QString &connectionName, bool open)
bool transaction()
QString databaseText() const const
void bindValue(const QString &placeholder, const QVariant &val, QSql::ParamType paramType)
QSqlError lastError() const const
bool next()
bool prepare(const QString &query)
QSqlRecord record() const const
void setForwardOnly(bool forward)
QVariant value(const QString &name) const const
int count() const const
QString fieldName(int index) const const
int indexOf(const QString &name) const const
QThread * currentThread()
QVariant fromValue(const T &value)
QString toString() const const