kernel/qsqlresult.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/****************************************************************************-
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSql module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/****************************************************************************
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtSql module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
9** Commercial License Usage -
10** Licensees holding valid commercial Qt licenses may use this file in -
11** accordance with the commercial license agreement provided with the -
12** Software or, alternatively, in accordance with the terms contained in -
13** a written agreement between you and Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qsqlresult.h" -
43 -
44#include "qvariant.h" -
45#include "qhash.h" -
46#include "qregexp.h" -
47#include "qsqlerror.h" -
48#include "qsqlfield.h" -
49#include "qsqlrecord.h" -
50#include "qvector.h" -
51#include "qsqldriver.h" -
52#include "qpointer.h" -
53#include "qsqlresult_p.h" -
54#include <QDebug> -
55 -
56QT_BEGIN_NAMESPACE -
57 -
58struct QHolder {-
QHolder(const QString& hldr = QString(), int index = -1): holderName(hldr), holderPos(index) {}
bool operator==(const QHolder& h) const { return h.holderPos == holderPos && h.holderName == holderName; }
bool operator!=(const QHolder& h) const { return h.holderPos != holderPos || h.holderName != holderName; }
QString holderName;
int holderPos;
};
class QSqlResultPrivate
{
public:
QSqlResultPrivate(QSqlResult* d)
: q(d), idx(QSql::BeforeFirstRow), active(false),
isSel(false), forwardOnly(false), precisionPolicy(QSql::LowPrecisionDouble), bindCount(0), binds(QSqlResult::PositionalBinding)
{}
void clearValues()
{
values.clear();
bindCount = 0;
}
void resetBindCount()
{
bindCount = 0;
}
void clearIndex()
{
indexes.clear();
holders.clear();
types.clear();
}
void clear()
{
clearValues();
clearIndex();;
}
QString positionalToNamedBinding();
QString namedToPositionalBinding();
QString holderAt(int index) const;
public:
QSqlResult* q;
QPointer<QSqlDriver> sqldriver;
int idx;
QString sql;
bool active;
bool isSel;
QSqlError error;
bool forwardOnly;
QSql::NumericalPrecisionPolicy precisionPolicy;
int bindCount;
QSqlResult::BindingSyntax binds;
QString executedQuery;
QHash<int, QSql::ParamType> types;
QVector<QVariant> values;
typedef QHash<QString, QList<int> > IndexMap;
IndexMap indexes;
typedef QVector<QHolder> QHolderVector;
QHolderVector holders;
};
static QString qFieldSerial(int);QString QSqlResultPrivate::holderAt(int index) const
59{ -
60 return holders.size() > index ? holders.at(index).holderName : qFieldSerialfieldSerial(index);
executed: return holders.size() > index ? holders.at(index).holderName : fieldSerial(index);
Execution Count:136
136
61} -
62 -
63// return a unique id for bound names -
64staticQString qFieldSerialQSqlResultPrivate::fieldSerial(int i) -
65{ -
66 ushort arr[] = { ':', 'f', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
executed (the execution status of this line is deduced): ushort arr[] = { ':', 'f', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
67 ushort *ptr = &arr[1];
executed (the execution status of this line is deduced): ushort *ptr = &arr[1];
-
68 -
69 while (i > 0) {
evaluated: i > 0
TRUEFALSE
yes
Evaluation Count:116817
yes
Evaluation Count:233566
116817-233566
70 *(++ptr) = 'a' + i % 16;
executed (the execution status of this line is deduced): *(++ptr) = 'a' + i % 16;
-
71 i >>= 4;
executed (the execution status of this line is deduced): i >>= 4;
-
72 }
executed: }
Execution Count:116817
116817
73 -
74 return QString(reinterpret_cast<const QChar *>(arr), int(ptr - arr) + 1);
executed: return QString(reinterpret_cast<const QChar *>(arr), int(ptr - arr) + 1);
Execution Count:233566
233566
75} -
76 -
77static bool qIsAlnum(QChar ch) -
78{ -
79 uint u = uint(ch.unicode()); -
80 // matches [a-zA-Z0-9_] -
81 return u - 'a' < 26 || u - 'A' < 26 || u - '0' < 10 || u == '_'; -
82} -
83 -
84QString QSqlResultPrivate::positionalToNamedBinding()(const QString &query, QString (fieldSerialFunc)(int idx)) -
85{ -
86 int n = sqlquery.size();
executed (the execution status of this line is deduced): int n = query.size();
-
87 -
88 QString result;
executed (the execution status of this line is deduced): QString result;
-
89 result.reserve(n * 5 / 4);
executed (the execution status of this line is deduced): result.reserve(n * 5 / 4);
-
90 bool inQuote = falseQChar closingQuote;
executed (the execution status of this line is deduced): QChar closingQuote;
-
91 int count = 0;
executed (the execution status of this line is deduced): int count = 0;
-
92 -
93 for (int i = 0; i < n; ++i) {
evaluated: i < n
TRUEFALSE
yes
Evaluation Count:253
yes
Evaluation Count:13
13-253
94 QChar ch = sqlquery.at(i);
executed (the execution status of this line is deduced): QChar ch = query.at(i);
-
95 if (!closingQuote.isNull()) {
evaluated: !closingQuote.isNull()
TRUEFALSE
yes
Evaluation Count:38
yes
Evaluation Count:215
38-215
96 if (ch == closingQuote) {
evaluated: ch == closingQuote
TRUEFALSE
yes
Evaluation Count:16
yes
Evaluation Count:22
16-22
97 if (closingQuote == QLatin1Char('?]')
evaluated: closingQuote == QLatin1Char(']')
TRUEFALSE
yes
Evaluation Count:8
yes
Evaluation Count:8
8
98 && !inQuotei + 1 < n && query.at(i + 1) == closingQuote) {
evaluated: i + 1 < n
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:5
partially evaluated: query.at(i + 1) == closingQuote
TRUEFALSE
yes
Evaluation Count:3
no
Evaluation Count:0
0-5
99 // consume the extra character. don't close. -
100 ++i;
executed (the execution status of this line is deduced): ++i;
-
101 result += qFieldSerialch;
executed (the execution status of this line is deduced): result += ch;
-
102 } else {
executed: }
Execution Count:3
3
103 closingQuote = QChar();
executed (the execution status of this line is deduced): closingQuote = QChar();
-
104 }
executed: }
Execution Count:13
13
105 } -
106 result += ch;
executed (the execution status of this line is deduced): result += ch;
-
107 } else {
executed: }
Execution Count:38
38
108 if (ch == QLatin1Char('?')) {
evaluated: ch == QLatin1Char('?')
TRUEFALSE
yes
Evaluation Count:10
yes
Evaluation Count:205
10-205
109 result += fieldSerialFunc(count++);
executed (the execution status of this line is deduced): result += fieldSerialFunc(count++);
-
110 } else {
executed: }
Execution Count:10
10
111 if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`'))inQuote
evaluated: ch == QLatin1Char('\'')
TRUEFALSE
yes
Evaluation Count:5
yes
Evaluation Count:200
evaluated: ch == QLatin1Char('"')
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:197
partially evaluated: ch == QLatin1Char('`')
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:197
0-200
112 closingQuote =!inQuote ch;
executed: closingQuote = ch;
Execution Count:8
8
113 else if (ch == QLatin1Char('['))
evaluated: ch == QLatin1Char('[')
TRUEFALSE
yes
Evaluation Count:5
yes
Evaluation Count:192
5-192
114 closingQuote = QLatin1Char(']');
executed: closingQuote = QLatin1Char(']');
Execution Count:5
5
115 result += ch;
executed (the execution status of this line is deduced): result += ch;
-
116 }
executed: }
Execution Count:205
205
117 } -
118 } -
119 result.squeeze();
executed (the execution status of this line is deduced): result.squeeze();
-
120 return result;
executed: return result;
Execution Count:13
13
121} -
122 -
123QString QSqlResultPrivate::namedToPositionalBinding()(const QString &query) -
124{ -
125 int n =sql query.size();
executed (the execution status of this line is deduced): int n = query.size();
-
126 -
127 QString result;
executed (the execution status of this line is deduced): QString result;
-
128 result.reserve(n);bool inQuote = false
executed (the execution status of this line is deduced): result.reserve(n);
-
129 QChar closingQuote;
executed (the execution status of this line is deduced): QChar closingQuote;
-
130 int count = 0;
executed (the execution status of this line is deduced): int count = 0;
-
131 int i = 0;
executed (the execution status of this line is deduced): int i = 0;
-
132 -
133 while (i < n) {
evaluated: i < n
TRUEFALSE
yes
Evaluation Count:12759
yes
Evaluation Count:247
247-12759
134 QChar ch =sql query.at(i);
executed (the execution status of this line is deduced): QChar ch = query.at(i);
-
135 if (!closingQuote.isNull()) {
evaluated: !closingQuote.isNull()
TRUEFALSE
yes
Evaluation Count:1302
yes
Evaluation Count:11457
1302-11457
136 if (ch == closingQuote) {
evaluated: ch == closingQuote
TRUEFALSE
yes
Evaluation Count:244
yes
Evaluation Count:1058
244-1058
137 if (closingQuote == QLatin1Char(':]')
evaluated: closingQuote == QLatin1Char(']')
TRUEFALSE
yes
Evaluation Count:10
yes
Evaluation Count:234
10-234
138 &&!inQuote i + 1 < n && query.at(i + 1) == closingQuote) {
evaluated: i + 1 < n
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:7
partially evaluated: query.at(i + 1) == closingQuote
TRUEFALSE
yes
Evaluation Count:3
no
Evaluation Count:0
0-7
139 // consume the extra character. don't close. -
140 ++i;
executed (the execution status of this line is deduced): ++i;
-
141 result += ch;
executed (the execution status of this line is deduced): result += ch;
-
142 } else {
executed: }
Execution Count:3
3
143 closingQuote = QChar();
executed (the execution status of this line is deduced): closingQuote = QChar();
-
144 }
executed: }
Execution Count:241
241
145 } -
146 result += ch;
executed (the execution status of this line is deduced): result += ch;
-
147 ++i;
executed (the execution status of this line is deduced): ++i;
-
148 } else {
executed: }
Execution Count:1302
1302
149 if (ch == QLatin1Char(':')
evaluated: ch == QLatin1Char(':')
TRUEFALSE
yes
Evaluation Count:30
yes
Evaluation Count:11427
30-11427
150 && (i == 0 ||sql query.at(i - 1) != QLatin1Char(':'))
partially evaluated: i == 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:30
partially evaluated: query.at(i - 1) != QLatin1Char(':')
TRUEFALSE
yes
Evaluation Count:30
no
Evaluation Count:0
0-30
151 && (i + 1 < n && qIsAlnum(sqlquery.at(i + 1)))) {
partially evaluated: i + 1 < n
TRUEFALSE
yes
Evaluation Count:30
no
Evaluation Count:0
partially evaluated: qIsAlnum(query.at(i + 1))
TRUEFALSE
yes
Evaluation Count:30
no
Evaluation Count:0
0-30
152 int pos = i + 2;
executed (the execution status of this line is deduced): int pos = i + 2;
-
153 while (pos < n && qIsAlnum(sqlquery.at(pos)))
evaluated: pos < n
TRUEFALSE
yes
Evaluation Count:56
yes
Evaluation Count:3
evaluated: qIsAlnum(query.at(pos))
TRUEFALSE
yes
Evaluation Count:29
yes
Evaluation Count:27
3-56
154 ++pos;
executed: ++pos;
Execution Count:29
29
155 QString holder(sqlquery.mid(i, pos - i));
executed (the execution status of this line is deduced): QString holder(query.mid(i, pos - i));
-
156 indexes[holder].append(count++);
executed (the execution status of this line is deduced): indexes[holder].append(count++);
-
157 holders.append(QHolder(holder, i));
executed (the execution status of this line is deduced): holders.append(QHolder(holder, i));
-
158 result += QLatin1Char('?');
executed (the execution status of this line is deduced): result += QLatin1Char('?');
-
159 i = pos;
executed (the execution status of this line is deduced): i = pos;
-
160 } else {
executed: }
Execution Count:30
30
161 if (ch == QLatin1Char('\'') || ch == QLatin1Char('"') || ch == QLatin1Char('`'))
evaluated: ch == QLatin1Char('\'')
TRUEFALSE
yes
Evaluation Count:12
yes
Evaluation Count:11415
evaluated: ch == QLatin1Char('"')
TRUEFALSE
yes
Evaluation Count:223
yes
Evaluation Count:11192
partially evaluated: ch == QLatin1Char('`')
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:11192
0-11415
162 inQuoteclosingQuote = !inQuotech;
executed: closingQuote = ch;
Execution Count:235
235
163 else if (ch == QLatin1Char('['))
evaluated: ch == QLatin1Char('[')
TRUEFALSE
yes
Evaluation Count:7
yes
Evaluation Count:11185
7-11185
164 closingQuote = QLatin1Char(']');
executed: closingQuote = QLatin1Char(']');
Execution Count:7
7
165 result += ch;
executed (the execution status of this line is deduced): result += ch;
-
166 ++i;
executed (the execution status of this line is deduced): ++i;
-
167 }
executed: }
Execution Count:11427
11427
168 } -
169 } -
170 result.squeeze();
executed (the execution status of this line is deduced): result.squeeze();
-
171 values.resize(holders.size());
executed (the execution status of this line is deduced): values.resize(holders.size());
-
172 return result;
executed: return result;
Execution Count:247
247
173} -
174 -
175/*! -
176 \class QSqlResult -
177 \brief The QSqlResult class provides an abstract interface for -
178 accessing data from specific SQL databases. -
179 -
180 \ingroup database -
181 \inmodule QtSql -
182 -
183 Normally, you would use QSqlQuery instead of QSqlResult, since -
184 QSqlQuery provides a generic wrapper for database-specific -
185 implementations of QSqlResult. -
186 -
187 If you are implementing your own SQL driver (by subclassing -
188 QSqlDriver), you will need to provide your own QSqlResult -
189 subclass that implements all the pure virtual functions and other -
190 virtual functions that you need. -
191 -
192 \sa QSqlDriver -
193*/ -
194 -
195/*! -
196 \enum QSqlResult::BindingSyntax -
197 -
198 This enum type specifies the different syntaxes for specifying -
199 placeholders in prepared queries. -
200 -
201 \value PositionalBinding Use the ODBC-style positional syntax, with "?" as placeholders. -
202 \value NamedBinding Use the Oracle-style syntax with named placeholders (e.g., ":id") -
203 -
204 \sa bindingSyntax() -
205*/ -
206 -
207/*! -
208 \enum QSqlResult::VirtualHookOperation -
209 \internal -
210*/ -
211 -
212/*! -
213 Creates a QSqlResult using database driver \a db. The object is -
214 initialized to an inactive state. -
215 -
216 \sa isActive(), driver() -
217*/ -
218 -
219QSqlResult::QSqlResult(const QSqlDriver *db) -
220{ -
221 d = new QSqlResultPrivate(this); -
222 d->sqldriver = const_cast<QSqlDriver *>(db); -
223 if(db) { -
224 setNumericalPrecisionPolicy(db->numericalPrecisionPolicy()); -
225 } -
226} -
227 -
228/*! -
229 Destroys the object and frees any allocated resources. -
230*/ -
231 -
232QSqlResult::~QSqlResult() -
233{ -
234 delete d; -
235} -
236 -
237/*! -
238 Sets the current query for the result to \a query. You must call -
239 reset() to execute the query on the database. -
240 -
241 \sa reset(), lastQuery() -
242*/ -
243 -
244void QSqlResult::setQuery(const QString& query) -
245{ -
246 d->sql = query; -
247} -
248 -
249/*! -
250 Returns the current SQL query text, or an empty string if there -
251 isn't one. -
252 -
253 \sa setQuery() -
254*/ -
255 -
256QString QSqlResult::lastQuery() const -
257{ -
258 return d->sql; -
259} -
260 -
261/*! -
262 Returns the current (zero-based) row position of the result. May -
263 return the special values QSql::BeforeFirstRow or -
264 QSql::AfterLastRow. -
265 -
266 \sa setAt(), isValid() -
267*/ -
268int QSqlResult::at() const -
269{ -
270 return d->idx; -
271} -
272 -
273 -
274/*! -
275 Returns true if the result is positioned on a valid record (that -
276 is, the result is not positioned before the first or after the -
277 last record); otherwise returns false. -
278 -
279 \sa at() -
280*/ -
281 -
282bool QSqlResult::isValid() const -
283{ -
284 return d->idx != QSql::BeforeFirstRow && d->idx != QSql::AfterLastRow; -
285} -
286 -
287/*! -
288 \fn bool QSqlResult::isNull(int index) -
289 -
290 Returns true if the field at position \a index in the current row -
291 is null; otherwise returns false. -
292*/ -
293 -
294/*! -
295 Returns true if the result has records to be retrieved; otherwise -
296 returns false. -
297*/ -
298 -
299bool QSqlResult::isActive() const -
300{ -
301 return d->active; -
302} -
303 -
304/*! -
305 This function is provided for derived classes to set the -
306 internal (zero-based) row position to \a index. -
307 -
308 \sa at() -
309*/ -
310 -
311void QSqlResult::setAt(int index) -
312{ -
313 d->idx = index; -
314} -
315 -
316 -
317/*! -
318 This function is provided for derived classes to indicate whether -
319 or not the current statement is a SQL \c SELECT statement. The \a -
320 select parameter should be true if the statement is a \c SELECT -
321 statement; otherwise it should be false. -
322 -
323 \sa isSelect() -
324*/ -
325 -
326void QSqlResult::setSelect(bool select) -
327{ -
328 d->isSel = select; -
329} -
330 -
331/*! -
332 Returns true if the current result is from a \c SELECT statement; -
333 otherwise returns false. -
334 -
335 \sa setSelect() -
336*/ -
337 -
338bool QSqlResult::isSelect() const -
339{ -
340 return d->isSel; -
341} -
342 -
343/*! -
344 Returns the driver associated with the result. This is the object -
345 that was passed to the constructor. -
346*/ -
347 -
348const QSqlDriver *QSqlResult::driver() const -
349{ -
350 return d->sqldriver; -
351} -
352 -
353 -
354/*! -
355 This function is provided for derived classes to set the internal -
356 active state to \a active. -
357 -
358 \sa isActive() -
359*/ -
360 -
361void QSqlResult::setActive(bool active) -
362{ -
363 if (active && d->executedQuery.isEmpty()) -
364 d->executedQuery = d->sql; -
365 -
366 d->active = active; -
367} -
368 -
369/*! -
370 This function is provided for derived classes to set the last -
371 error to \a error. -
372 -
373 \sa lastError() -
374*/ -
375 -
376void QSqlResult::setLastError(const QSqlError &error) -
377{ -
378 d->error = error; -
379} -
380 -
381 -
382/*! -
383 Returns the last error associated with the result. -
384*/ -
385 -
386QSqlError QSqlResult::lastError() const -
387{ -
388 return d->error; -
389} -
390 -
391/*! -
392 \fn int QSqlResult::size() -
393 -
394 Returns the size of the \c SELECT result, or -1 if it cannot be -
395 determined or if the query is not a \c SELECT statement. -
396 -
397 \sa numRowsAffected() -
398*/ -
399 -
400/*! -
401 \fn int QSqlResult::numRowsAffected() -
402 -
403 Returns the number of rows affected by the last query executed, or -
404 -1 if it cannot be determined or if the query is a \c SELECT -
405 statement. -
406 -
407 \sa size() -
408*/ -
409 -
410/*! -
411 \fn QVariant QSqlResult::data(int index) -
412 -
413 Returns the data for field \a index in the current row as -
414 a QVariant. This function is only called if the result is in -
415 an active state and is positioned on a valid record and \a index is -
416 non-negative. Derived classes must reimplement this function and -
417 return the value of field \a index, or QVariant() if it cannot be -
418 determined. -
419*/ -
420 -
421/*! -
422 \fn bool QSqlResult::reset(const QString &query) -
423 -
424 Sets the result to use the SQL statement \a query for subsequent -
425 data retrieval. -
426 -
427 Derived classes must reimplement this function and apply the \a -
428 query to the database. This function is only called after the -
429 result is set to an inactive state and is positioned before the -
430 first record of the new result. Derived classes should return -
431 true if the query was successful and ready to be used, or false -
432 otherwise. -
433 -
434 \sa setQuery() -
435*/ -
436 -
437/*! -
438 \fn bool QSqlResult::fetch(int index) -
439 -
440 Positions the result to an arbitrary (zero-based) row \a index. -
441 -
442 This function is only called if the result is in an active state. -
443 Derived classes must reimplement this function and position the -
444 result to the row \a index, and call setAt() with an appropriate -
445 value. Return true to indicate success, or false to signify -
446 failure. -
447 -
448 \sa isActive(), fetchFirst(), fetchLast(), fetchNext(), fetchPrevious() -
449*/ -
450 -
451/*! -
452 \fn bool QSqlResult::fetchFirst() -
453 -
454 Positions the result to the first record (row 0) in the result. -
455 -
456 This function is only called if the result is in an active state. -
457 Derived classes must reimplement this function and position the -
458 result to the first record, and call setAt() with an appropriate -
459 value. Return true to indicate success, or false to signify -
460 failure. -
461 -
462 \sa fetch(), fetchLast() -
463*/ -
464 -
465/*! -
466 \fn bool QSqlResult::fetchLast() -
467 -
468 Positions the result to the last record (last row) in the result. -
469 -
470 This function is only called if the result is in an active state. -
471 Derived classes must reimplement this function and position the -
472 result to the last record, and call setAt() with an appropriate -
473 value. Return true to indicate success, or false to signify -
474 failure. -
475 -
476 \sa fetch(), fetchFirst() -
477*/ -
478 -
479/*! -
480 Positions the result to the next available record (row) in the -
481 result. -
482 -
483 This function is only called if the result is in an active -
484 state. The default implementation calls fetch() with the next -
485 index. Derived classes can reimplement this function and position -
486 the result to the next record in some other way, and call setAt() -
487 with an appropriate value. Return true to indicate success, or -
488 false to signify failure. -
489 -
490 \sa fetch(), fetchPrevious() -
491*/ -
492 -
493bool QSqlResult::fetchNext() -
494{ -
495 return fetch(at() + 1); -
496} -
497 -
498/*! -
499 Positions the result to the previous record (row) in the result. -
500 -
501 This function is only called if the result is in an active state. -
502 The default implementation calls fetch() with the previous index. -
503 Derived classes can reimplement this function and position the -
504 result to the next record in some other way, and call setAt() -
505 with an appropriate value. Return true to indicate success, or -
506 false to signify failure. -
507*/ -
508 -
509bool QSqlResult::fetchPrevious() -
510{ -
511 return fetch(at() - 1); -
512} -
513 -
514/*! -
515 Returns true if you can only scroll forward through the result -
516 set; otherwise returns false. -
517 -
518 \sa setForwardOnly() -
519*/ -
520bool QSqlResult::isForwardOnly() const -
521{ -
522 return d->forwardOnly; -
523} -
524 -
525/*! -
526 Sets forward only mode to \a forward. If \a forward is true, only -
527 fetchNext() is allowed for navigating the results. Forward only -
528 mode needs much less memory since results do not have to be -
529 cached. By default, this feature is disabled. -
530 -
531 Setting forward only to false is a suggestion to the database engine, -
532 which has the final say on whether a result set is forward only or -
533 scrollable. isForwardOnly() will always return the correct status of -
534 the result set. -
535 -
536 \note Calling setForwardOnly after execution of the query will result -
537 in unexpected results at best, and crashes at worst. -
538 -
539 \sa isForwardOnly(), fetchNext(), QSqlQuery::setForwardOnly() -
540*/ -
541void QSqlResult::setForwardOnly(bool forward) -
542{ -
543 d->forwardOnly = forward; -
544} -
545 -
546/*!-
Prepares the given \a query, using the underlying database
functionality where possible. Returns true if the query is
prepared successfully; otherwise returns false.
\sa prepare()
*/*!
547 Prepares the given \a query, using the underlying database -
548 functionality where possible. Returns true if the query is -
549 prepared successfully; otherwise returns false. -
550 -
551 Note: This method should have been called "safePrepare()". -
552 -
553 \sa prepare() -
554*/ -
555bool QSqlResult::savePrepare(const QString& query) -
556{ -
557 if (!driver())
partially evaluated: !driver()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:239
0-239
558 return false;
never executed: return false;
0
559 d->clear();
executed (the execution status of this line is deduced): d->clear();
-
560 d->sql = query;
executed (the execution status of this line is deduced): d->sql = query;
-
561 if (!driver()->hasFeature(QSqlDriver::PreparedQueries))
partially evaluated: !driver()->hasFeature(QSqlDriver::PreparedQueries)
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:239
0-239
562 return prepare(query);
never executed: return prepare(query);
0
563 -
564 // parse the query to memorize parameter location -
565 d->executedQuery = d->namedToPositionalBinding(query);
executed (the execution status of this line is deduced): d->executedQuery = d->namedToPositionalBinding(query);
-
566 -
567 if (driver()->hasFeature(QSqlDriver::NamedPlaceholders))
evaluated: driver()->hasFeature(QSqlDriver::NamedPlaceholders)
TRUEFALSE
yes
Evaluation Count:13
yes
Evaluation Count:226
13-226
568 {13
// parse the query to memorize parameter location
d->namedToPositionalBinding();d->executedQuery = d->QSqlResultPrivate::positionalToNamedBinding();
} else {
d->executedQuery = d->namedToPositionalBinding();
}(query);
executed: d->executedQuery = QSqlResultPrivate::positionalToNamedBinding(query);
Execution Count:13
569 -
570 return prepare(d->executedQuery);
executed: return prepare(d->executedQuery);
Execution Count:239
239
571} -
572 -
573/*! -
574 Prepares the given \a query for execution; the query will normally -
575 use placeholders so that it can be executed repeatedly. Returns -
576 true if the query is prepared successfully; otherwise returns false. -
577 -
578 \sa exec() -
579*/ -
580bool QSqlResult::prepare(const QString& query) -
581{ -
582 if (d->holders.isEmpty()) {-
int nsql = query.size();
bool inQuote = false;
int i = 0;
executed (the execution status of this line is deduced): d->sql = query;
583 while (i < n) {5-8
QChar ch = query.at(i);if (ch == QLatin1Char(':') && !inQuote
&& (i == 0 || query.at(i - 1) != QLatin1Char(':'))
&& (i + 1 < n && qIsAlnum(query.at(i + 1)))) {
int pos = i + 2;
while (pos < n && qIsAlnum(query.at(pos)))
++pos;
QString holder(query.mid(i, pos - i));
d->indexes[holder].append(d->holders.size());d->holders.append(QHolder(holder, i));
i = pos;
} elseisEmpty()) {
evaluated: d->holders.isEmpty()
TRUEFALSE
yes
Evaluation Count:8
yes
Evaluation Count:5
584 /if (ch == QLatin1Char('\''))-
inQuote = !inQuote;
++i;
}
}/ parse the query to memorize parameter location
585 d->values.resizenamedToPositionalBinding(d->holders.size());-
}
d->sql =query;);
executed (the execution status of this line is deduced): d->namedToPositionalBinding(query);
586 }
executed: }
Execution Count:8
8
587 return true; // fake prepares should always succeed
executed: return true;
Execution Count:13
13
588} -
589 -
590/*! -
591 Executes the query, returning true if successful; otherwise returns -
592 false. -
593 -
594 \sa prepare() -
595*/ -
596bool QSqlResult::exec() -
597{ -
598 bool ret; -
599 // fake preparation - just replace the placeholders.. -
600 QString query = lastQuery(); -
601 if (d->binds == NamedBinding) { -
602 int i; -
603 QVariant val; -
604 QString holder; -
605 for (i = d->holders.count() - 1; i >= 0; --i) { -
606 holder = d->holders.at(i).holderName; -
607 val = d->values.value(d->indexes.value(holder).value(0,-1)); -
608 QSqlField f(QLatin1String(""), val.type()); -
609 f.setValue(val); -
610 query = query.replace(d->holders.at(i).holderPos, -
611 holder.length(), driver()->formatValue(f)); -
612 } -
613 } else { -
614 QString val; -
615 int i = 0; -
616 int idx = 0; -
617 for (idx = 0; idx < d->values.count(); ++idx) { -
618 i = query.indexOf(QLatin1Char('?'), i); -
619 if (i == -1) -
620 continue; -
621 QVariant var = d->values.value(idx); -
622 QSqlField f(QLatin1String(""), var.type()); -
623 if (var.isNull()) -
624 f.clear(); -
625 else -
626 f.setValue(var); -
627 val = driver()->formatValue(f); -
628 query = query.replace(i, 1, driver()->formatValue(f)); -
629 i += val.length(); -
630 } -
631 } -
632 -
633 // have to retain the original query with placeholders -
634 QString orig = lastQuery(); -
635 ret = reset(query); -
636 d->executedQuery = query; -
637 setQuery(orig); -
638 d->resetBindCount(); -
639 return ret; -
640} -
641 -
642/*! -
643 Binds the value \a val of parameter type \a paramType to position \a index -
644 in the current record (row). -
645 -
646 \sa addBindValue() -
647*/ -
648void QSqlResult::bindValue(int index, const QVariant& val, QSql::ParamType paramType) -
649{ -
650 d->binds = PositionalBinding;
executed (the execution status of this line is deduced): d->binds = PositionalBinding;
-
651 d->indexes[qFieldSerialQSqlResultPrivate::fieldSerial(index)].append(index);
executed (the execution status of this line is deduced): d->indexes[QSqlResultPrivate::fieldSerial(index)].append(index);
-
652 if (d->values.count() <= index)
evaluated: d->values.count() <= index
TRUEFALSE
yes
Evaluation Count:447
yes
Evaluation Count:232985
447-232985
653 d->values.resize(index + 1);
executed: d->values.resize(index + 1);
Execution Count:447
447
654 d->values[index] = val;
executed (the execution status of this line is deduced): d->values[index] = val;
-
655 if (paramType != QSql::In || !d->types.isEmpty())
partially evaluated: paramType != QSql::In
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:233432
partially evaluated: !d->types.isEmpty()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:233432
0-233432
656 d->types[index] = paramType;
never executed: d->types[index] = paramType;
0
657}
executed: }
Execution Count:233432
233432
658 -
659/*! -
660 \overload -
661 -
662 Binds the value \a val of parameter type \a paramType to the \a -
663 placeholder name in the current record (row). -
664 -
665 Values cannot be bound to multiple locations in the query, eg: -
666 \code -
667 INSERT INTO testtable (id, name, samename) VALUES (:id, :name, :name) -
668 \endcode -
669 Binding to name will bind to the first :name, but not the second. -
670 -
671 \note Binding an undefined placeholder will result in undefined behavior. -
672 -
673 \sa QSqlQuery::bindValue() -
674*/ -
675void QSqlResult::bindValue(const QString& placeholder, const QVariant& val, -
676 QSql::ParamType paramType) -
677{ -
678 d->binds = NamedBinding; -
679 // if the index has already been set when doing emulated named -
680 // bindings - don't reset it -
681 QList<int> indexes = d->indexes.value(placeholder); -
682 foreach (int idx, indexes) { -
683 if (d->values.count() <= idx) -
684 d->values.resize(idx + 1); -
685 d->values[idx] = val; -
686 if (paramType != QSql::In || !d->types.isEmpty()) -
687 d->types[idx] = paramType; -
688 } -
689} -
690 -
691/*! -
692 Binds the value \a val of parameter type \a paramType to the next -
693 available position in the current record (row). -
694 -
695 \sa bindValue() -
696*/ -
697void QSqlResult::addBindValue(const QVariant& val, QSql::ParamType paramType) -
698{ -
699 d->binds = PositionalBinding; -
700 bindValue(d->bindCount, val, paramType); -
701 ++d->bindCount; -
702} -
703 -
704/*! -
705 Returns the value bound at position \a index in the current record -
706 (row). -
707 -
708 \sa bindValue(), boundValues() -
709*/ -
710QVariant QSqlResult::boundValue(int index) const -
711{ -
712 return d->values.value(index); -
713} -
714 -
715/*! -
716 \overload -
717 -
718 Returns the value bound by the given \a placeholder name in the -
719 current record (row). -
720 -
721 \sa bindValueType() -
722*/ -
723QVariant QSqlResult::boundValue(const QString& placeholder) const -
724{ -
725 QList<int> indexes = d->indexes.value(placeholder); -
726 return d->values.value(indexes.value(0,-1)); -
727} -
728 -
729/*! -
730 Returns the parameter type for the value bound at position \a index. -
731 -
732 \sa boundValue() -
733*/ -
734QSql::ParamType QSqlResult::bindValueType(int index) const -
735{ -
736 return d->types.value(index, QSql::In); -
737} -
738 -
739/*! -
740 \overload -
741 -
742 Returns the parameter type for the value bound with the given \a -
743 placeholder name. -
744*/ -
745QSql::ParamType QSqlResult::bindValueType(const QString& placeholder) const -
746{ -
747 return d->types.value(d->indexes.value(placeholder).value(0,-1), QSql::In); -
748} -
749 -
750/*! -
751 Returns the number of bound values in the result. -
752 -
753 \sa boundValues() -
754*/ -
755int QSqlResult::boundValueCount() const -
756{ -
757 return d->values.count(); -
758} -
759 -
760/*! -
761 Returns a vector of the result's bound values for the current -
762 record (row). -
763 -
764 \sa boundValueCount() -
765*/ -
766QVector<QVariant>& QSqlResult::boundValues() const -
767{ -
768 return d->values; -
769} -
770 -
771/*! -
772 Returns the binding syntax used by prepared queries. -
773*/ -
774QSqlResult::BindingSyntax QSqlResult::bindingSyntax() const -
775{ -
776 return d->binds; -
777} -
778 -
779/*! -
780 Clears the entire result set and releases any associated -
781 resources. -
782*/ -
783void QSqlResult::clear() -
784{ -
785 d->clear(); -
786} -
787 -
788/*! -
789 Returns the query that was actually executed. This may differ from -
790 the query that was passed, for example if bound values were used -
791 with a prepared query and the underlying database doesn't support -
792 prepared queries. -
793 -
794 \sa exec(), setQuery() -
795*/ -
796QString QSqlResult::executedQuery() const -
797{ -
798 return d->executedQuery; -
799} -
800 -
801void QSqlResult::resetBindCount() -
802{ -
803 d->resetBindCount(); -
804} -
805 -
806/*! -
807 Returns the name of the bound value at position \a index in the -
808 current record (row). -
809 -
810 \sa boundValue() -
811*/ -
812QString QSqlResult::boundValueName(int index) const -
813{ -
814 return d->holderAt(index); -
815} -
816 -
817/*! -
818 Returns true if at least one of the query's bound values is a \c -
819 QSql::Out or a QSql::InOut; otherwise returns false. -
820 -
821 \sa bindValueType() -
822*/ -
823bool QSqlResult::hasOutValues() const -
824{ -
825 if (d->types.isEmpty()) -
826 return false; -
827 QHash<int, QSql::ParamType>::ConstIterator it; -
828 for (it = d->types.constBegin(); it != d->types.constEnd(); ++it) { -
829 if (it.value() != QSql::In) -
830 return true; -
831 } -
832 return false; -
833} -
834 -
835/*! -
836 Returns the current record if the query is active; otherwise -
837 returns an empty QSqlRecord. -
838 -
839 The default implementation always returns an empty QSqlRecord. -
840 -
841 \sa isActive() -
842*/ -
843QSqlRecord QSqlResult::record() const -
844{ -
845 return QSqlRecord(); -
846} -
847 -
848/*! -
849 Returns the object ID of the most recent inserted row if the -
850 database supports it. -
851 An invalid QVariant will be returned if the query did not -
852 insert any value or if the database does not report the id back. -
853 If more than one row was touched by the insert, the behavior is -
854 undefined. -
855 -
856 Note that for Oracle databases the row's ROWID will be returned, -
857 while for MySQL databases the row's auto-increment field will -
858 be returned. -
859 -
860 \sa QSqlDriver::hasFeature() -
861*/ -
862QVariant QSqlResult::lastInsertId() const -
863{ -
864 return QVariant(); -
865} -
866 -
867/*! \internal -
868*/ -
869void QSqlResult::virtual_hook(int, void *) -
870{ -
871} -
872 -
873/*! \internal -
874 \since 4.2 -
875 -
876 Executes a prepared query in batch mode if the driver supports it, -
877 otherwise emulates a batch execution using bindValue() and exec(). -
878 QSqlDriver::hasFeature() can be used to find out whether a driver -
879 supports batch execution. -
880 -
881 Batch execution can be faster for large amounts of data since it -
882 reduces network roundtrips. -
883 -
884 For batch executions, bound values have to be provided as lists -
885 of variants (QVariantList). -
886 -
887 Each list must contain values of the same type. All lists must -
888 contain equal amount of values (rows). -
889 -
890 NULL values are passed in as typed QVariants, for example -
891 \c {QVariant(QVariant::Int)} for an integer NULL value. -
892 -
893 Example: -
894 -
895 \snippet code/src_sql_kernel_qsqlresult.cpp 0 -
896 -
897 Here, we insert two rows into a SQL table, with each row containing three values. -
898 -
899 \sa exec(), QSqlDriver::hasFeature() -
900*/ -
901bool QSqlResult::execBatch(bool arrayBind) -
902{ -
903 Q_UNUSED(arrayBind); -
904 -
905 QVector<QVariant> values = d->values; -
906 if (values.count() == 0) -
907 return false; -
908 for (int i = 0; i < values.at(0).toList().count(); ++i) { -
909 for (int j = 0; j < values.count(); ++j) -
910 bindValue(j, values.at(j).toList().at(i), QSql::In); -
911 if (!exec()) -
912 return false; -
913 } -
914 return true; -
915} -
916 -
917/*! \internal -
918 */ -
919void QSqlResult::detachFromResultSet() -
920{ -
921} -
922 -
923/*! \internal -
924 */ -
925void QSqlResult::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy) -
926{ -
927 d->precisionPolicy = policy; -
928} -
929 -
930/*! \internal -
931 */ -
932QSql::NumericalPrecisionPolicy QSqlResult::numericalPrecisionPolicy() const -
933{ -
934 return d->precisionPolicy; -
935} -
936 -
937/*! \internal -
938*/ -
939bool QSqlResult::nextResult() -
940{ -
941 return false; -
942} -
943 -
944/*! -
945 Returns the low-level database handle for this result set -
946 wrapped in a QVariant or an invalid QVariant if there is no handle. -
947 -
948 \warning Use this with uttermost care and only if you know what you're doing. -
949 -
950 \warning The handle returned here can become a stale pointer if the result -
951 is modified (for example, if you clear it). -
952 -
953 \warning The handle can be NULL if the result was not executed yet. -
954 -
955 The handle returned here is database-dependent, you should query the type -
956 name of the variant before accessing it. -
957 -
958 This example retrieves the handle for a sqlite result: -
959 -
960 \snippet code/src_sql_kernel_qsqlresult.cpp 1 -
961 -
962 This snippet returns the handle for PostgreSQL or MySQL: -
963 -
964 \snippet code/src_sql_kernel_qsqlresult.cpp 2 -
965 -
966 \sa QSqlDriver::handle() -
967*/ -
968QVariant QSqlResult::handle() const -
969{ -
970 return QVariant(); -
971} -
972 -
973QT_END_NAMESPACE -
974 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial