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