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