1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the sql module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
32
#include "qsqlerror.h"
33
#include "qsqlfield.h"
34
#include "qsqlrecord.h"
35
#include "qsqlresult.h"
37
#include "qsqldriver.h"
40
Holder(const QString& hldr = QString(), int index = -1): holderName(hldr), holderPos(index) {}
41
bool operator==(const Holder& h) const { return h.holderPos == holderPos && h.holderName == holderName; }
42
bool operator!=(const Holder& h) const { return h.holderPos != holderPos || h.holderName != holderName; }
47
class QSqlResultPrivate
50
QSqlResultPrivate(QSqlResult* d)
51
: q(d), sqldriver(0), idx(QSql::BeforeFirstRow), active(false),
52
isSel(false), forwardOnly(false), bindCount(0), binds(QSqlResult::PositionalBinding)
79
QString positionalToNamedBinding();
80
QString namedToPositionalBinding();
81
QString holderAt(int index) const;
85
const QSqlDriver* sqldriver;
94
QSqlResult::BindingSyntax binds;
96
QString executedQuery;
97
QMap<int, QSql::ParamType> types;
98
QVector<QVariant> values;
99
typedef QMap<QString, int> IndexMap;
102
typedef QVector<Holder> HolderVector;
103
HolderVector holders;
106
QString QSqlResultPrivate::holderAt(int index) const
108
return indexes.key(index);
111
QString QSqlResultPrivate::positionalToNamedBinding()
113
QRegExp rx(QLatin1String("'[^']*'|\\?"));
116
while ((i = rx.indexIn(q, i)) != -1) {
117
if (rx.cap(0) == QLatin1String("?"))
118
q = q.replace(i, 1, QLatin1String(":f") + QString::number(++cnt));
119
i += rx.matchedLength();
124
QString QSqlResultPrivate::namedToPositionalBinding()
126
QRegExp rx(QLatin1String("'[^']*'|:([a-zA-Z0-9_]+)"));
129
while ((i = rx.indexIn(q, i)) != -1) {
130
if (rx.cap(1).isEmpty()) {
131
i += rx.matchedLength();
133
// record the index of the placeholder - needed
134
// for emulating named bindings with ODBC
135
indexes[rx.cap(0)]= ++cnt;
136
q.replace(i, rx.matchedLength(), QLatin1String("?"));
145
\brief The QSqlResult class provides an abstract interface for
146
accessing data from specific SQL databases.
151
Normally, you would use QSqlQuery instead of QSqlResult, since
152
QSqlQuery provides a generic wrapper for database-specific
153
implementations of QSqlResult.
155
If you are implementing your own SQL driver (by subclassing
156
QSqlDriver), you will need to provide your own QSqlResult
157
subclass that implements all the pure virtual functions and other
158
virtual functions that you need.
164
\enum QSqlResult::BindingSyntax
166
This enum type specifies the different syntaxes for specifying
167
placeholders in prepared queries.
169
\value PositionalBinding Use the ODBC-style positional syntax, with "?" as placeholders.
170
\value NamedBinding Use the Oracle-style syntax with named placeholders (e.g., ":id")
171
\omitvalue BindByPosition
172
\omitvalue BindByName
178
Creates a QSqlResult using database driver \a db. The object is
179
initialized to an inactive state.
181
\sa isActive(), driver()
184
QSqlResult::QSqlResult(const QSqlDriver *db)
186
d = new QSqlResultPrivate(this);
191
Destroys the object and frees any allocated resources.
194
QSqlResult::~QSqlResult()
200
Sets the current query for the result to \a query. You must call
201
reset() to execute the query on the database.
203
\sa reset(), lastQuery()
206
void QSqlResult::setQuery(const QString& query)
212
Returns the current SQL query text, or an empty string if there
218
QString QSqlResult::lastQuery() const
224
Returns the current (zero-based) row position of the result. May
225
return the special values QSql::BeforeFirstRow or
228
\sa setAt(), isValid()
230
int QSqlResult::at() const
237
Returns true if the result is positioned on a valid record (that
238
is, the result is not positioned before the first or after the
239
last record); otherwise returns false.
244
bool QSqlResult::isValid() const
246
return d->idx != QSql::BeforeFirstRow && d->idx != QSql::AfterLastRow;
250
\fn bool QSqlResult::isNull(int index)
252
Returns true if the field at position \a index in the current row
253
is null; otherwise returns false.
257
Returns true if the result has records to be retrieved; otherwise
261
bool QSqlResult::isActive() const
267
This function is provided for derived classes to set the
268
internal (zero-based) row position to \a index.
273
void QSqlResult::setAt(int index)
280
This function is provided for derived classes to indicate whether
281
or not the current statement is a SQL \c SELECT statement. The \a
282
select parameter should be true if the statement is a \c SELECT
283
statement; otherwise it should be false.
288
void QSqlResult::setSelect(bool select)
294
Returns true if the current result is from a \c SELECT statement;
295
otherwise returns false.
300
bool QSqlResult::isSelect() const
306
Returns the driver associated with the result. This is the object
307
that was passed to the constructor.
310
const QSqlDriver *QSqlResult::driver() const
317
This function is provided for derived classes to set the internal
318
active state to \a active.
323
void QSqlResult::setActive(bool active)
329
This function is provided for derived classes to set the last
335
void QSqlResult::setLastError(const QSqlError &error)
342
Returns the last error associated with the result.
345
QSqlError QSqlResult::lastError() const
351
\fn int QSqlResult::size()
353
Returns the size of the \c SELECT result, or -1 if it cannot be
354
determined or if the query is not a \c SELECT statement.
356
\sa numRowsAffected()
360
\fn int QSqlResult::numRowsAffected()
362
Returns the number of rows affected by the last query executed, or
363
-1 if it cannot be determined or if the query is a \c SELECT
370
\fn QVariant QSqlResult::data(int index)
372
Returns the data for field \a index in the current row as
373
a QVariant. This function is only called if the result is in
374
an active state and is positioned on a valid record and \a index is
375
non-negative. Derived classes must reimplement this function and
376
return the value of field \a index, or QVariant() if it cannot be
381
\fn bool QSqlResult::reset(const QString &query)
383
Sets the result to use the SQL statement \a query for subsequent
386
Derived classes must reimplement this function and apply the \a
387
query to the database. This function is only called after the
388
result is set to an inactive state and is positioned before the
389
first record of the new result. Derived classes should return
390
true if the query was successful and ready to be used, or false
397
\fn bool QSqlResult::fetch(int index)
399
Positions the result to an arbitrary (zero-based) row \a index.
401
This function is only called if the result is in an active state.
402
Derived classes must reimplement this function and position the
403
result to the row \a index, and call setAt() with an appropriate
404
value. Return true to indicate success, or false to signify
407
\sa isActive(), fetchFirst(), fetchLast(), fetchNext(), fetchPrevious()
411
\fn bool QSqlResult::fetchFirst()
413
Positions the result to the first record (row 0) in the result.
415
This function is only called if the result is in an active state.
416
Derived classes must reimplement this function and position the
417
result to the first record, and call setAt() with an appropriate
418
value. Return true to indicate success, or false to signify
421
\sa fetch(), fetchLast()
425
\fn bool QSqlResult::fetchLast()
427
Positions the result to the last record (last row) in the result.
429
This function is only called if the result is in an active state.
430
Derived classes must reimplement this function and position the
431
result to the last record, and call setAt() with an appropriate
432
value. Return true to indicate success, or false to signify
435
\sa fetch(), fetchFirst()
439
Positions the result to the next available record (row) in the
442
This function is only called if the result is in an active
443
state. The default implementation calls fetch() with the next
444
index. Derived classes can reimplement this function and position
445
the result to the next record in some other way, and call setAt()
446
with an appropriate value. Return true to indicate success, or
447
false to signify failure.
449
\sa fetch(), fetchPrevious()
452
bool QSqlResult::fetchNext()
454
return fetch(at() + 1);
458
Positions the result to the previous record (row) in the result.
460
This function is only called if the result is in an active state.
461
The default implementation calls fetch() with the previous index.
462
Derived classes can reimplement this function and position the
463
result to the next record in some other way, and call setAt()
464
with an appropriate value. Return true to indicate success, or
465
false to signify failure.
468
bool QSqlResult::fetchPrevious()
470
return fetch(at() - 1);
474
Returns true if you can only scroll forward through the result
475
set; otherwise returns false.
479
bool QSqlResult::isForwardOnly() const
481
return d->forwardOnly;
485
Sets forward only mode to \a forward. If \a forward is true, only
486
fetchNext() is allowed for navigating the results. Forward only
487
mode needs much less memory since results do not have to be
488
cached. By default, this feature is disabled.
490
\sa isForwardOnly(), fetchNext()
492
void QSqlResult::setForwardOnly(bool forward)
494
d->forwardOnly = forward;
498
Prepares the given \a query, using the underlying database
499
functionality where possible.
503
bool QSqlResult::savePrepare(const QString& query)
509
if (!driver()->hasFeature(QSqlDriver::PreparedQueries))
510
return prepare(query);
512
if (driver()->hasFeature(QSqlDriver::NamedPlaceholders)) {
513
// parse the query to memorize parameter location
514
d->namedToPositionalBinding();
515
d->executedQuery = d->positionalToNamedBinding();
517
d->executedQuery = d->namedToPositionalBinding();
519
return prepare(d->executedQuery);
523
Prepares the given \a query for execution; the query will normally
524
use placeholders so that it can be executed repeatedly.
528
bool QSqlResult::prepare(const QString& query)
530
QRegExp rx(QLatin1String("'[^']*'|:([a-zA-Z0-9_]+)"));
532
while ((i = rx.indexIn(query, i)) != -1) {
533
if (!rx.cap(1).isEmpty())
534
d->holders.append(Holder(rx.cap(0), i));
535
i += rx.matchedLength();
538
return true; // fake prepares should always succeed
546
bool QSqlResult::exec()
549
// fake preparation - just replace the placeholders..
550
QString query = lastQuery();
551
if (d->binds == NamedBinding) {
555
for (i = d->holders.count() - 1; i >= 0; --i) {
556
holder = d->holders[i].holderName;
557
val = d->values[d->indexes[holder]];
558
QSqlField f(QLatin1String(""), val.type());
560
query = query.replace(d->holders[i].holderPos,
561
holder.length(), driver()->formatValue(f));
567
for (idx = 0; idx < d->values.count(); ++idx) {
568
i = query.indexOf(QLatin1Char('?'), i);
571
QVariant var = d->values[idx];
572
QSqlField f(QLatin1String(""), var.type());
577
val = driver()->formatValue(f);
578
query = query.replace(i, 1, driver()->formatValue(f));
583
// have to retain the original query with placeholders
584
QString orig = lastQuery();
586
d->executedQuery = query;
593
Binds the value \a val of parameter type \a paramType to position \a index
594
in the current record (row).
598
void QSqlResult::bindValue(int index, const QVariant& val, QSql::ParamType paramType)
600
d->binds = PositionalBinding;
601
QString nm(QLatin1String(":f") + QString::number(index));
602
d->indexes[nm] = index;
603
if (d->values.count() <= index)
604
d->values.resize(index + 1);
605
d->values[index] = val;
606
if (paramType != QSql::In || !d->types.isEmpty())
607
d->types[index] = paramType;
613
Binds the value \a val of parameter type \a paramType to the \a
614
placeholder name in the current record (row).
616
void QSqlResult::bindValue(const QString& placeholder, const QVariant& val,
617
QSql::ParamType paramType)
619
d->binds = NamedBinding;
620
// if the index has already been set when doing emulated named
621
// bindings - don't reset it
622
int idx = d->indexes.value(placeholder, -1);
624
if (d->values.count() <= idx)
625
d->values.resize(idx + 1);
626
d->values[idx] = val;
628
d->values.append(val);
629
idx = d->values.count() - 1;
630
d->indexes[placeholder] = idx;
633
if (paramType != QSql::In || !d->types.isEmpty())
634
d->types[idx] = paramType;
638
Binds the value \a val of parameter type \a paramType to the next
639
available position in the current record (row).
643
void QSqlResult::addBindValue(const QVariant& val, QSql::ParamType paramType)
645
d->binds = PositionalBinding;
646
bindValue(d->bindCount, val, paramType);
651
Returns the value bound at position \a index in the current record
654
\sa bindValue(), boundValues()
656
QVariant QSqlResult::boundValue(int index) const
658
return d->values.value(index);
664
Returns the value bound by the given \a placeholder name in the
665
current record (row).
669
QVariant QSqlResult::boundValue(const QString& placeholder) const
671
int idx = d->indexes.value(placeholder, -1);
672
return d->values.value(idx);
676
Returns the parameter type for the value bound at position \a index.
680
QSql::ParamType QSqlResult::bindValueType(int index) const
682
return d->types.value(index, QSql::In);
688
Returns the parameter type for the value bound with the given \a
691
QSql::ParamType QSqlResult::bindValueType(const QString& placeholder) const
693
return d->types.value(d->indexes.value(placeholder, -1), QSql::In);
697
Returns the number of bound values in the result.
701
int QSqlResult::boundValueCount() const
703
return d->values.count();
707
Returns a vector of the result's bound values for the current
710
\sa boundValueCount()
712
QVector<QVariant>& QSqlResult::boundValues() const
718
Returns the binding syntax used by prepared queries.
720
QSqlResult::BindingSyntax QSqlResult::bindingSyntax() const
726
Clears the entire result set and releases any associated
729
void QSqlResult::clear()
735
Returns the query that was actually executed. This may differ from
736
the query that was passed, for example if bound values were used
737
with a prepared query and the underlying database doesn't support
740
\sa exec(), setQuery()
742
QString QSqlResult::executedQuery() const
744
return d->executedQuery;
747
void QSqlResult::resetBindCount()
753
Returns the name of the bound value at position \a index in the
754
current record (row).
758
QString QSqlResult::boundValueName(int index) const
760
return d->holderAt(index);
764
Returns true if at least one of the query's bound values is a \c
765
QSql::Out or a \c QSql::InOut; otherwise returns false.
769
bool QSqlResult::hasOutValues() const
771
if (d->types.isEmpty())
773
QMap<int, QSql::ParamType>::ConstIterator it;
774
for (it = d->types.constBegin(); it != d->types.constEnd(); ++it) {
775
if (it.value() != QSql::In)
782
Returns the current record if the query is active; otherwise
783
returns an empty QSqlRecord.
785
The default implementation always returns an empty QSqlRecord.
789
QSqlRecord QSqlResult::record() const
795
Returns the object ID of the most recent inserted row if the
796
database supports it.
797
An invalid QVariant will be returned if the query did not
798
insert any value or if the database does not report the id back.
799
If more than one row was touched by the insert, the behavior is
802
\sa QSqlDriver::hasFeature()
804
QVariant QSqlResult::lastInsertId() const
811
void QSqlResult::virtual_hook(int, void *)
817
Returns the low-level database handle for this result set
818
wrapped in a QVariant or an invalid QVariant if there is no handle.
820
\warning Use this with uttermost care and only if you know what you're doing.
822
\warning The handle returned here can become a stale pointer if the result
823
is modified (for example, if you clear it).
825
\warning The handle can be NULL if the result was not executed yet.
827
The handle returned here is database-dependent, you should query the type
828
name of the variant before accessing it.
830
This example retrieves the handle for a sqlite result:
833
QSqlQuery query = ...
834
QVariant v = query.result()->handle();
835
if (v.isValid() && v.typeName() == "sqlite3_stmt*") {
836
// v.data() returns a pointer to the handle
837
sqlite3_stmt *handle = *static_cast<sqlite3_stmt **>(v.data());
838
if (handle != 0) { // check that it is not NULL
844
This snippet returns the handle for PostgreSQL or MySQL:
847
if (v.typeName() == "PGresult*") {
848
PGresult *handle = *static_cast<PGresult **>(v.data());
852
if (v.typeName() == "MYSQL_STMT*") {
853
MYSQL_STMT *handle = *static_cast<MYSQL_STMT **>(v.data());
858
\sa QSqlDriver::handle()
860
QVariant QSqlResult::handle() const