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