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