source: trunk/src/sql/kernel/qsqlquery.cpp@ 1061

Last change on this file since 1061 was 846, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 37.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtSql module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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
55QT_BEGIN_NAMESPACE
56
57class QSqlQueryPrivate
58{
59public:
60 QSqlQueryPrivate(QSqlResult* result);
61 ~QSqlQueryPrivate();
62 QAtomicInt ref;
63 QSqlResult* sqlResult;
64
65 static QSqlQueryPrivate* shared_null();
66};
67
68Q_GLOBAL_STATIC_WITH_ARGS(QSqlQueryPrivate, nullQueryPrivate, (0))
69Q_GLOBAL_STATIC(QSqlNullDriver, nullDriver)
70Q_GLOBAL_STATIC_WITH_ARGS(QSqlNullResult, nullResult, (nullDriver()))
71
72QSqlQueryPrivate* QSqlQueryPrivate::shared_null()
73{
74 QSqlQueryPrivate *null = nullQueryPrivate();
75 null->ref.ref();
76 return null;
77}
78
79/*!
80\internal
81*/
82QSqlQueryPrivate::QSqlQueryPrivate(QSqlResult* result)
83 : ref(1), sqlResult(result)
84{
85 if (!sqlResult)
86 sqlResult = nullResult();
87}
88
89QSqlQueryPrivate::~QSqlQueryPrivate()
90{
91 QSqlResult *nr = nullResult();
92 if (!nr || sqlResult == nr)
93 return;
94 delete sqlResult;
95}
96
97/*!
98 \class QSqlQuery
99 \brief The QSqlQuery class provides a means of executing and
100 manipulating SQL statements.
101
102 \ingroup database
103 \ingroup shared
104
105 \inmodule QtSql
106
107 QSqlQuery encapsulates the functionality involved in creating,
108 navigating and retrieving data from SQL queries which are
109 executed on a \l QSqlDatabase. It can be used to execute DML
110 (data manipulation language) statements, such as \c SELECT, \c
111 INSERT, \c UPDATE and \c DELETE, as well as DDL (data definition
112 language) statements, such as \c{CREATE} \c{TABLE}. It can also
113 be used to execute database-specific commands which are not
114 standard SQL (e.g. \c{SET DATESTYLE=ISO} for PostgreSQL).
115
116 Successfully executed SQL statements set the query's state to
117 active so that isActive() returns true. Otherwise the query's
118 state is set to inactive. In either case, when executing a new SQL
119 statement, the query is positioned on an invalid record. An active
120 query must be navigated to a valid record (so that isValid()
121 returns true) before values can be retrieved.
122
123 For some databases, if an active query that is a \c{SELECT}
124 statement exists when you call \l{QSqlDatabase::}{commit()} or
125 \l{QSqlDatabase::}{rollback()}, the commit or rollback will
126 fail. See isActive() for details.
127
128 \target QSqlQuery examples
129
130 Navigating records is performed with the following functions:
131
132 \list
133 \o next()
134 \o previous()
135 \o first()
136 \o last()
137 \o seek()
138 \endlist
139
140 These functions allow the programmer to move forward, backward
141 or arbitrarily through the records returned by the query. If you
142 only need to move forward through the results (e.g., by using
143 next()), you can use setForwardOnly(), which will save a
144 significant amount of memory overhead and improve performance on
145 some databases. Once an active query is positioned on a valid
146 record, data can be retrieved using value(). All data is
147 transferred from the SQL backend using QVariants.
148
149 For example:
150
151 \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 7
152
153 To access the data returned by a query, use value(int). Each
154 field in the data returned by a \c SELECT statement is accessed
155 by passing the field's position in the statement, starting from
156 0. This makes using \c{SELECT *} queries inadvisable because the
157 order of the fields returned is indeterminate.
158
159 For the sake of efficiency, there are no functions to access a
160 field by name (unless you use prepared queries with names, as
161 explained below). To convert a field name into an index, use
162 record().\l{QSqlRecord::indexOf()}{indexOf()}, for example:
163
164 \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 8
165
166 QSqlQuery supports prepared query execution and the binding of
167 parameter values to placeholders. Some databases don't support
168 these features, so for those, Qt emulates the required
169 functionality. For example, the Oracle and ODBC drivers have
170 proper prepared query support, and Qt makes use of it; but for
171 databases that don't have this support, Qt implements the feature
172 itself, e.g. by replacing placeholders with actual values when a
173 query is executed. Use numRowsAffected() to find out how many rows
174 were affected by a non-\c SELECT query, and size() to find how
175 many were retrieved by a \c SELECT.
176
177 Oracle databases identify placeholders by using a colon-name
178 syntax, e.g \c{:name}. ODBC simply uses \c ? characters. Qt
179 supports both syntaxes, with the restriction that you can't mix
180 them in the same query.
181
182 You can retrieve the values of all the fields in a single variable
183 (a map) using boundValues().
184
185 \section1 Approaches to Binding Values
186
187 Below we present the same example using each of the four
188 different binding approaches, as well as one example of binding
189 values to a stored procedure.
190
191 \bold{Named binding using named placeholders:}
192
193 \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 9
194
195 \bold{Positional binding using named placeholders:}
196
197 \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 10
198
199 \bold{Binding values using positional placeholders (version 1):}
200
201 \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 11
202
203 \bold{Binding values using positional placeholders (version 2):}
204
205 \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 12
206
207 \bold{Binding values to a stored procedure:}
208
209 This code calls a stored procedure called \c AsciiToInt(), passing
210 it a character through its in parameter, and taking its result in
211 the out parameter.
212
213 \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 13
214
215 Note that unbound parameters will retain their values.
216
217 Stored procedures that uses the return statement to return values,
218 or return multiple result sets, are not fully supported. For specific
219 details see \l{SQL Database Drivers}.
220
221 \warning You must load the SQL driver and open the connection before a
222 QSqlQuery is created. Also, the connection must remain open while the
223 query exists; otherwise, the behavior of QSqlQuery is undefined.
224
225 \sa QSqlDatabase, QSqlQueryModel, QSqlTableModel, QVariant
226*/
227
228/*!
229 Constructs a QSqlQuery object which uses the QSqlResult \a result
230 to communicate with a database.
231*/
232
233QSqlQuery::QSqlQuery(QSqlResult *result)
234{
235 d = new QSqlQueryPrivate(result);
236}
237
238/*!
239 Destroys the object and frees any allocated resources.
240*/
241
242QSqlQuery::~QSqlQuery()
243{
244 if (!d->ref.deref())
245 delete d;
246}
247
248/*!
249 Constructs a copy of \a other.
250*/
251
252QSqlQuery::QSqlQuery(const QSqlQuery& other)
253{
254 d = other.d;
255 d->ref.ref();
256}
257
258/*!
259 \internal
260*/
261static void qInit(QSqlQuery *q, const QString& query, QSqlDatabase db)
262{
263 QSqlDatabase database = db;
264 if (!database.isValid())
265 database = QSqlDatabase::database(QLatin1String(QSqlDatabase::defaultConnection), false);
266 if (database.isValid()) {
267 *q = QSqlQuery(database.driver()->createResult());
268 }
269 if (!query.isEmpty())
270 q->exec(query);
271}
272
273/*!
274 Constructs a QSqlQuery object using the SQL \a query and the
275 database \a db. If \a db is not specified, or is invalid, the application's
276 default database is used. If \a query is not an empty string, it
277 will be executed.
278
279 \sa QSqlDatabase
280*/
281QSqlQuery::QSqlQuery(const QString& query, QSqlDatabase db)
282{
283 d = QSqlQueryPrivate::shared_null();
284 qInit(this, query, db);
285}
286
287/*!
288 Constructs a QSqlQuery object using the database \a db.
289 If \a db is invalid, the application's default database will be used.
290
291 \sa QSqlDatabase
292*/
293
294QSqlQuery::QSqlQuery(QSqlDatabase db)
295{
296 d = QSqlQueryPrivate::shared_null();
297 qInit(this, QString(), db);
298}
299
300
301/*!
302 Assigns \a other to this object.
303*/
304
305QSqlQuery& QSqlQuery::operator=(const QSqlQuery& other)
306{
307 qAtomicAssign(d, other.d);
308 return *this;
309}
310
311/*!
312 Returns true if the query is \l{isActive()}{active} and positioned
313 on a valid record and the \a field is NULL; otherwise returns
314 false. Note that for some drivers, isNull() will not return accurate
315 information until after an attempt is made to retrieve data.
316
317 \sa isActive(), isValid(), value()
318*/
319
320bool QSqlQuery::isNull(int field) const
321{
322 if (d->sqlResult->isActive() && d->sqlResult->isValid())
323 return d->sqlResult->isNull(field);
324 return true;
325}
326
327/*!
328
329 Executes the SQL in \a query. Returns true and sets the query state
330 to \l{isActive()}{active} if the query was successful; otherwise
331 returns false. The \a query string must use syntax appropriate for
332 the SQL database being queried (for example, standard SQL).
333
334 After the query is executed, the query is positioned on an \e
335 invalid record and must be navigated to a valid record before data
336 values can be retrieved (for example, using next()).
337
338 Note that the last error for this query is reset when exec() is
339 called.
340
341 Example:
342
343 \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 34
344
345 \sa isActive(), isValid(), next(), previous(), first(), last(),
346 seek()
347*/
348
349bool QSqlQuery::exec(const QString& query)
350{
351 if (d->ref != 1) {
352 bool fo = isForwardOnly();
353 *this = QSqlQuery(driver()->createResult());
354 d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
355 setForwardOnly(fo);
356 } else {
357 d->sqlResult->clear();
358 d->sqlResult->setActive(false);
359 d->sqlResult->setLastError(QSqlError());
360 d->sqlResult->setAt(QSql::BeforeFirstRow);
361 d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
362 }
363 d->sqlResult->setQuery(query.trimmed());
364 if (!driver()->isOpen() || driver()->isOpenError()) {
365 qWarning("QSqlQuery::exec: database not open");
366 return false;
367 }
368 if (query.isEmpty()) {
369 qWarning("QSqlQuery::exec: empty query");
370 return false;
371 }
372#ifdef QT_DEBUG_SQL
373 qDebug("\n QSqlQuery: %s", query.toLocal8Bit().constData());
374#endif
375 return d->sqlResult->reset(query);
376}
377
378/*!
379 Returns the value of field \a index in the current record.
380
381 The fields are numbered from left to right using the text of the
382 \c SELECT statement, e.g. in
383
384 \snippet doc/src/snippets/code/src_sql_kernel_qsqlquery.cpp 0
385
386 field 0 is \c forename and field 1 is \c
387 surname. Using \c{SELECT *} is not recommended because the order
388 of the fields in the query is undefined.
389
390 An invalid QVariant is returned if field \a index does not
391 exist, if the query is inactive, or if the query is positioned on
392 an invalid record.
393
394 \sa previous() next() first() last() seek() isActive() isValid()
395*/
396
397QVariant QSqlQuery::value(int index) const
398{
399 if (isActive() && isValid() && (index > QSql::BeforeFirstRow))
400 return d->sqlResult->data(index);