blob: 5a08a04ba33c8b495fa001948747738e3aa1df8a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#pragma once
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QString>
#include <QVariant>
#include "util/assert.h"
#include "util/db/dbfieldindex.h"
#include "util/db/dbid.h"
// forward declarations
class SqlQueryFinisher;
class FwdSqlQuerySelectResult;
// A forward-only QSqlQuery that is prepared immediately
// during initialization. It offers a limited set of functions
// from QSqlQuery.
//
// Setting QSqlQuery to forward-only causes memory savings since
// QSqlCachedResult (what QtSQLite uses) won't allocate a giant
// in-memory table that we won't use at all when invoking only
// QSqlQuery::next() to iterate over the results.
//
// Prefer to use this derived class instead of QSqlQuery to avoid
// performance bottlenecks and for implicit logging failed query
// executions.
//
// Please note that forward-only queries don't provide information
// about the size of the result set!
class FwdSqlQuery : protected QSqlQuery {
friend class SqlQueryFinisher;
friend class FwdSqlQuerySelectResult;
public:
FwdSqlQuery()
: m_prepared(false) {
}
FwdSqlQuery(
const QSqlDatabase& database,
const QString& statement);
bool isPrepared() const {
return m_prepared;
}
bool hasError() const {
return lastError().isValid() &&
(lastError().type() != QSqlError::NoError);
}
bool hasDuplicateColumnNameError() const;
QSqlError lastError() const {
return QSqlQuery::lastError();
}
void bindValue(const QString& placeholder, const QVariant& value) {
QSqlQuery::bindValue(placeholder, value);
}
// Overloaded function for type DbId
void bindValue(const QString& placeholder, const DbId& value) {
bindValue(placeholder, value.toVariant());
}
QString executedQuery() const {
return QSqlQuery::executedQuery();
}
// Execute the prepared query and log errors on failure.
//
// Please note, that the member function exec() inherited
// from the base class QSqlQuery is not polymorphic (virtual)
// and can't be overridden safely!
bool execPrepared();
QSqlRecord record() const {
return QSqlQuery::record();
}
int numRowsAffected() const {
DEBUG_ASSERT(!hasError());
return QSqlQuery::numRowsAffected();
}
QVariant lastInsertId() const {
DEBUG_ASSERT(!lastError().isValid());
DEBUG_ASSERT(!isSelect());
QVariant result(QSqlQuery::lastInsertId());
DEBUG_ASSERT(result.isValid());
DEBUG_ASSERT(!result.isNull());
return result;
}
bool next() {
DEBUG_ASSERT(!hasError());
DEBUG_ASSERT(isSelect());
return QSqlQuery::next();
}
DbFieldIndex fieldIndex(const QString& fieldName) const;
QVariant fieldValue(DbFieldIndex fieldIndex) const {
DEBUG_ASSERT(!hasError());
DEBUG_ASSERT(isSelect());
return value(fieldIndex);
}
bool fieldValueBoolean(DbFieldIndex fieldIndex) const;
private:
bool m_prepared;
};
|