author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Fri, 19 Feb 2010 23:40:16 +0200 | |
branch | RCL_3 |
changeset 4 | 3b1da2848fc7 |
parent 0 | 1918ee327afb |
permissions | -rw-r--r-- |
0 | 1 |
/**************************************************************************** |
2 |
** |
|
4
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
3 |
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
0 | 4 |
** All rights reserved. |
5 |
** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 |
** |
|
7 |
** This file is part of the QtSql module of the Qt Toolkit. |
|
8 |
** |
|
9 |
** $QT_BEGIN_LICENSE:LGPL$ |
|
10 |
** No Commercial Usage |
|
11 |
** This file contains pre-release code and may not be distributed. |
|
12 |
** You may use this file in accordance with the terms and conditions |
|
13 |
** contained in the Technology Preview License Agreement accompanying |
|
14 |
** this package. |
|
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 |
** If you have questions regarding the use of this file, please contact |
|
29 |
** Nokia at qt-info@nokia.com. |
|
30 |
** |
|
31 |
** |
|
32 |
** |
|
33 |
** |
|
34 |
** |
|
35 |
** |
|
36 |
** |
|
37 |
** |
|
38 |
** $QT_END_LICENSE$ |
|
39 |
** |
|
40 |
****************************************************************************/ |
|
41 |
||
42 |
#include "qsqldriver.h" |
|
43 |
||
44 |
#include "qdatetime.h" |
|
45 |
#include "qsqlerror.h" |
|
46 |
#include "qsqlfield.h" |
|
47 |
#include "qsqlindex.h" |
|
48 |
#include "private/qobject_p.h" |
|
49 |
||
50 |
QT_BEGIN_NAMESPACE |
|
51 |
||
52 |
static QString prepareIdentifier(const QString &identifier, |
|
53 |
QSqlDriver::IdentifierType type, const QSqlDriver *driver) |
|
54 |
{ |
|
55 |
Q_ASSERT( driver != NULL ); |
|
56 |
QString ret = identifier; |
|
57 |
if (!driver->isIdentifierEscaped(identifier, type)) { |
|
58 |
ret = driver->escapeIdentifier(identifier, type); |
|
59 |
} |
|
60 |
return ret; |
|
61 |
} |
|
62 |
||
63 |
class QSqlDriverPrivate : public QObjectPrivate |
|
64 |
{ |
|
65 |
public: |
|
66 |
QSqlDriverPrivate(); |
|
67 |
virtual ~QSqlDriverPrivate(); |
|
68 |
||
69 |
public: |
|
70 |
// @CHECK: this member is never used. It was named q, which expanded to q_func(). |
|
71 |
QSqlDriver *q_func(); |
|
72 |
uint isOpen : 1; |
|
73 |
uint isOpenError : 1; |
|
74 |
QSqlError error; |
|
75 |
QSql::NumericalPrecisionPolicy precisionPolicy; |
|
76 |
}; |
|
77 |
||
78 |
inline QSqlDriverPrivate::QSqlDriverPrivate() |
|
79 |
: QObjectPrivate(), isOpen(false), isOpenError(false), precisionPolicy(QSql::LowPrecisionDouble) |
|
80 |
{ |
|
81 |
} |
|
82 |
||
83 |
QSqlDriverPrivate::~QSqlDriverPrivate() |
|
84 |
{ |
|
85 |
} |
|
86 |
||
87 |
/*! |
|
88 |
\class QSqlDriver |
|
89 |
\brief The QSqlDriver class is an abstract base class for accessing |
|
90 |
specific SQL databases. |
|
91 |
||
92 |
\ingroup database |
|
93 |
\inmodule QtSql |
|
94 |
||
95 |
This class should not be used directly. Use QSqlDatabase instead. |
|
96 |
||
97 |
If you want to create your own SQL drivers, you can subclass this |
|
98 |
class and reimplement its pure virtual functions and those |
|
99 |
virtual functions that you need. See \l{How to Write Your Own |
|
100 |
Database Driver} for more information. |
|
101 |
||
102 |
\sa QSqlDatabase, QSqlResult |
|
103 |
*/ |
|
104 |
||
105 |
/*! |
|
106 |
Constructs a new driver with the given \a parent. |
|
107 |
*/ |
|
108 |
||
109 |
QSqlDriver::QSqlDriver(QObject *parent) |
|
110 |
: QObject(*new QSqlDriverPrivate, parent) |
|
111 |
{ |
|
112 |
} |
|
113 |
||
114 |
/*! |
|
115 |
Destroys the object and frees any allocated resources. |
|
116 |
*/ |
|
117 |
||
118 |
QSqlDriver::~QSqlDriver() |
|
119 |
{ |
|
120 |
} |
|
121 |
||
122 |
/*! |
|
123 |
\since 4.4 |
|
124 |
||
125 |
\fn QSqlDriver::notification(const QString &name) |
|
126 |
||
127 |
This signal is emitted when the database posts an event notification |
|
128 |
that the driver subscribes to. \a name identifies the event notification. |
|
129 |
||
130 |
\sa subscribeToNotification() |
|
131 |
*/ |
|
132 |
||
133 |
/*! |
|
134 |
\fn bool QSqlDriver::open(const QString &db, const QString &user, const QString& password, |
|
135 |
const QString &host, int port, const QString &options) |
|
136 |
||
137 |
Derived classes must reimplement this pure virtual function to |
|
138 |
open a database connection on database \a db, using user name \a |
|
139 |
user, password \a password, host \a host, port \a port and |
|
140 |
connection options \a options. |
|
141 |
||
142 |
The function must return true on success and false on failure. |
|
143 |
||
144 |
\sa setOpen() |
|
145 |
*/ |
|
146 |
||
147 |
/*! |
|
148 |
\fn bool QSqlDriver::close() |
|
149 |
||
150 |
Derived classes must reimplement this pure virtual function in |
|
151 |
order to close the database connection. Return true on success, |
|
152 |
false on failure. |
|
153 |
||
154 |
\sa open(), setOpen() |
|
155 |
*/ |
|
156 |
||
157 |
/*! |
|
158 |
\fn QSqlResult *QSqlDriver::createResult() const |
|
159 |
||
160 |
Creates an empty SQL result on the database. Derived classes must |
|
161 |
reimplement this function and return a QSqlResult object |
|
162 |
appropriate for their database to the caller. |
|
163 |
*/ |
|
164 |
||
165 |
/*! |
|
166 |
Returns true if the database connection is open; otherwise returns |
|
167 |
false. |
|
168 |
*/ |
|
169 |
||
170 |
bool QSqlDriver::isOpen() const |
|
171 |
{ |
|
172 |
return d_func()->isOpen; |
|
173 |
} |
|
174 |
||
175 |
/*! |
|
176 |
Returns true if the there was an error opening the database |
|
177 |
connection; otherwise returns false. |
|
178 |
*/ |
|
179 |
||
180 |
bool QSqlDriver::isOpenError() const |
|
181 |
{ |
|
182 |
return d_func()->isOpenError; |
|
183 |
} |
|
184 |
||
185 |
/*! |
|
186 |
\enum QSqlDriver::DriverFeature |
|
187 |
||
188 |
This enum contains a list of features a driver might support. Use |
|
189 |
hasFeature() to query whether a feature is supported or not. |
|
190 |
||
191 |
\value Transactions Whether the driver supports SQL transactions. |
|
192 |
\value QuerySize Whether the database is capable of reporting the size |
|
193 |
of a query. Note that some databases do not support returning the size |
|
194 |
(i.e. number of rows returned) of a query, in which case |
|
195 |
QSqlQuery::size() will return -1. |
|
196 |
\value BLOB Whether the driver supports Binary Large Object fields. |
|
197 |
\value Unicode Whether the driver supports Unicode strings if the |
|
198 |
database server does. |
|
199 |
\value PreparedQueries Whether the driver supports prepared query execution. |
|
200 |
\value NamedPlaceholders Whether the driver supports the use of named placeholders. |
|
201 |
\value PositionalPlaceholders Whether the driver supports the use of positional placeholders. |
|
202 |
\value LastInsertId Whether the driver supports returning the Id of the last touched row. |
|
203 |
\value BatchOperations Whether the driver supports batched operations, see QSqlQuery::execBatch() |
|
204 |
\value SimpleLocking Whether the driver disallows a write lock on a table while other queries have a read lock on it. |
|
205 |
\value LowPrecisionNumbers Whether the driver allows fetching numerical values with low precision. |
|
206 |
\value EventNotifications Whether the driver supports database event notifications. |
|
207 |
\value FinishQuery Whether the driver can do any low-level resource cleanup when QSqlQuery::finish() is called. |
|
208 |
\value MultipleResultSets Whether the driver can access multiple result sets returned from batched statements or stored procedures. |
|
209 |
||
210 |
More information about supported features can be found in the |
|
211 |
\l{sql-driver.html}{Qt SQL driver} documentation. |
|
212 |
||
213 |
\sa hasFeature() |
|
214 |
*/ |
|
215 |
||
216 |
/*! |
|
217 |
\enum QSqlDriver::StatementType |
|
218 |
||
219 |
This enum contains a list of SQL statement (or clause) types the |
|
220 |
driver can create. |
|
221 |
||
222 |
\value WhereStatement An SQL \c WHERE statement (e.g., \c{WHERE f = 5}). |
|
223 |
\value SelectStatement An SQL \c SELECT statement (e.g., \c{SELECT f FROM t}). |
|
224 |
\value UpdateStatement An SQL \c UPDATE statement (e.g., \c{UPDATE TABLE t set f = 1}). |
|
225 |
\value InsertStatement An SQL \c INSERT statement (e.g., \c{INSERT INTO t (f) values (1)}). |
|
226 |
\value DeleteStatement An SQL \c DELETE statement (e.g., \c{DELETE FROM t}). |
|
227 |
||
228 |
\sa sqlStatement() |
|
229 |
*/ |
|
230 |
||
231 |
/*! |
|
232 |
\enum QSqlDriver::IdentifierType |
|
233 |
||
234 |
This enum contains a list of SQL identifier types. |
|
235 |
||
236 |
\value FieldName A SQL field name |
|
237 |
\value TableName A SQL table name |
|
238 |
*/ |
|
239 |
||
240 |
/*! |
|
241 |
\fn bool QSqlDriver::hasFeature(DriverFeature feature) const |
|
242 |
||
243 |
Returns true if the driver supports feature \a feature; otherwise |
|
244 |
returns false. |
|
245 |
||
246 |
Note that some databases need to be open() before this can be |
|
247 |
determined. |
|
248 |
||
249 |
\sa DriverFeature |
|
250 |
*/ |
|
251 |
||
252 |
/*! |
|
253 |
This function sets the open state of the database to \a open. |
|
254 |
Derived classes can use this function to report the status of |
|
255 |
open(). |
|
256 |
||
257 |
\sa open(), setOpenError() |
|
258 |
*/ |
|
259 |
||
260 |
void QSqlDriver::setOpen(bool open) |
|
261 |
{ |
|
262 |
d_func()->isOpen = open; |
|
263 |
} |
|
264 |
||
265 |
/*! |
|
266 |
This function sets the open error state of the database to \a |
|
267 |
error. Derived classes can use this function to report the status |
|
268 |
of open(). Note that if \a error is true the open state of the |
|
269 |
database is set to closed (i.e., isOpen() returns false). |
|
270 |
||
271 |
\sa open(), setOpen() |
|
272 |
*/ |
|
273 |
||
274 |
void QSqlDriver::setOpenError(bool error) |
|
275 |
{ |
|
276 |
d_func()->isOpenError = error; |
|
277 |
if (error) |
|
278 |
d_func()->isOpen = false; |
|
279 |
} |
|
280 |
||
281 |
/*! |
|
282 |
This function is called to begin a transaction. If successful, |
|
283 |
return true, otherwise return false. The default implementation |
|
284 |
does nothing and returns false. |
|
285 |
||
286 |
\sa commitTransaction(), rollbackTransaction() |
|
287 |
*/ |
|
288 |
||
289 |
bool QSqlDriver::beginTransaction() |
|
290 |
{ |
|
291 |
return false; |
|
292 |
} |
|
293 |
||
294 |
/*! |
|
295 |
This function is called to commit a transaction. If successful, |
|
296 |
return true, otherwise return false. The default implementation |
|
297 |
does nothing and returns false. |
|
298 |
||
299 |
\sa beginTransaction(), rollbackTransaction() |
|
300 |
*/ |
|
301 |
||
302 |
bool QSqlDriver::commitTransaction() |
|
303 |
{ |
|
304 |
return false; |
|
305 |
} |
|
306 |
||
307 |
/*! |
|
308 |
This function is called to rollback a transaction. If successful, |
|
309 |
return true, otherwise return false. The default implementation |
|
310 |
does nothing and returns false. |
|
311 |
||
312 |
\sa beginTransaction(), commitTransaction() |
|
313 |
*/ |
|
314 |
||
315 |
bool QSqlDriver::rollbackTransaction() |
|
316 |
{ |
|
317 |
return false; |
|
318 |
} |
|
319 |
||
320 |
/*! |
|
321 |
This function is used to set the value of the last error, \a error, |
|
322 |
that occurred on the database. |
|
323 |
||
324 |
\sa lastError() |
|
325 |
*/ |
|
326 |
||
327 |
void QSqlDriver::setLastError(const QSqlError &error) |
|
328 |
{ |
|
329 |
d_func()->error = error; |
|
330 |
} |
|
331 |
||
332 |
/*! |
|
333 |
Returns a QSqlError object which contains information about the |
|
334 |
last error that occurred on the database. |
|
335 |
*/ |
|
336 |
||
337 |
QSqlError QSqlDriver::lastError() const |
|
338 |
{ |
|
339 |
return d_func()->error; |
|
340 |
} |
|
341 |
||
342 |
/*! |
|
343 |
Returns a list of the names of the tables in the database. The |
|
344 |
default implementation returns an empty list. |
|
345 |
||
346 |
The \a tableType argument describes what types of tables |
|
347 |
should be returned. Due to binary compatibility, the string |
|
348 |
contains the value of the enum QSql::TableTypes as text. |
|
349 |
An empty string should be treated as QSql::Tables for |
|
350 |
backward compatibility. |
|
351 |
*/ |
|
352 |
||
353 |
QStringList QSqlDriver::tables(QSql::TableType) const |
|
354 |
{ |
|
355 |
return QStringList(); |
|
356 |
} |
|
357 |
||
358 |
/*! |
|
359 |
Returns the primary index for table \a tableName. Returns an empty |
|
360 |
QSqlIndex if the table doesn't have a primary index. The default |
|
361 |
implementation returns an empty index. |
|
362 |
*/ |
|
363 |
||
364 |
QSqlIndex QSqlDriver::primaryIndex(const QString&) const |
|
365 |
{ |
|
366 |
return QSqlIndex(); |
|
367 |
} |
|
368 |
||
369 |
||
370 |
/*! |
|
371 |
Returns a QSqlRecord populated with the names of the fields in |
|
372 |
table \a tableName. If no such table exists, an empty record is |
|
373 |
returned. The default implementation returns an empty record. |
|
374 |
*/ |
|
375 |
||
376 |
QSqlRecord QSqlDriver::record(const QString & /* tableName */) const |
|
377 |
{ |
|
378 |
return QSqlRecord(); |
|
379 |
} |
|
380 |
||
381 |
/*! |
|
382 |
Returns the \a identifier escaped according to the database rules. |
|
383 |
\a identifier can either be a table name or field name, dependent |
|
384 |
on \a type. |
|
385 |
||
386 |
The default implementation does nothing. |
|
387 |
\sa isIdentifierEscaped() |
|
388 |
*/ |
|
389 |
QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType) const |
|
390 |
{ |
|
391 |
return identifier; |
|
392 |
} |
|
393 |
||
394 |
/*! |
|
395 |
Returns whether \a identifier is escaped according to the database rules. |
|
396 |
\a identifier can either be a table name or field name, dependent |
|
397 |
on \a type. |
|
398 |
||
399 |
\warning Because of binary compatability constraints, this function is not virtual. |
|
400 |
If you want to provide your own implementation in your QSqlDriver subclass, |
|
401 |
reimplement the isIdentifierEscapedImplementation() slot in your subclass instead. |
|
402 |
The isIdentifierEscapedFunction() will dynamically detect the slot and call it. |
|
403 |
||
404 |
\sa stripDelimiters(), escapeIdentifier() |
|
405 |
*/ |
|
406 |
bool QSqlDriver::isIdentifierEscaped(const QString &identifier, IdentifierType type) const |
|
407 |
{ |
|
408 |
bool result; |
|
409 |
QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this), |
|
410 |
"isIdentifierEscapedImplementation", Qt::DirectConnection, |
|
411 |
Q_RETURN_ARG(bool, result), |
|
412 |
Q_ARG(QString, identifier), |
|
413 |
Q_ARG(IdentifierType, type)); |
|
414 |
return result; |
|
415 |
} |
|
416 |
||
417 |
/*! |
|
418 |
Returns the \a identifier with the leading and trailing delimiters removed, |
|
419 |
\a identifier can either be a table name or field name, |
|
420 |
dependent on \a type. If \a identifier does not have leading |
|
421 |
and trailing delimiter characters, \a identifier is returned without |
|
422 |
modification. |
|
423 |
||
424 |
\warning Because of binary compatability constraints, this function is not virtual, |
|
425 |
If you want to provide your own implementation in your QSqlDriver subclass, |
|
426 |
reimplement the stripDelimitersImplementation() slot in your subclass instead. |
|
427 |
The stripDelimiters() function will dynamically detect the slot and call it. |
|
428 |
||
429 |
\since 4.5 |
|
430 |
\sa isIdentifierEscaped() |
|
431 |
*/ |
|
432 |
QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType type) const |
|
433 |
{ |
|
434 |
QString result; |
|
435 |
QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this), |
|
436 |
"stripDelimitersImplementation", Qt::DirectConnection, |
|
437 |
Q_RETURN_ARG(QString, result), |
|
438 |
Q_ARG(QString, identifier), |
|
439 |
Q_ARG(IdentifierType, type)); |
|
440 |
return result; |
|
441 |
} |
|
442 |
||
443 |
/*! |
|
444 |
Returns a SQL statement of type \a type for the table \a tableName |
|
445 |
with the values from \a rec. If \a preparedStatement is true, the |
|
446 |
string will contain placeholders instead of values. |
|
447 |
||
448 |
This method can be used to manipulate tables without having to worry |
|
449 |
about database-dependent SQL dialects. For non-prepared statements, |
|
450 |
the values will be properly escaped. |
|
451 |
*/ |
|
452 |
QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, |
|
453 |
const QSqlRecord &rec, bool preparedStatement) const |
|
454 |
{ |
|
455 |
int i; |
|
456 |
QString s; |
|
457 |
s.reserve(128); |
|
458 |
switch (type) { |
|
459 |
case SelectStatement: |
|
460 |
for (i = 0; i < rec.count(); ++i) { |
|
461 |
if (rec.isGenerated(i)) |
|
462 |
s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", ")); |
|
463 |
} |
|
464 |
if (s.isEmpty()) |
|
465 |
return s; |
|
466 |
s.chop(2); |
|
467 |
s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName); |
|
468 |
break; |
|
469 |
case WhereStatement: |
|
470 |
if (preparedStatement) { |
|
471 |
for (int i = 0; i < rec.count(); ++i) { |
|
472 |
s.append(prepareIdentifier(rec.fieldName(i), FieldName,this)); |
|
473 |
if (rec.isNull(i)) |
|
474 |
s.append(QLatin1String(" IS NULL")); |
|
475 |
else |
|
476 |
s.append(QLatin1String(" = ?")); |
|
477 |
s.append(QLatin1String(" AND ")); |
|
478 |
} |
|
479 |
} else { |
|
480 |
for (i = 0; i < rec.count(); ++i) { |
|
481 |
s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)); |
|
482 |
QString val = formatValue(rec.field(i)); |
|
483 |
if (val == QLatin1String("NULL")) |
|
484 |
s.append(QLatin1String(" IS NULL")); |
|
485 |
else |
|
486 |
s.append(QLatin1String(" = ")).append(val); |
|
487 |
s.append(QLatin1String(" AND ")); |
|
488 |
} |
|
489 |
} |
|
490 |
if (!s.isEmpty()) { |
|
491 |
s.prepend(QLatin1String("WHERE ")); |
|
492 |
s.chop(5); // remove tailing AND |
|
493 |
} |
|
494 |
break; |
|
495 |
case UpdateStatement: |
|
496 |
s.append(QLatin1String("UPDATE ")).append(tableName).append( |
|
497 |
QLatin1String(" SET ")); |
|
498 |
for (i = 0; i < rec.count(); ++i) { |
|
499 |
if (!rec.isGenerated(i) || !rec.value(i).isValid()) |
|
500 |
continue; |
|
501 |
s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1Char('=')); |
|
502 |
if (preparedStatement) |
|
503 |
s.append(QLatin1Char('?')); |
|
504 |
else |
|
505 |
s.append(formatValue(rec.field(i))); |
|
506 |
s.append(QLatin1String(", ")); |
|
507 |
} |
|
508 |
if (s.endsWith(QLatin1String(", "))) |
|
509 |
s.chop(2); |
|
510 |
else |
|
511 |
s.clear(); |
|
512 |
break; |
|
513 |
case DeleteStatement: |
|
514 |
s.append(QLatin1String("DELETE FROM ")).append(tableName); |
|
515 |
break; |
|
516 |
case InsertStatement: { |
|
517 |
s.append(QLatin1String("INSERT INTO ")).append(tableName).append(QLatin1String(" (")); |
|
518 |
QString vals; |
|
519 |
for (i = 0; i < rec.count(); ++i) { |
|
520 |
if (!rec.isGenerated(i) || !rec.value(i).isValid()) |
|
521 |
continue; |
|
522 |
s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", ")); |
|
523 |
if (preparedStatement) |
|
524 |
vals.append(QLatin1Char('?')); |
|
525 |
else |
|
526 |
vals.append(formatValue(rec.field(i))); |
|
527 |
vals.append(QLatin1String(", ")); |
|
528 |
} |
|
529 |
if (vals.isEmpty()) { |
|
530 |
s.clear(); |
|
531 |
} else { |
|
532 |
vals.chop(2); // remove trailing comma |
|
533 |
s[s.length() - 2] = QLatin1Char(')'); |
|
534 |
s.append(QLatin1String("VALUES (")).append(vals).append(QLatin1Char(')')); |
|
535 |
} |
|
536 |
break; } |
|
537 |
} |
|
538 |
return s; |
|
539 |
} |
|
540 |
||
541 |
/*! |
|
542 |
Returns a string representation of the \a field value for the |
|
543 |
database. This is used, for example, when constructing INSERT and |
|
544 |
UPDATE statements. |
|
545 |
||
546 |
The default implementation returns the value formatted as a string |
|
547 |
according to the following rules: |
|
548 |
||
549 |
\list |
|
550 |
||
551 |
\i If \a field is character data, the value is returned enclosed |
|
552 |
in single quotation marks, which is appropriate for many SQL |
|
553 |
databases. Any embedded single-quote characters are escaped |
|
554 |
(replaced with two single-quote characters). If \a trimStrings is |
|
555 |
true (the default is false), all trailing whitespace is trimmed |
|
556 |
from the field. |
|
557 |
||
558 |
\i If \a field is date/time data, the value is formatted in ISO |
|
559 |
format and enclosed in single quotation marks. If the date/time |
|
560 |
data is invalid, "NULL" is returned. |
|
561 |
||
562 |
\i If \a field is \link QByteArray bytearray\endlink data, and the |
|
563 |
driver can edit binary fields, the value is formatted as a |
|
564 |
hexadecimal string. |
|
565 |
||
566 |
\i For any other field type, toString() is called on its value |
|
567 |
and the result of this is returned. |
|
568 |
||
569 |
\endlist |
|
570 |
||
571 |
\sa QVariant::toString() |
|
572 |
||
573 |
*/ |
|
574 |
QString QSqlDriver::formatValue(const QSqlField &field, bool trimStrings) const |
|
575 |
{ |
|
576 |
const QLatin1String nullTxt("NULL"); |
|
577 |
||
578 |
QString r; |
|
579 |
if (field.isNull()) |
|
580 |
r = nullTxt; |
|
581 |
else { |
|
582 |
switch (field.type()) { |
|
583 |
case QVariant::Int: |
|
584 |
case QVariant::UInt: |
|
585 |
if (field.value().type() == QVariant::Bool) |
|
586 |
r = field.value().toBool() ? QLatin1String("1") : QLatin1String("0"); |
|
587 |
else |
|
588 |
r = field.value().toString(); |
|
589 |
break; |
|
590 |
#ifndef QT_NO_DATESTRING |
|
591 |
case QVariant::Date: |
|
592 |
if (field.value().toDate().isValid()) |
|
593 |
r = QLatin1Char('\'') + field.value().toDate().toString(Qt::ISODate) |
|
594 |
+ QLatin1Char('\''); |
|
595 |
else |
|
596 |
r = nullTxt; |
|
597 |
break; |
|
598 |
case QVariant::Time: |
|
599 |
if (field.value().toTime().isValid()) |
|
600 |
r = QLatin1Char('\'') + field.value().toTime().toString(Qt::ISODate) |
|
601 |
+ QLatin1Char('\''); |
|
602 |
else |
|
603 |
r = nullTxt; |
|
604 |
break; |
|
605 |
case QVariant::DateTime: |
|
606 |
if (field.value().toDateTime().isValid()) |
|
607 |
r = QLatin1Char('\'') + |
|
608 |
field.value().toDateTime().toString(Qt::ISODate) + QLatin1Char('\''); |
|
609 |
else |
|
610 |
r = nullTxt; |
|
611 |
break; |
|
612 |
#endif |
|
613 |
case QVariant::String: |
|
614 |
case QVariant::Char: |
|
615 |
{ |
|
616 |
QString result = field.value().toString(); |
|
617 |
if (trimStrings) { |
|
618 |
int end = result.length(); |
|
619 |
while (end && result.at(end-1).isSpace()) /* skip white space from end */ |
|
620 |
end--; |
|
621 |
result.truncate(end); |
|
622 |
} |
|
623 |
/* escape the "'" character */ |
|
624 |
result.replace(QLatin1Char('\''), QLatin1String("''")); |
|
625 |
r = QLatin1Char('\'') + result + QLatin1Char('\''); |
|
626 |
break; |
|
627 |
} |
|
628 |
case QVariant::Bool: |
|
629 |
r = QString::number(field.value().toBool()); |
|
630 |
break; |
|
631 |
case QVariant::ByteArray : { |
|
632 |
if (hasFeature(BLOB)) { |
|
633 |
QByteArray ba = field.value().toByteArray(); |
|
634 |
QString res; |
|
635 |
static const char hexchars[] = "0123456789abcdef"; |
|
636 |
for (int i = 0; i < ba.size(); ++i) { |
|
637 |
uchar s = (uchar) ba[i]; |
|
638 |
res += QLatin1Char(hexchars[s >> 4]); |
|
639 |
res += QLatin1Char(hexchars[s & 0x0f]); |
|
640 |
} |
|
641 |
r = QLatin1Char('\'') + res + QLatin1Char('\''); |
|
642 |
break; |
|
643 |
} |
|
644 |
} |
|
645 |
default: |
|
646 |
r = field.value().toString(); |
|
647 |
break; |
|
648 |
} |
|
649 |
} |
|
650 |
return r; |
|
651 |
} |
|
652 |
||
653 |
/*! |
|
654 |
Returns the low-level database handle wrapped in a QVariant or an |
|
655 |
invalid variant if there is no handle. |
|
656 |
||
657 |
\warning Use this with uttermost care and only if you know what you're doing. |
|
658 |
||
659 |
\warning The handle returned here can become a stale pointer if the connection |
|
660 |
is modified (for example, if you close the connection). |
|
661 |
||
662 |
\warning The handle can be NULL if the connection is not open yet. |
|
663 |
||
664 |
The handle returned here is database-dependent, you should query the type |
|
665 |
name of the variant before accessing it. |
|
666 |
||
667 |
This example retrieves the handle for a connection to sqlite: |
|
668 |
||
669 |
\snippet doc/src/snippets/code/src_sql_kernel_qsqldriver.cpp 0 |
|
670 |
||
671 |
This snippet returns the handle for PostgreSQL or MySQL: |
|
672 |
||
673 |
\snippet doc/src/snippets/code/src_sql_kernel_qsqldriver.cpp 1 |
|
674 |
||
675 |
\sa QSqlResult::handle() |
|
676 |
*/ |
|
677 |
QVariant QSqlDriver::handle() const |
|
678 |
{ |
|
679 |
return QVariant(); |
|
680 |
} |
|
681 |
||
682 |
/*! |
|
683 |
\fn QSqlRecord QSqlDriver::record(const QSqlQuery& query) const |
|
684 |
||
685 |
Use query.record() instead. |
|
686 |
*/ |
|
687 |
||
688 |
/*! |
|
689 |
\fn QSqlRecord QSqlDriver::recordInfo(const QString& tablename) const |
|
690 |
||
691 |
Use record() instead. |
|
692 |
*/ |
|
693 |
||
694 |
/*! |
|
695 |
\fn QSqlRecord QSqlDriver::recordInfo(const QSqlQuery& query) const |
|
696 |
||
697 |
Use query.record() instead. |
|
698 |
*/ |
|
699 |
||
700 |
/*! |
|
701 |
\fn QString QSqlDriver::nullText() const |
|
702 |
||
703 |
sqlStatement() is now used to generate SQL. Use tr("NULL") for example, instead. |
|
704 |
*/ |
|
705 |
||
706 |
/*! |
|
707 |
\fn QString QSqlDriver::formatValue(const QSqlField *field, bool trimStrings) const |
|
708 |
||
709 |
Use the other formatValue() overload instead. |
|
710 |
*/ |
|
711 |
||
712 |
/*! |
|
713 |
This function is called to subscribe to event notifications from the database. |
|
714 |
\a name identifies the event notification. |
|
715 |
||
716 |
If successful, return true, otherwise return false. |
|
717 |
||
718 |
The database must be open when this function is called. When the database is closed |
|
719 |
by calling close() all subscribed event notifications are automatically unsubscribed. |
|
720 |
Note that calling open() on an already open database may implicitly cause close() to |
|
721 |
be called, which will cause the driver to unsubscribe from all event notifications. |
|
722 |
||
723 |
When an event notification identified by \a name is posted by the database the |
|
724 |
notification() signal is emitted. |
|
725 |
||
726 |
\warning Because of binary compatibility constraints, this function is not virtual. |
|
727 |
If you want to provide event notification support in your own QSqlDriver subclass, |
|
728 |
reimplement the subscribeToNotificationImplementation() slot in your subclass instead. |
|
729 |
The subscribeToNotification() function will dynamically detect the slot and call it. |
|
730 |
||
731 |
\since 4.4 |
|
732 |
\sa unsubscribeFromNotification() subscribedToNotifications() QSqlDriver::hasFeature() |
|
733 |
*/ |
|
734 |
bool QSqlDriver::subscribeToNotification(const QString &name) |
|
735 |
{ |
|
736 |
bool result; |
|
737 |
QMetaObject::invokeMethod(const_cast<QSqlDriver *>(this), |
|
738 |
"subscribeToNotificationImplementation", Qt::DirectConnection, |
|
739 |
Q_RETURN_ARG(bool, result), |
|
740 |
Q_ARG(QString, name)); |
|
741 |
return result; |
|
742 |
} |
|
743 |
||
744 |
/*! |
|
745 |
This function is called to unsubscribe from event notifications from the database. |
|
746 |
\a name identifies the event notification. |
|
747 |
||
748 |
If successful, return true, otherwise return false. |
|
749 |
||
750 |
The database must be open when this function is called. All subscribed event |
|
751 |
notifications are automatically unsubscribed from when the close() function is called. |
|
752 |
||
753 |
After calling \e this function the notification() signal will no longer be emitted |
|
754 |
when an event notification identified by \a name is posted by the database. |
|
755 |
||
756 |
\warning Because of binary compatibility constraints, this function is not virtual. |
|
757 |
If you want to provide event notification support in your own QSqlDriver subclass, |
|
758 |
reimplement the unsubscribeFromNotificationImplementation() slot in your subclass instead. |
|
759 |
The unsubscribeFromNotification() function will dynamically detect the slot and call it. |
|
760 |
||
761 |
\since 4.4 |
|
762 |
\sa subscribeToNotification() subscribedToNotifications() |
|
763 |
*/ |
|
764 |
bool QSqlDriver::unsubscribeFromNotification(const QString &name) |
|
765 |
{ |
|
766 |
bool result; |
|
767 |
QMetaObject::invokeMethod(const_cast<QSqlDriver *>(this), |
|
768 |
"unsubscribeFromNotificationImplementation", Qt::DirectConnection, |
|
769 |
Q_RETURN_ARG(bool, result), |
|
770 |
Q_ARG(QString, name)); |
|
771 |
return result; |
|
772 |
} |
|
773 |
||
774 |
/*! |
|
775 |
Returns a list of the names of the event notifications that are currently subscribed to. |
|
776 |
||
777 |
\warning Because of binary compatibility constraints, this function is not virtual. |
|
778 |
If you want to provide event notification support in your own QSqlDriver subclass, |
|
779 |
reimplement the subscribedToNotificationsImplementation() slot in your subclass instead. |
|
780 |
The subscribedToNotifications() function will dynamically detect the slot and call it. |
|
781 |
||
782 |
\since 4.4 |
|
783 |
\sa subscribeToNotification() unsubscribeFromNotification() |
|
784 |
*/ |
|
785 |
QStringList QSqlDriver::subscribedToNotifications() const |
|
786 |
{ |
|
787 |
QStringList result; |
|
788 |
QMetaObject::invokeMethod(const_cast<QSqlDriver *>(this), |
|
789 |
"subscribedToNotificationsImplementation", Qt::DirectConnection, |
|
790 |
Q_RETURN_ARG(QStringList, result)); |
|
791 |
return result; |
|
792 |
} |
|
793 |
||
794 |
/*! |
|
795 |
This slot is called to subscribe to event notifications from the database. |
|
796 |
\a name identifies the event notification. |
|
797 |
||
798 |
If successful, return true, otherwise return false. |
|
799 |
||
800 |
The database must be open when this \e slot is called. When the database is closed |
|
801 |
by calling close() all subscribed event notifications are automatically unsubscribed. |
|
802 |
Note that calling open() on an already open database may implicitly cause close() to |
|
803 |
be called, which will cause the driver to unsubscribe from all event notifications. |
|
804 |
||
805 |
When an event notification identified by \a name is posted by the database the |
|
806 |
notification() signal is emitted. |
|
807 |
||
808 |
Reimplement this slot to provide your own QSqlDriver subclass with event notification |
|
809 |
support; because of binary compatibility constraints, the subscribeToNotification() |
|
810 |
function (introduced in Qt 4.4) is not virtual. Instead, subscribeToNotification() |
|
811 |
will dynamically detect and call \e this slot. The default implementation does nothing |
|
812 |
and returns false. |
|
813 |
||
814 |
\since 4.4 |
|
815 |
\sa subscribeToNotification() |
|
816 |
*/ |
|
817 |
bool QSqlDriver::subscribeToNotificationImplementation(const QString &name) |
|
818 |
{ |
|
819 |
Q_UNUSED(name); |
|
820 |
return false; |
|
821 |
} |
|
822 |
||
823 |
/*! |
|
824 |
This slot is called to unsubscribe from event notifications from the database. |
|
825 |
\a name identifies the event notification. |
|
826 |
||
827 |
If successful, return true, otherwise return false. |
|
828 |
||
829 |
The database must be open when \e this slot is called. All subscribed event |
|
830 |
notifications are automatically unsubscribed from when the close() function is called. |
|
831 |
||
832 |
After calling \e this slot the notification() signal will no longer be emitted |
|
833 |
when an event notification identified by \a name is posted by the database. |
|
834 |
||
835 |
Reimplement this slot to provide your own QSqlDriver subclass with event notification |
|
836 |
support; because of binary compatibility constraints, the unsubscribeFromNotification() |
|
837 |
function (introduced in Qt 4.4) is not virtual. Instead, unsubscribeFromNotification() |
|
838 |
will dynamically detect and call \e this slot. The default implementation does nothing |
|
839 |
and returns false. |
|
840 |
||
841 |
\since 4.4 |
|
842 |
\sa unsubscribeFromNotification() |
|
843 |
*/ |
|
844 |
bool QSqlDriver::unsubscribeFromNotificationImplementation(const QString &name) |
|
845 |
{ |
|
846 |
Q_UNUSED(name); |
|
847 |
return false; |
|
848 |
} |
|
849 |
||
850 |
/*! |
|
851 |
Returns a list of the names of the event notifications that are currently subscribed to. |
|
852 |
||
853 |
Reimplement this slot to provide your own QSqlDriver subclass with event notification |
|
854 |
support; because of binary compatibility constraints, the subscribedToNotifications() |
|
855 |
function (introduced in Qt 4.4) is not virtual. Instead, subscribedToNotifications() |
|
856 |
will dynamically detect and call \e this slot. The default implementation simply |
|
857 |
returns an empty QStringList. |
|
858 |
||
859 |
\since 4.4 |
|
860 |
\sa subscribedToNotifications() |
|
861 |
*/ |
|
862 |
QStringList QSqlDriver::subscribedToNotificationsImplementation() const |
|
863 |
{ |
|
864 |
return QStringList(); |
|
865 |
} |
|
866 |
||
867 |
/*! |
|
868 |
\since 4.6 |
|
869 |
||
870 |
This slot returns whether \a identifier is escaped according to the database rules. |
|
871 |
\a identifier can either be a table name or field name, dependent |
|
872 |
on \a type. |
|
873 |
||
874 |
Because of binary compatability constraints, isIdentifierEscaped() function |
|
875 |
(introduced in Qt 4.5) is not virtual. Instead, isIdentifierEscaped() will |
|
876 |
dynamically detect and call \e this slot. The default implementation |
|
877 |
assumes the escape/delimiter character is a double quote. Reimplement this |
|
878 |
slot in your own QSqlDriver if your database engine uses a different |
|
879 |
delimiter character. |
|
880 |
||
881 |
\sa isIdentifierEscaped() |
|
882 |
*/ |
|
883 |
bool QSqlDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const |
|
884 |
{ |
|
885 |
Q_UNUSED(type); |
|
886 |
return identifier.size() > 2 |
|
887 |
&& identifier.startsWith(QLatin1Char('"')) //left delimited |
|
888 |
&& identifier.endsWith(QLatin1Char('"')); //right delimited |
|
889 |
} |
|
890 |
||
891 |
/*! |
|
892 |
\since 4.6 |
|
893 |
||
894 |
This slot returns \a identifier with the leading and trailing delimiters removed, |
|
895 |
\a identifier can either be a tablename or field name, dependent on \a type. |
|
896 |
If \a identifier does not have leading and trailing delimiter characters, \a |
|
897 |
identifier is returned without modification. |
|
898 |
||
899 |
Because of binary compatability constraints, the stripDelimiters() function |
|
900 |
(introduced in Qt 4.5) is not virtual. Instead, stripDelimiters() will |
|
901 |
dynamically detect and call \e this slot. It generally unnecessary |
|
902 |
to reimplement this slot. |
|
903 |
||
904 |
\sa stripDelimiters() |
|
905 |
*/ |
|
906 |
QString QSqlDriver::stripDelimitersImplementation(const QString &identifier, IdentifierType type) const |
|
907 |
{ |
|
908 |
QString ret; |
|
909 |
if (this->isIdentifierEscaped(identifier, type)) { |
|
910 |
ret = identifier.mid(1); |
|
911 |
ret.chop(1); |
|
912 |
} else { |
|
913 |
ret = identifier; |
|
914 |
} |
|
915 |
return ret; |
|
916 |
} |
|
917 |
||
918 |
/*! |
|
919 |
\since 4.6 |
|
920 |
||
921 |
Sets the default numerical precision policy used by queries created |
|
922 |
by this driver to \a precisionPolicy. |
|
923 |
||
924 |
Note: Setting the default precision policy to \a precisionPolicy |
|
925 |
doesn't affect any currently active queries. |
|
926 |
||
927 |
\sa QSql::NumericalPrecisionPolicy, numericalPrecisionPolicy(), |
|
928 |
QSqlQuery::setNumericalPrecisionPolicy(), QSqlQuery::numericalPrecisionPolicy() |
|
929 |
*/ |
|
930 |
void QSqlDriver::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy) |
|
931 |
{ |
|
932 |
d_func()->precisionPolicy = precisionPolicy; |
|
933 |
} |
|
934 |
||
935 |
/*! |
|
936 |
\since 4.6 |
|
937 |
||
938 |
Returns the current default precision policy for the database connection. |
|
939 |
||
940 |
\sa QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy(), |
|
941 |
QSqlQuery::numericalPrecisionPolicy(), QSqlQuery::setNumericalPrecisionPolicy() |
|
942 |
*/ |
|
943 |
QSql::NumericalPrecisionPolicy QSqlDriver::numericalPrecisionPolicy() const |
|
944 |
{ |
|
945 |
return d_func()->precisionPolicy; |
|
946 |
} |
|
947 |
||
948 |
QT_END_NAMESPACE |