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 "qsqldriver.h" |
41 | |
42 | #include "qdatetime.h" |
43 | #include "qsqlerror.h" |
44 | #include "qsqlfield.h" |
45 | #include "qsqlindex.h" |
46 | #include "private/qobject_p.h" |
47 | #include "private/qsqldriver_p.h" |
48 | |
49 | QT_BEGIN_NAMESPACE |
50 | |
51 | static QString prepareIdentifier(const QString &identifier, |
52 | QSqlDriver::IdentifierType type, const QSqlDriver *driver) |
53 | { |
54 | Q_ASSERT( driver != nullptr ); |
55 | QString ret = identifier; |
56 | if (!driver->isIdentifierEscaped(identifier, type)) { |
57 | ret = driver->escapeIdentifier(identifier, type); |
58 | } |
59 | return ret; |
60 | } |
61 | |
62 | /*! |
63 | \class QSqlDriver |
64 | \brief The QSqlDriver class is an abstract base class for accessing |
65 | specific SQL databases. |
66 | |
67 | \ingroup database |
68 | \inmodule QtSql |
69 | |
70 | This class should not be used directly. Use QSqlDatabase instead. |
71 | |
72 | If you want to create your own SQL drivers, you can subclass this |
73 | class and reimplement its pure virtual functions and those |
74 | virtual functions that you need. See \l{How to Write Your Own |
75 | Database Driver} for more information. |
76 | |
77 | \sa QSqlDatabase, QSqlResult |
78 | */ |
79 | |
80 | /*! |
81 | Constructs a new driver with the given \a parent. |
82 | */ |
83 | |
84 | QSqlDriver::QSqlDriver(QObject *parent) |
85 | : QObject(*new QSqlDriverPrivate, parent) |
86 | { |
87 | } |
88 | |
89 | /*! \internal |
90 | */ |
91 | QSqlDriver::QSqlDriver(QSqlDriverPrivate &dd, QObject *parent) |
92 | : QObject(dd, parent) |
93 | { |
94 | } |
95 | |
96 | /*! |
97 | Destroys the object and frees any allocated resources. |
98 | */ |
99 | |
100 | QSqlDriver::~QSqlDriver() |
101 | { |
102 | } |
103 | |
104 | /*! |
105 | \since 4.4 |
106 | |
107 | \fn QSqlDriver::notification(const QString &name) |
108 | |
109 | This signal is emitted when the database posts an event notification |
110 | that the driver subscribes to. \a name identifies the event notification. |
111 | |
112 | \sa subscribeToNotification() |
113 | |
114 | \obsolete use QSqlDriver::notification(const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload) |
115 | instead |
116 | */ |
117 | |
118 | /*! |
119 | \since 5.0 |
120 | |
121 | \fn QSqlDriver::notification(const QString &name, QSqlDriver::NotificationSource source, const QVariant & payload) |
122 | |
123 | This signal is emitted when the database posts an event notification |
124 | that the driver subscribes to. \a name identifies the event notification, \a source indicates the signal source, |
125 | \a payload holds the extra data optionally delivered with the notification. |
126 | |
127 | \sa subscribeToNotification() |
128 | */ |
129 | |
130 | /*! |
131 | \fn bool QSqlDriver::open(const QString &db, const QString &user, const QString& password, |
132 | const QString &host, int port, const QString &options) |
133 | |
134 | Derived classes must reimplement this pure virtual function to |
135 | open a database connection on database \a db, using user name \a |
136 | user, password \a password, host \a host, port \a port and |
137 | connection options \a options. |
138 | |
139 | The function must return true on success and false on failure. |
140 | |
141 | \sa setOpen() |
142 | */ |
143 | |
144 | /*! |
145 | \fn bool QSqlDriver::close() |
146 | |
147 | Derived classes must reimplement this pure virtual function in |
148 | order to close the database connection. Return true on success, |
149 | false on failure. |
150 | |
151 | \sa open(), setOpen() |
152 | */ |
153 | |
154 | /*! |
155 | \fn QSqlResult *QSqlDriver::createResult() const |
156 | |
157 | Creates an empty SQL result on the database. Derived classes must |
158 | reimplement this function and return a QSqlResult object |
159 | appropriate for their database to the caller. |
160 | */ |
161 | |
162 | /*! |
163 | Returns \c true if the database connection is open; otherwise returns |
164 | false. |
165 | */ |
166 | |
167 | bool QSqlDriver::isOpen() const |
168 | { |
169 | Q_D(const QSqlDriver); |
170 | return d->isOpen; |
171 | } |
172 | |
173 | /*! |
174 | Returns \c true if the there was an error opening the database |
175 | connection; otherwise returns \c false. |
176 | */ |
177 | |
178 | bool QSqlDriver::isOpenError() const |
179 | { |
180 | Q_D(const QSqlDriver); |
181 | return d->isOpenError; |
182 | } |
183 | |
184 | /*! |
185 | \enum QSqlDriver::DriverFeature |
186 | |
187 | This enum contains a list of features a driver might support. Use |
188 | hasFeature() to query whether a feature is supported or not. |
189 | |
190 | \value Transactions Whether the driver supports SQL transactions. |
191 | \value QuerySize Whether the database is capable of reporting the size |
192 | of a query. Note that some databases do not support returning the size |
193 | (i.e. number of rows returned) of a query, in which case |
194 | QSqlQuery::size() will return -1. |
195 | \value BLOB Whether the driver supports Binary Large Object fields. |
196 | \value Unicode Whether the driver supports Unicode strings if the |
197 | database server does. |
198 | \value PreparedQueries Whether the driver supports prepared query execution. |
199 | \value NamedPlaceholders Whether the driver supports the use of named placeholders. |
200 | \value PositionalPlaceholders Whether the driver supports the use of positional placeholders. |
201 | \value LastInsertId Whether the driver supports returning the Id of the last touched row. |
202 | \value BatchOperations Whether the driver supports batched operations, see QSqlQuery::execBatch() |
203 | \value SimpleLocking Whether the driver disallows a write lock on a table while other queries have a read lock on it. |
204 | \value LowPrecisionNumbers Whether the driver allows fetching numerical values with low precision. |
205 | \value EventNotifications Whether the driver supports database event notifications. |
206 | \value FinishQuery Whether the driver can do any low-level resource cleanup when QSqlQuery::finish() is called. |
207 | \value MultipleResultSets Whether the driver can access multiple result sets returned from batched statements or stored procedures. |
208 | \value CancelQuery Whether the driver allows cancelling a running query. |
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 | \enum QSqlDriver::NotificationSource |
242 | |
243 | This enum contains a list of SQL notification sources. |
244 | |
245 | \value UnknownSource The notification source is unknown |
246 | \value SelfSource The notification source is this connection |
247 | \value OtherSource The notification source is another connection |
248 | */ |
249 | |
250 | /*! |
251 | \enum QSqlDriver::DbmsType |
252 | \internal |
253 | |
254 | This enum contains DBMS types. |
255 | |
256 | \value UnknownDbms |
257 | \value MSSqlServer |
258 | \value MySqlServer |
259 | \value PostgreSQL |
260 | \value Oracle |
261 | \value Sybase |
262 | \value SQLite |
263 | \value Interbase |
264 | \value DB2 |
265 | */ |
266 | |
267 | /*! |
268 | \fn bool QSqlDriver::hasFeature(DriverFeature feature) const |
269 | |
270 | Returns \c true if the driver supports feature \a feature; otherwise |
271 | returns \c false. |
272 | |
273 | Note that some databases need to be open() before this can be |
274 | determined. |
275 | |
276 | \sa DriverFeature |
277 | */ |
278 | |
279 | /*! |
280 | This function sets the open state of the database to \a open. |
281 | Derived classes can use this function to report the status of |
282 | open(). |
283 | |
284 | \sa open(), setOpenError() |
285 | */ |
286 | |
287 | void QSqlDriver::setOpen(bool open) |
288 | { |
289 | Q_D(QSqlDriver); |
290 | d->isOpen = open; |
291 | } |
292 | |
293 | /*! |
294 | This function sets the open error state of the database to \a |
295 | error. Derived classes can use this function to report the status |
296 | of open(). Note that if \a error is true the open state of the |
297 | database is set to closed (i.e., isOpen() returns \c false). |
298 | |
299 | \sa open(), setOpen() |
300 | */ |
301 | |
302 | void QSqlDriver::setOpenError(bool error) |
303 | { |
304 | Q_D(QSqlDriver); |
305 | d->isOpenError = error; |
306 | if (error) |
307 | d->isOpen = false; |
308 | } |
309 | |
310 | /*! |
311 | This function is called to begin a transaction. If successful, |
312 | return true, otherwise return false. The default implementation |
313 | does nothing and returns \c false. |
314 | |
315 | \sa commitTransaction(), rollbackTransaction() |
316 | */ |
317 | |
318 | bool QSqlDriver::beginTransaction() |
319 | { |
320 | return false; |
321 | } |
322 | |
323 | /*! |
324 | This function is called to commit a transaction. If successful, |
325 | return true, otherwise return false. The default implementation |
326 | does nothing and returns \c false. |
327 | |
328 | \sa beginTransaction(), rollbackTransaction() |
329 | */ |
330 | |
331 | bool QSqlDriver::commitTransaction() |
332 | { |
333 | return false; |
334 | } |
335 | |
336 | /*! |
337 | This function is called to rollback a transaction. If successful, |
338 | return true, otherwise return false. The default implementation |
339 | does nothing and returns \c false. |
340 | |
341 | \sa beginTransaction(), commitTransaction() |
342 | */ |
343 | |
344 | bool QSqlDriver::rollbackTransaction() |
345 | { |
346 | return false; |
347 | } |
348 | |
349 | /*! |
350 | This function is used to set the value of the last error, \a error, |
351 | that occurred on the database. |
352 | |
353 | \sa lastError() |
354 | */ |
355 | |
356 | void QSqlDriver::setLastError(const QSqlError &error) |
357 | { |
358 | Q_D(QSqlDriver); |
359 | d->error = error; |
360 | } |
361 | |
362 | /*! |
363 | Returns a QSqlError object which contains information about the |
364 | last error that occurred on the database. |
365 | */ |
366 | |
367 | QSqlError QSqlDriver::lastError() const |
368 | { |
369 | Q_D(const QSqlDriver); |
370 | return d->error; |
371 | } |
372 | |
373 | /*! |
374 | Returns a list of the names of the tables in the database. The |
375 | default implementation returns an empty list. |
376 | |
377 | The \a tableType argument describes what types of tables |
378 | should be returned. Due to binary compatibility, the string |
379 | contains the value of the enum QSql::TableTypes as text. |
380 | An empty string should be treated as QSql::Tables for |
381 | backward compatibility. |
382 | */ |
383 | |
384 | QStringList QSqlDriver::tables(QSql::TableType) const |
385 | { |
386 | return QStringList(); |
387 | } |
388 | |
389 | /*! |
390 | Returns the primary index for table \a tableName. Returns an empty |
391 | QSqlIndex if the table doesn't have a primary index. The default |
392 | implementation returns an empty index. |
393 | */ |
394 | |
395 | QSqlIndex QSqlDriver::primaryIndex(const QString&) const |
396 | { |
397 | return QSqlIndex(); |
398 | } |
399 | |
400 | |
401 | /*! |
402 | Returns a QSqlRecord populated with the names of the fields in |
403 | table \a tableName. If no such table exists, an empty record is |
404 | returned. The default implementation returns an empty record. |
405 | */ |
406 | |
407 | QSqlRecord QSqlDriver::record(const QString & /* tableName */) const |
408 | { |
409 | return QSqlRecord(); |
410 | } |
411 | |
412 | /*! |
413 | Returns the \a identifier escaped according to the database rules. |
414 | \a identifier can either be a table name or field name, dependent |
415 | on \a type. |
416 | |
417 | The default implementation does nothing. |
418 | \sa isIdentifierEscaped() |
419 | */ |
420 | QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType) const |
421 | { |
422 | return identifier; |
423 | } |
424 | |
425 | /*! |
426 | Returns whether \a identifier is escaped according to the database rules. |
427 | \a identifier can either be a table name or field name, dependent |
428 | on \a type. |
429 | |
430 | Reimplement this function if you want to provide your own implementation in your |
431 | QSqlDriver subclass, |
432 | |
433 | \sa stripDelimiters(), escapeIdentifier() |
434 | */ |
435 | bool QSqlDriver::isIdentifierEscaped(const QString &identifier, IdentifierType type) const |
436 | { |
437 | Q_UNUSED(type); |
438 | return identifier.size() > 2 |
439 | && identifier.startsWith(c: QLatin1Char('"')) //left delimited |
440 | && identifier.endsWith(c: QLatin1Char('"')); //right delimited |
441 | } |
442 | |
443 | /*! |
444 | Returns the \a identifier with the leading and trailing delimiters removed, |
445 | \a identifier can either be a table name or field name, |
446 | dependent on \a type. If \a identifier does not have leading |
447 | and trailing delimiter characters, \a identifier is returned without |
448 | modification. |
449 | |
450 | Reimplement this function if you want to provide your own implementation in your |
451 | QSqlDriver subclass, |
452 | |
453 | \since 4.5 |
454 | \sa isIdentifierEscaped() |
455 | */ |
456 | QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType type) const |
457 | { |
458 | QString ret; |
459 | if (isIdentifierEscaped(identifier, type)) { |
460 | ret = identifier.mid(position: 1); |
461 | ret.chop(n: 1); |
462 | } else { |
463 | ret = identifier; |
464 | } |
465 | return ret; |
466 | } |
467 | |
468 | /*! |
469 | Returns a SQL statement of type \a type for the table \a tableName |
470 | with the values from \a rec. If \a preparedStatement is true, the |
471 | string will contain placeholders instead of values. |
472 | |
473 | The generated flag in each field of \a rec determines whether the |
474 | field is included in the generated statement. |
475 | |
476 | This method can be used to manipulate tables without having to worry |
477 | about database-dependent SQL dialects. For non-prepared statements, |
478 | the values will be properly escaped. |
479 | |
480 | In the WHERE statement, each non-null field of \a rec specifies a |
481 | filter condition of equality to the field value, or if prepared, a |
482 | placeholder. However, prepared or not, a null field specifies the |
483 | condition IS NULL and never introduces a placeholder. The |
484 | application must not attempt to bind data for the null field during |
485 | execution. The field must be set to some non-null value if a |
486 | placeholder is desired. Furthermore, since non-null fields specify |
487 | equality conditions and SQL NULL is not equal to anything, even |
488 | itself, it is generally not useful to bind a null to a placeholder. |
489 | |
490 | */ |
491 | QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, |
492 | const QSqlRecord &rec, bool preparedStatement) const |
493 | { |
494 | const auto tableNameString = tableName.isEmpty() ? QString() |
495 | : prepareIdentifier(identifier: tableName, type: QSqlDriver::TableName, driver: this); |
496 | int i; |
497 | QString s; |
498 | s.reserve(asize: 128); |
499 | switch (type) { |
500 | case SelectStatement: |
501 | for (i = 0; i < rec.count(); ++i) { |
502 | if (rec.isGenerated(i)) |
503 | s.append(s: prepareIdentifier(identifier: rec.fieldName(i), type: QSqlDriver::FieldName, driver: this)).append(s: QLatin1String(", " )); |
504 | } |
505 | if (s.isEmpty()) |
506 | return s; |
507 | s.chop(n: 2); |
508 | s = QLatin1String("SELECT " ) + s + QLatin1String(" FROM " ) + tableNameString; |
509 | break; |
510 | case WhereStatement: |
511 | { |
512 | const QString tableNamePrefix = tableNameString.isEmpty() |
513 | ? QString() : tableNameString + QLatin1Char('.'); |
514 | for (int i = 0; i < rec.count(); ++i) { |
515 | if (!rec.isGenerated(i)) |
516 | continue; |
517 | s.append(s: s.isEmpty() ? QLatin1String("WHERE " ) : QLatin1String(" AND " )); |
518 | s.append(s: tableNamePrefix); |
519 | s.append(s: prepareIdentifier(identifier: rec.fieldName(i), type: QSqlDriver::FieldName, driver: this)); |
520 | if (rec.isNull(i)) |
521 | s.append(s: QLatin1String(" IS NULL" )); |
522 | else if (preparedStatement) |
523 | s.append(s: QLatin1String(" = ?" )); |
524 | else |
525 | s.append(s: QLatin1String(" = " )).append(s: formatValue(field: rec.field(i))); |
526 | } |
527 | break; |
528 | } |
529 | case UpdateStatement: |
530 | s = s + QLatin1String("UPDATE " ) + tableNameString + QLatin1String(" SET " ); |
531 | for (i = 0; i < rec.count(); ++i) { |
532 | if (!rec.isGenerated(i)) |
533 | continue; |
534 | s.append(s: prepareIdentifier(identifier: rec.fieldName(i), type: QSqlDriver::FieldName, driver: this)).append(c: QLatin1Char('=')); |
535 | if (preparedStatement) |
536 | s.append(c: QLatin1Char('?')); |
537 | else |
538 | s.append(s: formatValue(field: rec.field(i))); |
539 | s.append(s: QLatin1String(", " )); |
540 | } |
541 | if (s.endsWith(s: QLatin1String(", " ))) |
542 | s.chop(n: 2); |
543 | else |
544 | s.clear(); |
545 | break; |
546 | case DeleteStatement: |
547 | s = s + QLatin1String("DELETE FROM " ) + tableNameString; |
548 | break; |
549 | case InsertStatement: { |
550 | s = s + QLatin1String("INSERT INTO " ) + tableNameString + QLatin1String(" (" ); |
551 | QString vals; |
552 | for (i = 0; i < rec.count(); ++i) { |
553 | if (!rec.isGenerated(i)) |
554 | continue; |
555 | s.append(s: prepareIdentifier(identifier: rec.fieldName(i), type: QSqlDriver::FieldName, driver: this)).append(s: QLatin1String(", " )); |
556 | if (preparedStatement) |
557 | vals.append(c: QLatin1Char('?')); |
558 | else |
559 | vals.append(s: formatValue(field: rec.field(i))); |
560 | vals.append(s: QLatin1String(", " )); |
561 | } |
562 | if (vals.isEmpty()) { |
563 | s.clear(); |
564 | } else { |
565 | vals.chop(n: 2); // remove trailing comma |
566 | s[s.length() - 2] = QLatin1Char(')'); |
567 | s.append(s: QLatin1String("VALUES (" )).append(s: vals).append(c: QLatin1Char(')')); |
568 | } |
569 | break; } |
570 | } |
571 | return s; |
572 | } |
573 | |
574 | /*! |
575 | Returns a string representation of the \a field value for the |
576 | database. This is used, for example, when constructing INSERT and |
577 | UPDATE statements. |
578 | |
579 | The default implementation returns the value formatted as a string |
580 | according to the following rules: |
581 | |
582 | \list |
583 | |
584 | \li If \a field is character data, the value is returned enclosed |
585 | in single quotation marks, which is appropriate for many SQL |
586 | databases. Any embedded single-quote characters are escaped |
587 | (replaced with two single-quote characters). If \a trimStrings is |
588 | true (the default is false), all trailing whitespace is trimmed |
589 | from the field. |
590 | |
591 | \li If \a field is date/time data, the value is formatted in ISO |
592 | format and enclosed in single quotation marks. If the date/time |
593 | data is invalid, "NULL" is returned. |
594 | |
595 | \li If \a field is \l{QByteArray}{bytearray} data, and the |
596 | driver can edit binary fields, the value is formatted as a |
597 | hexadecimal string. |
598 | |
599 | \li For any other field type, toString() is called on its value |
600 | and the result of this is returned. |
601 | |
602 | \endlist |
603 | |
604 | \sa QVariant::toString() |
605 | |
606 | */ |
607 | QString QSqlDriver::formatValue(const QSqlField &field, bool trimStrings) const |
608 | { |
609 | const QLatin1String nullTxt("NULL" ); |
610 | |
611 | QString r; |
612 | if (field.isNull()) |
613 | r = nullTxt; |
614 | else { |
615 | switch (+field.type()) { |
616 | case QMetaType::Int: |
617 | case QMetaType::UInt: |
618 | if (field.value().userType() == QMetaType::Bool) |
619 | r = field.value().toBool() ? QLatin1String("1" ) : QLatin1String("0" ); |
620 | else |
621 | r = field.value().toString(); |
622 | break; |
623 | #if QT_CONFIG(datestring) |
624 | case QMetaType::QDate: |
625 | if (field.value().toDate().isValid()) |
626 | r = QLatin1Char('\'') + field.value().toDate().toString(format: Qt::ISODate) |
627 | + QLatin1Char('\''); |
628 | else |
629 | r = nullTxt; |
630 | break; |
631 | case QMetaType::QTime: |
632 | if (field.value().toTime().isValid()) |
633 | r = QLatin1Char('\'') + field.value().toTime().toString(f: Qt::ISODate) |
634 | + QLatin1Char('\''); |
635 | else |
636 | r = nullTxt; |
637 | break; |
638 | case QMetaType::QDateTime: |
639 | if (field.value().toDateTime().isValid()) |
640 | r = QLatin1Char('\'') + |
641 | field.value().toDateTime().toString(format: Qt::ISODate) + QLatin1Char('\''); |
642 | else |
643 | r = nullTxt; |
644 | break; |
645 | #endif |
646 | case QMetaType::QString: |
647 | case QMetaType::QChar: |
648 | { |
649 | QString result = field.value().toString(); |
650 | if (trimStrings) { |
651 | int end = result.length(); |
652 | while (end && result.at(i: end-1).isSpace()) /* skip white space from end */ |
653 | end--; |
654 | result.truncate(pos: end); |
655 | } |
656 | /* escape the "'" character */ |
657 | result.replace(c: QLatin1Char('\''), after: QLatin1String("''" )); |
658 | r = QLatin1Char('\'') + result + QLatin1Char('\''); |
659 | break; |
660 | } |
661 | case QMetaType::Bool: |
662 | r = QString::number(field.value().toBool()); |
663 | break; |
664 | case QMetaType::QByteArray : { |
665 | if (hasFeature(f: BLOB)) { |
666 | QByteArray ba = field.value().toByteArray(); |
667 | QString res; |
668 | static const char hexchars[] = "0123456789abcdef" ; |
669 | for (int i = 0; i < ba.size(); ++i) { |
670 | uchar s = (uchar) ba[i]; |
671 | res += QLatin1Char(hexchars[s >> 4]); |
672 | res += QLatin1Char(hexchars[s & 0x0f]); |
673 | } |
674 | r = QLatin1Char('\'') + res + QLatin1Char('\''); |
675 | break; |
676 | } |
677 | } |
678 | Q_FALLTHROUGH(); |
679 | default: |
680 | r = field.value().toString(); |
681 | break; |
682 | } |
683 | } |
684 | return r; |
685 | } |
686 | |
687 | /*! |
688 | Returns the low-level database handle wrapped in a QVariant or an |
689 | invalid variant if there is no handle. |
690 | |
691 | \warning Use this with uttermost care and only if you know what you're doing. |
692 | |
693 | \warning The handle returned here can become a stale pointer if the connection |
694 | is modified (for example, if you close the connection). |
695 | |
696 | \warning The handle can be NULL if the connection is not open yet. |
697 | |
698 | The handle returned here is database-dependent, you should query the type |
699 | name of the variant before accessing it. |
700 | |
701 | This example retrieves the handle for a connection to sqlite: |
702 | |
703 | \snippet code/src_sql_kernel_qsqldriver.cpp 0 |
704 | |
705 | This snippet returns the handle for PostgreSQL or MySQL: |
706 | |
707 | \snippet code/src_sql_kernel_qsqldriver.cpp 1 |
708 | |
709 | \sa QSqlResult::handle() |
710 | */ |
711 | QVariant QSqlDriver::handle() const |
712 | { |
713 | return QVariant(); |
714 | } |
715 | |
716 | /*! |
717 | This function is called to subscribe to event notifications from the database. |
718 | \a name identifies the event notification. |
719 | |
720 | If successful, return true, otherwise return false. |
721 | |
722 | The database must be open when this function is called. When the database is closed |
723 | by calling close() all subscribed event notifications are automatically unsubscribed. |
724 | Note that calling open() on an already open database may implicitly cause close() to |
725 | be called, which will cause the driver to unsubscribe from all event notifications. |
726 | |
727 | When an event notification identified by \a name is posted by the database the |
728 | notification() signal is emitted. |
729 | |
730 | Reimplement this function if you want to provide event notification support in your |
731 | own QSqlDriver subclass, |
732 | |
733 | \since 4.4 |
734 | \sa unsubscribeFromNotification(), subscribedToNotifications(), QSqlDriver::hasFeature() |
735 | */ |
736 | bool QSqlDriver::subscribeToNotification(const QString &name) |
737 | { |
738 | Q_UNUSED(name); |
739 | return false; |
740 | } |
741 | |
742 | /*! |
743 | This function is called to unsubscribe from event notifications from the database. |
744 | \a name identifies the event notification. |
745 | |
746 | If successful, return true, otherwise return false. |
747 | |
748 | The database must be open when this function is called. All subscribed event |
749 | notifications are automatically unsubscribed from when the close() function is called. |
750 | |
751 | After calling \e this function the notification() signal will no longer be emitted |
752 | when an event notification identified by \a name is posted by the database. |
753 | |
754 | Reimplement this function if you want to provide event notification support in your |
755 | own QSqlDriver subclass, |
756 | |
757 | \since 4.4 |
758 | \sa subscribeToNotification(), subscribedToNotifications() |
759 | */ |
760 | bool QSqlDriver::unsubscribeFromNotification(const QString &name) |
761 | { |
762 | Q_UNUSED(name); |
763 | return false; |
764 | } |
765 | |
766 | /*! |
767 | Returns a list of the names of the event notifications that are currently subscribed to. |
768 | |
769 | Reimplement this function if you want to provide event notification support in your |
770 | own QSqlDriver subclass, |
771 | |
772 | \since 4.4 |
773 | \sa subscribeToNotification(), unsubscribeFromNotification() |
774 | */ |
775 | QStringList QSqlDriver::subscribedToNotifications() const |
776 | { |
777 | return QStringList(); |
778 | } |
779 | |
780 | /*! |
781 | \since 4.6 |
782 | |
783 | Sets the default numerical precision policy used by queries created |
784 | by this driver to \a precisionPolicy. |
785 | |
786 | Note: Setting the default precision policy to \a precisionPolicy |
787 | doesn't affect any currently active queries. |
788 | |
789 | \sa QSql::NumericalPrecisionPolicy, numericalPrecisionPolicy(), |
790 | QSqlQuery::setNumericalPrecisionPolicy(), QSqlQuery::numericalPrecisionPolicy() |
791 | */ |
792 | void QSqlDriver::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy) |
793 | { |
794 | Q_D(QSqlDriver); |
795 | d->precisionPolicy = precisionPolicy; |
796 | } |
797 | |
798 | /*! |
799 | \since 4.6 |
800 | |
801 | Returns the current default precision policy for the database connection. |
802 | |
803 | \sa QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy(), |
804 | QSqlQuery::numericalPrecisionPolicy(), QSqlQuery::setNumericalPrecisionPolicy() |
805 | */ |
806 | QSql::NumericalPrecisionPolicy QSqlDriver::numericalPrecisionPolicy() const |
807 | { |
808 | Q_D(const QSqlDriver); |
809 | return d->precisionPolicy; |
810 | } |
811 | |
812 | /*! |
813 | \since 5.4 |
814 | \internal |
815 | |
816 | Returns the current DBMS type for the database connection. |
817 | */ |
818 | QSqlDriver::DbmsType QSqlDriver::dbmsType() const |
819 | { |
820 | Q_D(const QSqlDriver); |
821 | return d->dbmsType; |
822 | } |
823 | |
824 | /*! |
825 | \since 5.0 |
826 | \internal |
827 | |
828 | Tries to cancel the running query, if the underlying driver has the |
829 | capability to cancel queries. Returns \c true on success, otherwise false. |
830 | |
831 | This function can be called from a different thread. |
832 | |
833 | If you use this function as a slot, you need to use a Qt::DirectConnection |
834 | from a different thread. |
835 | |
836 | Reimplement this function to support canceling running queries in |
837 | your own QSqlDriver subclass. It must be implemented in a thread-safe |
838 | manner. |
839 | |
840 | \sa QSqlDriver::hasFeature() |
841 | */ |
842 | bool QSqlDriver::cancelQuery() |
843 | { |
844 | return false; |
845 | } |
846 | |
847 | QT_END_NAMESPACE |
848 | |