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