Qt 4.8
qsqlquery.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 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 "qsqlquery.h"
43 
44 //#define QT_DEBUG_SQL
45 
46 #include "qatomic.h"
47 #include "qsqlrecord.h"
48 #include "qsqlresult.h"
49 #include "qsqldriver.h"
50 #include "qsqldatabase.h"
51 #include "private/qsqlnulldriver_p.h"
52 #include "qvector.h"
53 #include "qmap.h"
54 
56 
58 {
59 public:
64 
65  static QSqlQueryPrivate* shared_null();
66 };
67 
68 Q_GLOBAL_STATIC_WITH_ARGS(QSqlQueryPrivate, nullQueryPrivate, (0))
70 Q_GLOBAL_STATIC_WITH_ARGS(QSqlNullResult, nullResult, (nullDriver()))
71 
73 {
74  QSqlQueryPrivate *null = nullQueryPrivate();
75  null->ref.ref();
76  return null;
77 }
78 
83  : ref(1), sqlResult(result)
84 {
85  if (!sqlResult)
86  sqlResult = nullResult();
87 }
88 
90 {
91  QSqlResult *nr = nullResult();
92  if (!nr || sqlResult == nr)
93  return;
94  delete sqlResult;
95 }
96 
237 {
238  d = new QSqlQueryPrivate(result);
239 }
240 
246 {
247  if (!d->ref.deref())
248  delete d;
249 }
250 
256 {
257  d = other.d;
258  d->ref.ref();
259 }
260 
264 static void qInit(QSqlQuery *q, const QString& query, QSqlDatabase db)
265 {
266  QSqlDatabase database = db;
267  if (!database.isValid())
269  if (database.isValid()) {
270  *q = QSqlQuery(database.driver()->createResult());
271  }
272  if (!query.isEmpty())
273  q->exec(query);
274 }
275 
285 {
287  qInit(this, query, db);
288 }
289 
298 {
300  qInit(this, QString(), db);
301 }
302 
303 
309 {
310  qAtomicAssign(d, other.d);
311  return *this;
312 }
313 
323 bool QSqlQuery::isNull(int field) const
324 {
325  if (d->sqlResult->isActive() && d->sqlResult->isValid())
326  return d->sqlResult->isNull(field);
327  return true;
328 }
329 
355 bool QSqlQuery::exec(const QString& query)
356 {
357  if (d->ref != 1) {
358  bool fo = isForwardOnly();
359  *this = QSqlQuery(driver()->createResult());
360  d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
361  setForwardOnly(fo);
362  } else {
363  d->sqlResult->clear();
364  d->sqlResult->setActive(false);
365  d->sqlResult->setLastError(QSqlError());
366  d->sqlResult->setAt(QSql::BeforeFirstRow);
367  d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
368  }
369  d->sqlResult->setQuery(query.trimmed());
370  if (!driver()->isOpen() || driver()->isOpenError()) {
371  qWarning("QSqlQuery::exec: database not open");
372  return false;
373  }
374  if (query.isEmpty()) {
375  qWarning("QSqlQuery::exec: empty query");
376  return false;
377  }
378 #ifdef QT_DEBUG_SQL
379  qDebug("\n QSqlQuery: %s", query.toLocal8Bit().constData());
380 #endif
381  return d->sqlResult->reset(query);
382 }
383 
404 {
405  if (isActive() && isValid() && (index > QSql::BeforeFirstRow))
406  return d->sqlResult->data(index);
407  qWarning("QSqlQuery::value: not positioned on a valid record");
408  return QVariant();
409 }
410 
420 int QSqlQuery::at() const
421 {
422  return d->sqlResult->at();
423 }
424 
433 {
434  return d->sqlResult->lastQuery();
435 }
436 
442 {
443  return d->sqlResult->driver();
444 }
445 
451 {
452  return d->sqlResult;
453 }
454 
502 bool QSqlQuery::seek(int index, bool relative)
503 {
504  if (!isSelect() || !isActive())
505  return false;
506  int actualIdx;
507  if (!relative) { // arbitrary seek
508  if (index < 0) {
509  d->sqlResult->setAt(QSql::BeforeFirstRow);
510  return false;
511  }
512  actualIdx = index;
513  } else {
514  switch (at()) { // relative seek
516  if (index > 0)
517  actualIdx = index;
518  else {
519  return false;
520  }
521  break;
522  case QSql::AfterLastRow:
523  if (index < 0) {
524  d->sqlResult->fetchLast();
525  actualIdx = at() + index;
526  } else {
527  return false;
528  }
529  break;
530  default:
531  if ((at() + index) < 0) {
532  d->sqlResult->setAt(QSql::BeforeFirstRow);
533  return false;
534  }
535  actualIdx = at() + index;
536  break;
537  }
538  }
539  // let drivers optimize
540  if (isForwardOnly() && actualIdx < at()) {
541  qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query");
542  return false;
543  }
544  if (actualIdx == (at() + 1) && at() != QSql::BeforeFirstRow) {
545  if (!d->sqlResult->fetchNext()) {
546  d->sqlResult->setAt(QSql::AfterLastRow);
547  return false;
548  }
549  return true;
550  }
551  if (actualIdx == (at() - 1)) {
552  if (!d->sqlResult->fetchPrevious()) {
553  d->sqlResult->setAt(QSql::BeforeFirstRow);
554  return false;
555  }
556  return true;
557  }
558  if (!d->sqlResult->fetch(actualIdx)) {
559  d->sqlResult->setAt(QSql::AfterLastRow);
560  return false;
561  }
562  return true;
563 }
564 
595 {
596  if (!isSelect() || !isActive())
597  return false;
598  bool b = false;
599  switch (at()) {
601  b = d->sqlResult->fetchFirst();
602  return b;
603  case QSql::AfterLastRow:
604  return false;
605  default:
606  if (!d->sqlResult->fetchNext()) {
607  d->sqlResult->setAt(QSql::AfterLastRow);
608  return false;
609  }
610  return true;
611  }
612 }
613 
644 {
645  if (!isSelect() || !isActive())
646  return false;
647  if (isForwardOnly()) {
648  qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query");
649  return false;
650  }
651 
652  bool b = false;
653  switch (at()) {
655  return false;
656  case QSql::AfterLastRow:
657  b = d->sqlResult->fetchLast();
658  return b;
659  default:
660  if (!d->sqlResult->fetchPrevious()) {
661  d->sqlResult->setAt(QSql::BeforeFirstRow);
662  return false;
663  }
664  return true;
665  }
666 }
667 
679 {
680  if (!isSelect() || !isActive())
681  return false;
682  if (isForwardOnly() && at() > QSql::BeforeFirstRow) {
683  qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query");
684  return false;
685  }
686  bool b = false;
687  b = d->sqlResult->fetchFirst();
688  return b;
689 }
690 
704 {
705  if (!isSelect() || !isActive())
706  return false;
707  bool b = false;
708  b = d->sqlResult->fetchLast();
709  return b;
710 }
711 
724 int QSqlQuery::size() const
725 {
726  if (isActive() && d->sqlResult->driver()->hasFeature(QSqlDriver::QuerySize))
727  return d->sqlResult->size();
728  return -1;
729 }
730 
741 {
742  if (isActive())
743  return d->sqlResult->numRowsAffected();
744  return -1;
745 }
746 
755 {
756  return d->sqlResult->lastError();
757 }
758 
764 bool QSqlQuery::isValid() const
765 {
766  return d->sqlResult->isValid();
767 }
768 
786 {
787  return d->sqlResult->isActive();
788 }
789 
796 {
797  return d->sqlResult->isSelect();
798 }
799 
807 {
808  return d->sqlResult->isForwardOnly();
809 }
810 
835 void QSqlQuery::setForwardOnly(bool forward)
836 {
837  d->sqlResult->setForwardOnly(forward);
838 }
839 
859 {
860  QSqlRecord rec = d->sqlResult->record();
861 
862  if (isValid()) {
863  for (int i = 0; i < rec.count(); ++i)
864  rec.setValue(i, value(i));
865  }
866  return rec;
867 }
868 
875 {
876  *this = QSqlQuery(driver()->createResult());
877 }
878 
903 bool QSqlQuery::prepare(const QString& query)
904 {
905  if (d->ref != 1) {
906  bool fo = isForwardOnly();
907  *this = QSqlQuery(driver()->createResult());
908  setForwardOnly(fo);
909  d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
910  } else {
911  d->sqlResult->setActive(false);
912  d->sqlResult->setLastError(QSqlError());
913  d->sqlResult->setAt(QSql::BeforeFirstRow);
914  d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
915  }
916  if (!driver()) {
917  qWarning("QSqlQuery::prepare: no driver");
918  return false;
919  }
920  if (!driver()->isOpen() || driver()->isOpenError()) {
921  qWarning("QSqlQuery::prepare: database not open");
922  return false;
923  }
924  if (query.isEmpty()) {
925  qWarning("QSqlQuery::prepare: empty query");
926  return false;
927  }
928 #ifdef QT_DEBUG_SQL
929  qDebug("\n QSqlQuery::prepare: %s", query.toLocal8Bit().constData());
930 #endif
931  return d->sqlResult->savePrepare(query);
932 }
933 
944 {
945  d->sqlResult->resetBindCount();
946 
947  if (d->sqlResult->lastError().isValid())
948  d->sqlResult->setLastError(QSqlError());
949 
950  return d->sqlResult->exec();
951 }
952 
1006 {
1007  return d->sqlResult->execBatch(mode == ValuesAsColumns);
1008 }
1009 
1030 void QSqlQuery::bindValue(const QString& placeholder, const QVariant& val,
1031  QSql::ParamType paramType
1032 )
1033 {
1034  d->sqlResult->bindValue(placeholder, val, paramType);
1035 }
1036 
1043 void QSqlQuery::bindValue(int pos, const QVariant& val, QSql::ParamType paramType)
1044 {
1045  d->sqlResult->bindValue(pos, val, paramType);
1046 }
1047 
1060 void QSqlQuery::addBindValue(const QVariant& val, QSql::ParamType paramType)
1061 {
1062  d->sqlResult->addBindValue(val, paramType);
1063 }
1064 
1070 QVariant QSqlQuery::boundValue(const QString& placeholder) const
1071 {
1072  return d->sqlResult->boundValue(placeholder);
1073 }
1074 
1079 {
1080  return d->sqlResult->boundValue(pos);
1081 }
1082 
1098 {
1100 
1101  const QVector<QVariant> values(d->sqlResult->boundValues());
1102  for (int i = 0; i < values.count(); ++i)
1103  map[d->sqlResult->boundValueName(i)] = values.at(i);
1104  return map;
1105 }
1106 
1120 {
1121  return d->sqlResult->executedQuery();
1122 }
1123 
1149 {
1150  return d->sqlResult->lastInsertId();
1151 }
1152 
1175 {
1176  d->sqlResult->setNumericalPrecisionPolicy(precisionPolicy);
1177 }
1178 
1185 {
1186  return d->sqlResult->numericalPrecisionPolicy();
1187 }
1188 
1206 {
1207  if (isActive()) {
1208  d->sqlResult->setLastError(QSqlError());
1209  d->sqlResult->setAt(QSql::BeforeFirstRow);
1210  d->sqlResult->detachFromResultSet();
1211  d->sqlResult->setActive(false);
1212  }
1213 }
1214 
1249 {
1250  if (isActive())
1251  return d->sqlResult->nextResult();
1252  return false;
1253 }
1254 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
The QSqlError class provides SQL database error information.
Definition: qsqlerror.h:53
double d
Definition: qnumeric_p.h:62
const QSqlDriver * driver() const
Returns the database driver associated with the query.
Definition: qsqlquery.cpp:441
NumericalPrecisionPolicy
Definition: qsql.h:82
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
bool first()
Retrieves the first record in the result, if available, and positions the query on the retrieved reco...
Definition: qsqlquery.cpp:678
bool prepare(const QString &query)
Prepares the SQL query query for execution.
Definition: qsqlquery.cpp:903
int numRowsAffected() const
Returns the number of rows affected by the result&#39;s SQL statement, or -1 if it cannot be determined...
Definition: qsqlquery.cpp:740
The QAtomicInt class provides platform-independent atomic operations on integers. ...
Definition: qatomic.h:55
~QSqlQuery()
Destroys the object and frees any allocated resources.
Definition: qsqlquery.cpp:245
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const
Returns the current precision policy.
Definition: qsqlquery.cpp:1184
#define at(className, varName)
QSqlRecord record() const
Returns a QSqlRecord containing the field information for the current query.
Definition: qsqlquery.cpp:858
void finish()
Instruct the database driver that no more data will be fetched from this query until it is re-execute...
Definition: qsqlquery.cpp:1205
bool isValid() const
Returns true if the QSqlDatabase has a valid driver.
The QSqlQuery class provides a means of executing and manipulating SQL statements.
Definition: qsqlquery.h:63
bool previous()
Retrieves the previous record in the result, if available, and positions the query on the retrieved r...
Definition: qsqlquery.cpp:643
QSqlQuery(QSqlResult *r)
Constructs a QSqlQuery object which uses the QSqlResult result to communicate with a database...
Definition: qsqlquery.cpp:236
The QSqlDatabase class represents a connection to a database.
Definition: qsqldatabase.h:78
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
The QSqlRecord class encapsulates a database record.
Definition: qsqlrecord.h:58
bool ref()
Atomically increments the value of this QAtomicInt.
The QSqlDriver class is an abstract base class for accessing specific SQL databases.
Definition: qsqldriver.h:68
The QString class provides a Unicode character string.
Definition: qstring.h:83
Q_GLOBAL_STATIC_WITH_ARGS(QSqlNullResult, nullResult,(nullDriver())) QSqlQueryPrivate *QSqlQueryPrivate
Definition: qsqlquery.cpp:70
bool isActive() const
Returns true if the query is active.
Definition: qsqlquery.cpp:785
const QSqlResult * result() const
Returns the result associated with the query.
Definition: qsqlquery.cpp:450
QSqlDriver * driver() const
Returns the database driver used to access the database connection.
QString lastQuery() const
Returns the text of the current query being used, or an empty string if there is no current query tex...
Definition: qsqlquery.cpp:432
bool isSelect() const
Returns true if the current query is a SELECT statement; otherwise returns false. ...
Definition: qsqlquery.cpp:795
Q_CORE_EXPORT void qDebug(const char *,...)
bool execBatch(BatchExecutionMode mode=ValuesAsRows)
Executes a previously prepared SQL query in a batch.
Definition: qsqlquery.cpp:1005
void clear()
Clears the result set and releases any resources held by the query.
Definition: qsqlquery.cpp:874
QFuture< void > map(Sequence &sequence, MapFunction function)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QVariant boundValue(const QString &placeholder) const
Returns the value for the placeholder.
Definition: qsqlquery.cpp:1070
QString trimmed() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end.
Definition: qstring.cpp:4506
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
static QSqlDatabase database(const QString &connectionName=QLatin1String(defaultConnection), bool open=true)
Returns the database connection called connectionName.
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
Q_CORE_EXPORT void qWarning(const char *,...)
QSqlResult * sqlResult
Definition: qsqlquery.cpp:63
quint16 values[128]
bool last()
Retrieves the last record in the result, if available, and positions the query on the retrieved recor...
Definition: qsqlquery.cpp:703
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT
Returns the local 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:4049
QString executedQuery() const
Returns the last query that was successfully executed.
Definition: qsqlquery.cpp:1119
void setForwardOnly(bool forward)
Sets forward only mode to forward.
Definition: qsqlquery.cpp:835
virtual QSqlResult * createResult() const =0
Creates an empty SQL result on the database.
QSqlQueryPrivate * d
Definition: qsqlquery.h:123
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
bool exec()
Executes a previously prepared SQL query.
Definition: qsqlquery.cpp:943
int count() const
Returns the number of fields in the record.
Definition: qsqlrecord.cpp:573
void addBindValue(const QVariant &val, QSql::ParamType type=QSql::In)
Adds the value val to the list of values when using positional value binding.
Definition: qsqlquery.cpp:1060
QSqlError lastError() const
Returns error information about the last error (if any) that occurred with this query.
Definition: qsqlquery.cpp:754
QT_STATIC_CONST char * defaultConnection
Definition: qsqldatabase.h:128
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
Instruct the database driver to return numerical values with a precision specified by precisionPolicy...
Definition: qsqlquery.cpp:1174
static QByteArray paramType(const QByteArray &ptype, bool *out)
static void qInit(QSqlQuery *q, const QString &query, QSqlDatabase db)
Definition: qsqlquery.cpp:264
BatchExecutionMode
Definition: qsqlquery.h:107
bool nextResult()
Discards the current result set and navigates to the next if available.
Definition: qsqlquery.cpp:1248
void qAtomicAssign(T *&d, T *x)
This is a helper for the assignment operators of implicitly shared classes.
Definition: qatomic.h:195
QSqlQueryPrivate(QSqlResult *result)
Definition: qsqlquery.cpp:82
static QSqlQueryPrivate * shared_null()
quint16 index
bool isForwardOnly() const
Returns true if you can only scroll forward through a result set; otherwise returns false...
Definition: qsqlquery.cpp:806
void bindValue(const QString &placeholder, const QVariant &val, QSql::ParamType type=QSql::In)
Set the placeholder placeholder to be bound to value val in the prepared statement.
Definition: qsqlquery.cpp:1030
bool seek(int i, bool relative=false)
Retrieves the record at position index, if available, and positions the query on the retrieved record...
Definition: qsqlquery.cpp:502
int size() const
Returns the size of the result (number of rows returned), or -1 if the size cannot be determined or i...
Definition: qsqlquery.cpp:724
void setValue(int i, const QVariant &val)
Sets the value of the field at position index to val.
Definition: qsqlrecord.cpp:585
bool exec(const QString &query)
Executes the SQL in query.
Definition: qsqlquery.cpp:355
QSqlQuery & operator=(const QSqlQuery &other)
Assigns other to this object.
Definition: qsqlquery.cpp:308
bool isNull(int field) const
Returns true if the query is active and positioned on a valid record and the field is NULL; otherwise...
Definition: qsqlquery.cpp:323
int at() const
Returns the current internal position of the query.
Definition: qsqlquery.cpp:420
QVariant value(int i) const
Returns the value of field index in the current record.
Definition: qsqlquery.cpp:403
bool next()
Retrieves the next record in the result, if available, and positions the query on the retrieved recor...
Definition: qsqlquery.cpp:594
The QSqlResult class provides an abstract interface for accessing data from specific SQL databases...
Definition: qsqlresult.h:63
QMap< QString, QVariant > boundValues() const
Returns a map of the bound values.
Definition: qsqlquery.cpp:1097
QVariant lastInsertId() const
Returns the object ID of the most recent inserted row if the database supports it.
Definition: qsqlquery.cpp:1148
bool isValid() const
Returns true if the query is currently positioned on a valid record; otherwise returns false...
Definition: qsqlquery.cpp:764
QAtomicInt ref
Definition: qsqlquery.cpp:62