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 "qsqldatabase.h"
5#include "qsqlquery.h"
6#include "qloggingcategory.h"
7#include "qcoreapplication.h"
8#include "qreadwritelock.h"
9#include "qsqldriver.h"
10#include "qsqldriver_p.h"
11#include "qsqldriverplugin.h"
12#include "qsqlindex.h"
13#include "QtCore/qapplicationstatic.h"
14#include "private/qfactoryloader_p.h"
15#include "private/qsqlnulldriver_p.h"
16#include "qhash.h"
17#include "qthread.h"
18
19QT_BEGIN_NAMESPACE
20
21static Q_LOGGING_CATEGORY(lcSqlDb, "qt.sql.qsqldatabase")
22
23using namespace Qt::StringLiterals;
24
25#define CHECK_QCOREAPPLICATION \
26 if (Q_UNLIKELY(!QCoreApplication::instance())) { \
27 qCWarning(lcSqlDb, "QSqlDatabase requires a QCoreApplication"); \
28 return; \
29 }
30#define CHECK_QCOREAPPLICATION_RETVAL \
31 if (Q_UNLIKELY(!QCoreApplication::instance())) { \
32 qCWarning(lcSqlDb, "QSqlDatabase requires a QCoreApplication"); \
33 return {}; \
34 }
35
36Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
37 (QSqlDriverFactoryInterface_iid, "/sqldrivers"_L1))
38
39const char *QSqlDatabase::defaultConnection = "qt_sql_default_connection";
40
41namespace {
42 struct QtSqlGlobals
43 {
44 ~QtSqlGlobals();
45 QSqlDatabase connection(const QString &key) const
46 {
47 QReadLocker locker(&lock);
48 return connections.value(key);
49 }
50 bool connectionExists(const QString &key) const
51 {
52 QReadLocker locker(&lock);
53 return connections.contains(key);
54 }
55 QStringList connectionNames() const
56 {
57 QReadLocker locker(&lock);
58 return connections.keys();
59 }
60 mutable QReadWriteLock lock;
61 QHash<QString, QSqlDriverCreatorBase*> registeredDrivers;
62 QHash<QString, QSqlDatabase> connections;
63 };
64}
65Q_APPLICATION_STATIC(QtSqlGlobals, s_sqlGlobals)
66
67class QSqlDatabasePrivate
68{
69public:
70 QSqlDatabasePrivate(QSqlDriver *dr):
71 ref(1),
72 driver(dr),
73 port(-1)
74 {
75 precisionPolicy = QSql::LowPrecisionDouble;
76 }
77 QSqlDatabasePrivate(const QSqlDatabasePrivate &other);
78 ~QSqlDatabasePrivate();
79 void init(const QString& type);
80 void copy(const QSqlDatabasePrivate *other);
81 void disable();
82
83 QAtomicInt ref;
84 QSqlDriver* driver;
85 QString dbname;
86 QString uname;
87 QString pword;
88 QString hname;
89 QString drvName;
90 int port;
91 QString connOptions;
92 QString connName;
93 QSql::NumericalPrecisionPolicy precisionPolicy;
94
95 static QSqlDatabasePrivate *shared_null();
96 static QSqlDatabase database(const QString& name, bool open);
97 static void addDatabase(const QSqlDatabase &db, const QString & name);
98 static void removeDatabase(const QString& name);
99 static void invalidateDb(const QSqlDatabase &db, const QString &name, bool doWarn = true);
100};
101
102QSqlDatabasePrivate::QSqlDatabasePrivate(const QSqlDatabasePrivate &other) : ref(1)
103{
104 dbname = other.dbname;
105 uname = other.uname;
106 pword = other.pword;
107 hname = other.hname;
108 drvName = other.drvName;
109 port = other.port;
110 connOptions = other.connOptions;
111 driver = other.driver;
112 precisionPolicy = other.precisionPolicy;
113 if (driver)
114 driver->setNumericalPrecisionPolicy(other.driver->numericalPrecisionPolicy());
115}
116
117QSqlDatabasePrivate::~QSqlDatabasePrivate()
118{
119 if (driver != shared_null()->driver)
120 delete driver;
121}
122
123QtSqlGlobals::~QtSqlGlobals()
124{
125 qDeleteAll(c: registeredDrivers);
126 for (const auto &[k, v] : std::as_const(t&: connections).asKeyValueRange())
127 QSqlDatabasePrivate::invalidateDb(db: v, name: k, doWarn: false);
128}
129
130QSqlDatabasePrivate *QSqlDatabasePrivate::shared_null()
131{
132 static QSqlNullDriver dr;
133 static QSqlDatabasePrivate n(&dr);
134 return &n;
135}
136
137void QSqlDatabasePrivate::invalidateDb(const QSqlDatabase &db, const QString &name, bool doWarn)
138{
139 if (db.d->ref.loadRelaxed() != 1 && doWarn) {
140 qCWarning(lcSqlDb, "QSqlDatabasePrivate::removeDatabase: connection '%ls' is still in use, "
141 "all queries will cease to work.", qUtf16Printable(name));
142 db.d->disable();
143 db.d->connName.clear();
144 }
145}
146
147void QSqlDatabasePrivate::removeDatabase(const QString &name)
148{
149 CHECK_QCOREAPPLICATION
150 QtSqlGlobals *sqlGlobals = s_sqlGlobals();
151 QWriteLocker locker(&sqlGlobals->lock);
152
153 if (!sqlGlobals->connections.contains(key: name))
154 return;
155
156 invalidateDb(db: sqlGlobals->connections.take(key: name), name);
157}
158
159void QSqlDatabasePrivate::addDatabase(const QSqlDatabase &db, const QString &name)
160{
161 CHECK_QCOREAPPLICATION
162 QtSqlGlobals *sqlGlobals = s_sqlGlobals();
163 QWriteLocker locker(&sqlGlobals->lock);
164
165 if (sqlGlobals->connections.contains(key: name)) {
166 invalidateDb(db: sqlGlobals->connections.take(key: name), name);
167 qCWarning(lcSqlDb, "QSqlDatabasePrivate::addDatabase: duplicate connection name '%ls', old "
168 "connection removed.", qUtf16Printable(name));
169 }
170 sqlGlobals->connections.insert(key: name, value: db);
171 db.d->connName = name;
172}
173
174/*! \internal
175*/
176QSqlDatabase QSqlDatabasePrivate::database(const QString& name, bool open)
177{
178 CHECK_QCOREAPPLICATION_RETVAL
179 QSqlDatabase db = s_sqlGlobals()->connection(key: name);
180 if (!db.isValid())
181 return db;
182 if (db.driver()->thread() != QThread::currentThread()) {
183 qCWarning(lcSqlDb, "QSqlDatabasePrivate::database: requested database does not belong to the calling thread.");
184 return QSqlDatabase();
185 }
186
187 if (open && !db.isOpen()) {
188 if (!db.open())
189 qCWarning(lcSqlDb) << "QSqlDatabasePrivate::database: unable to open database:" << db.lastError().text();
190
191 }
192 return db;
193}
194
195
196/*! \internal
197 Copies the connection data from \a other.
198*/
199void QSqlDatabasePrivate::copy(const QSqlDatabasePrivate *other)
200{
201 dbname = other->dbname;
202 uname = other->uname;
203 pword = other->pword;
204 hname = other->hname;
205 drvName = other->drvName;
206 port = other->port;
207 connOptions = other->connOptions;
208 precisionPolicy = other->precisionPolicy;
209 if (driver)
210 driver->setNumericalPrecisionPolicy(other->driver->numericalPrecisionPolicy());
211}
212
213void QSqlDatabasePrivate::disable()
214{
215 if (driver != shared_null()->driver) {
216 delete driver;
217 driver = shared_null()->driver;
218 }
219}
220
221/*!
222 \class QSqlDriverCreatorBase
223 \brief The QSqlDriverCreatorBase class is the base class for
224 SQL driver factories.
225
226 \ingroup database
227 \inmodule QtSql
228
229 Reimplement createObject() to return an instance of the specific
230 QSqlDriver subclass that you want to provide.
231
232 See QSqlDatabase::registerSqlDriver() for details.
233
234 \sa QSqlDriverCreator
235*/
236
237/*!
238 \fn QSqlDriverCreatorBase::~QSqlDriverCreatorBase()
239
240 Destroys the SQL driver creator object.
241*/
242QSqlDriverCreatorBase::~QSqlDriverCreatorBase()
243 = default;
244
245/*!
246 \fn QSqlDriver *QSqlDriverCreatorBase::createObject() const
247
248 Reimplement this function to returns a new instance of a
249 QSqlDriver subclass.
250*/
251
252/*!
253 \class QSqlDriverCreator
254 \brief The QSqlDriverCreator class is a template class that
255 provides a SQL driver factory for a specific driver type.
256
257 \ingroup database
258 \inmodule QtSql
259
260 QSqlDriverCreator<T> instantiates objects of type T, where T is a
261 QSqlDriver subclass.
262
263 See QSqlDatabase::registerSqlDriver() for details.
264*/
265
266/*!
267 \fn template <class T> QSqlDriver *QSqlDriverCreator<T>::createObject() const
268 \reimp
269*/
270
271/*!
272 \class QSqlDatabase
273 \brief The QSqlDatabase class handles a connection to
274 a database.
275
276 \ingroup database
277
278 \inmodule QtSql
279
280 The QSqlDatabase class provides an interface for accessing a
281 database through a connection. An instance of QSqlDatabase
282 represents the connection. The connection provides access to the
283 database via one of the \l{SQL Database Drivers#Supported
284 Databases} {supported database drivers}, which are derived from
285 QSqlDriver. Alternatively, you can subclass your own database
286 driver from QSqlDriver. See \l{How to Write Your Own Database
287 Driver} for more information.
288 A QSqlDatabase instance must only be accessed by the thread it
289 was created in. Therefore you have to make sure to create them
290 in the correct context. Alternatively you can change the context
291 with QSqlDatabase::moveToThread().
292
293 Create a connection (i.e., an instance of QSqlDatabase) by calling
294 one of the static addDatabase() functions, where you specify
295 \l{SQL Database Drivers#Supported Databases} {the driver or type
296 of driver} to use (depending on the type of database)
297 and a connection name. A connection is known by its own name,
298 \e{not} by the name of the database it connects to. You can have
299 multiple connections to one database. QSqlDatabase also supports
300 the concept of a \e{default} connection, which is the unnamed
301 connection. To create the default connection, don't pass the
302 connection name argument when you call addDatabase().
303 Subsequently, the default connection will be assumed if you call
304 any static member function without specifying the connection name.
305 The following snippet shows how to create and open a default connection
306 to a PostgreSQL database:
307
308 \snippet sqldatabase/sqldatabase.cpp 0
309
310 Once the QSqlDatabase object has been created, set the connection
311 parameters with setDatabaseName(), setUserName(), setPassword(),
312 setHostName(), setPort(), and setConnectOptions(). Then call
313 open() to activate the physical connection to the database. The
314 connection is not usable until you open it.
315
316 The connection defined above will be the \e{default} connection,
317 because we didn't give a connection name to \l{QSqlDatabase::}
318 {addDatabase()}. Subsequently, you can get the default connection
319 by calling database() without the connection name argument:
320
321 \snippet sqldatabase/sqldatabase.cpp 1
322
323 QSqlDatabase is a value class. Changes made to a database
324 connection via one instance of QSqlDatabase will affect other
325 instances of QSqlDatabase that represent the same connection. Use
326 cloneDatabase() to create an independent database connection based
327 on an existing one.
328
329 \warning It is highly recommended that you do not keep a copy of the
330 QSqlDatabase around as a member of a class, as this will prevent the
331 instance from being correctly cleaned up on shutdown. If you need to
332 access an existing QSqlDatabase, it should be accessed with database().
333 If you chose to have a QSqlDatabase member variable, this needs to be
334 deleted before the QCoreApplication instance is deleted, otherwise it
335 may lead to undefined behavior.
336
337 If you create multiple database connections, specify a unique
338 connection name for each one, when you call addDatabase(). Use
339 database() with a connection name to get that connection. Use
340 removeDatabase() with a connection name to remove a connection.
341 QSqlDatabase outputs a warning if you try to remove a connection
342 referenced by other QSqlDatabase objects. Use contains() to see if
343 a given connection name is in the list of connections.
344
345 \table
346 \header
347 \li {2,1}Some utility methods:
348 \row
349 \li tables()
350 \li returns the list of tables
351 \row
352 \li primaryIndex()
353 \li returns a table's primary index
354 \row
355 \li record()
356 \li returns meta-information about a table's fields
357 \row
358 \li transaction()
359 \li starts a transaction
360 \row
361 \li commit()
362 \li saves and completes a transaction
363 \row
364 \li rollback()
365 \li cancels a transaction
366 \row
367 \li hasFeature()
368 \li checks if a driver supports transactions
369 \row
370 \li lastError()
371 \li returns information about the last error
372 \row
373 \li drivers()
374 \li returns the names of the available SQL drivers
375 \row
376 \li isDriverAvailable()
377 \li checks if a particular driver is available
378 \row
379 \li registerSqlDriver()
380 \li registers a custom-made driver
381 \endtable
382
383 \note When using transactions, you must start the
384 transaction before you create your query.
385
386 \sa QSqlDriver, QSqlQuery, {Qt SQL}, {Threads and the SQL Module}
387*/
388
389/*! \fn QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const QString &connectionName)
390 \threadsafe
391
392 Adds a database to the list of database connections using the
393 driver \a type and the connection name \a connectionName. If
394 there already exists a database connection called \a
395 connectionName, that connection is removed.
396
397 The database connection is referred to by \a connectionName. The
398 newly added database connection is returned.
399
400 If \a type is not available or could not be loaded, isValid() returns \c false.
401
402 If \a connectionName is not specified, the new connection becomes
403 the default connection for the application, and subsequent calls
404 to database() without the connection name argument will return the
405 default connection. If a \a connectionName is provided here, use
406 database(\a connectionName) to retrieve the connection.
407
408 \warning If you add a connection with the same name as an existing
409 connection, the new connection replaces the old one. If you call
410 this function more than once without specifying \a connectionName,
411 the default connection will be the one replaced.
412
413 Before using the connection, it must be initialized. e.g., call
414 some or all of setDatabaseName(), setUserName(), setPassword(),
415 setHostName(), setPort(), and setConnectOptions(), and, finally,
416 open().
417
418 \sa database(), removeDatabase(), {Threads and the SQL Module}
419*/
420QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const QString &connectionName)
421{
422 QSqlDatabase db(type);
423 QSqlDatabasePrivate::addDatabase(db, name: connectionName);
424 return db;
425}
426
427/*!
428 \threadsafe
429
430 Returns the database connection called \a connectionName. The
431 database connection must have been previously added with
432 addDatabase(). If \a open is true (the default) and the database
433 connection is not already open it is opened now. If no \a
434 connectionName is specified the default connection is used. If \a
435 connectionName does not exist in the list of databases, an invalid
436 connection is returned.
437
438 \sa isOpen(), {Threads and the SQL Module}
439*/
440
441QSqlDatabase QSqlDatabase::database(const QString& connectionName, bool open)
442{
443 return QSqlDatabasePrivate::database(name: connectionName, open);
444}
445
446/*!
447 \threadsafe
448
449 Removes the database connection \a connectionName from the list of
450 database connections.
451
452 \warning There should be no open queries on the database
453 connection when this function is called, otherwise a resource leak
454 will occur.
455
456 Example:
457
458 \snippet code/src_sql_kernel_qsqldatabase.cpp 0
459
460 The correct way to do it:
461
462 \snippet code/src_sql_kernel_qsqldatabase.cpp 1
463
464 To remove the default connection, which may have been created with a
465 call to addDatabase() not specifying a connection name, you can
466 retrieve the default connection name by calling connectionName() on
467 the database returned by database(). Note that if a default database
468 hasn't been created an invalid database will be returned.
469
470 \sa database(), connectionName(), {Threads and the SQL Module}
471*/
472
473void QSqlDatabase::removeDatabase(const QString& connectionName)
474{
475 QSqlDatabasePrivate::removeDatabase(name: connectionName);
476}
477
478/*!
479 Returns a list of all the available database drivers.
480
481 \sa registerSqlDriver()
482*/
483
484QStringList QSqlDatabase::drivers()
485{
486 CHECK_QCOREAPPLICATION_RETVAL
487 QStringList list;
488
489 if (QFactoryLoader *fl = loader()) {
490 typedef QMultiMap<int, QString> PluginKeyMap;
491
492 const PluginKeyMap keyMap = fl->keyMap();
493 for (const QString &val : keyMap) {
494 if (!list.contains(str: val))
495 list << val;
496 }
497 }
498
499 QtSqlGlobals *sqlGlobals = s_sqlGlobals();
500 QReadLocker locker(&sqlGlobals->lock);
501 const auto &dict = sqlGlobals->registeredDrivers;
502 for (const auto &[k, _] : dict.asKeyValueRange()) {
503 if (!list.contains(str: k))
504 list << k;
505 }
506
507 return list;
508}
509
510/*!
511 This function registers a new SQL driver called \a name, within
512 the SQL framework. This is useful if you have a custom SQL driver
513 and don't want to compile it as a plugin.
514
515 Example:
516 \snippet code/src_sql_kernel_qsqldatabase_snippet.cpp 2
517
518 QSqlDatabase takes ownership of the \a creator pointer, so you
519 mustn't delete it yourself.
520
521 \sa drivers()
522*/
523void QSqlDatabase::registerSqlDriver(const QString& name, QSqlDriverCreatorBase *creator)
524{
525 CHECK_QCOREAPPLICATION
526 QtSqlGlobals *sqlGlobals = s_sqlGlobals();
527 QWriteLocker locker(&sqlGlobals->lock);
528 delete sqlGlobals->registeredDrivers.take(key: name);
529 if (creator)
530 sqlGlobals->registeredDrivers.insert(key: name, value: creator);
531}
532
533/*!
534 \threadsafe
535
536 Returns \c true if the list of database connections contains \a
537 connectionName; otherwise returns \c false.
538
539 \sa connectionNames(), database(), {Threads and the SQL Module}
540*/
541
542bool QSqlDatabase::contains(const QString& connectionName)
543{
544 CHECK_QCOREAPPLICATION_RETVAL
545 return s_sqlGlobals()->connectionExists(key: connectionName);
546}
547
548/*!
549 \threadsafe
550
551 Returns a list containing the names of all connections.
552
553 \sa contains(), database(), {Threads and the SQL Module}
554*/
555QStringList QSqlDatabase::connectionNames()
556{
557 CHECK_QCOREAPPLICATION_RETVAL
558 return s_sqlGlobals()->connectionNames();
559}
560
561/*!
562 \overload
563
564 Creates a QSqlDatabase connection that uses the driver referred
565 to by \a type. If the \a type is not recognized, the database
566 connection will have no functionality.
567
568 The currently available driver types are:
569
570 \table
571 \header \li Driver Type \li Description
572 \row \li QDB2 \li IBM DB2
573 \row \li QIBASE \li Borland InterBase Driver
574 \row \li QMYSQL \li MySQL Driver
575 \row \li QOCI \li Oracle Call Interface Driver
576 \row \li QODBC \li ODBC Driver (includes Microsoft SQL Server)
577 \row \li QPSQL \li PostgreSQL Driver
578 \row \li QSQLITE \li SQLite version 3 or above
579 \row \li QMIMER \li Mimer SQL 11 or above
580 \endtable
581
582 Additional third party drivers, including your own custom
583 drivers, can be loaded dynamically.
584
585 \sa {SQL Database Drivers}, registerSqlDriver(), drivers()
586*/
587
588QSqlDatabase::QSqlDatabase(const QString &type)
589 : d(new QSqlDatabasePrivate(nullptr))
590{
591 d->init(type);
592}
593
594/*!
595 \overload
596
597 Creates a database connection using the given \a driver.
598*/
599
600QSqlDatabase::QSqlDatabase(QSqlDriver *driver)
601 : d(new QSqlDatabasePrivate(driver))
602{
603}
604
605/*!
606 Creates an empty, invalid QSqlDatabase object. Use addDatabase(),
607 removeDatabase(), and database() to get valid QSqlDatabase
608 objects.
609*/
610QSqlDatabase::QSqlDatabase()
611 : d(QSqlDatabasePrivate::shared_null())
612{
613 d->ref.ref();
614}
615
616/*!
617 Creates a copy of \a other.
618*/
619QSqlDatabase::QSqlDatabase(const QSqlDatabase &other)
620{
621 d = other.d;
622 d->ref.ref();
623}
624
625/*!
626 Assigns \a other to this object.
627*/
628QSqlDatabase &QSqlDatabase::operator=(const QSqlDatabase &other)
629{
630 qAtomicAssign(d, x: other.d);
631 return *this;
632}
633
634/*!
635 \internal
636
637 Create the actual driver instance \a type.
638*/
639
640void QSqlDatabasePrivate::init(const QString &type)
641{
642 CHECK_QCOREAPPLICATION
643 drvName = type;
644
645 if (!driver) {
646 QtSqlGlobals *sqlGlobals = s_sqlGlobals();
647 QReadLocker locker(&sqlGlobals->lock);
648 const auto &dict = sqlGlobals->registeredDrivers;
649 auto it = dict.find(key: type);
650 if (it != dict.end())
651 driver = it.value()->createObject();
652 }
653
654 if (!driver && loader())
655 driver = qLoadPlugin<QSqlDriver, QSqlDriverPlugin>(loader: loader(), key: type);
656
657 if (!driver) {
658 qCWarning(lcSqlDb, "QSqlDatabase: %ls driver not loaded", qUtf16Printable(type));
659 qCWarning(lcSqlDb, "QSqlDatabase: available drivers: %ls",
660 qUtf16Printable(QSqlDatabase::drivers().join(u' ')));
661 if (QCoreApplication::instance() == nullptr)
662 qCWarning(lcSqlDb, "QSqlDatabase: an instance of QCoreApplication is required for loading driver plugins");
663 driver = shared_null()->driver;
664 }
665}
666
667/*!
668 Destroys the object and frees any allocated resources.
669
670 \note When the last connection is destroyed, the destructor
671 implicitly calls close() to release the database connection.
672
673 \sa close()
674*/
675
676QSqlDatabase::~QSqlDatabase()
677{
678 if (!d->ref.deref()) {
679 close();
680 delete d;
681 }
682}
683
684/*!
685 Executes a SQL statement on the database and returns a QSqlQuery
686 object. Use lastError() to retrieve error information. If \a
687 query is empty, an empty, invalid query is returned and
688 lastError() is not affected.
689
690 \sa QSqlQuery, lastError()
691 \deprecated [6.6] Use QSqlQuery::exec() instead.
692*/
693#if QT_DEPRECATED_SINCE(6, 6)
694QSqlQuery QSqlDatabase::exec(const QString & query) const
695{
696 QSqlQuery r(d->driver->createResult());
697 if (!query.isEmpty()) {
698 r.exec(query);
699 d->driver->setLastError(r.lastError());
700 }
701 return r;
702}
703#endif
704
705/*!
706 Opens the database connection using the current connection
707 values. Returns \c true on success; otherwise returns \c false. Error
708 information can be retrieved using lastError().
709
710 \sa lastError(), setDatabaseName(), setUserName(), setPassword(),
711 setHostName(), setPort(), setConnectOptions()
712*/
713
714bool QSqlDatabase::open()
715{
716 return d->driver->open(db: d->dbname, user: d->uname, password: d->pword, host: d->hname,
717 port: d->port, connOpts: d->connOptions);
718}
719
720/*!
721 \overload
722
723 Opens the database connection using the given \a user name and \a
724 password. Returns \c true on success; otherwise returns \c false. Error
725 information can be retrieved using the lastError() function.
726
727 This function does not store the password it is given. Instead,
728 the password is passed directly to the driver for opening the
729 connection and it is then discarded.
730
731 \sa lastError()
732*/
733
734bool QSqlDatabase::open(const QString& user, const QString& password)
735{
736 setUserName(user);
737 return d->driver->open(db: d->dbname, user, password, host: d->hname,
738 port: d->port, connOpts: d->connOptions);
739}
740
741/*!
742 Closes the database connection, freeing any resources acquired, and
743 invalidating any existing QSqlQuery objects that are used with the
744 database.
745
746 This will also affect copies of this QSqlDatabase object.
747
748 \sa removeDatabase()
749*/
750
751void QSqlDatabase::close()
752{
753 d->driver->close();
754}
755
756/*!
757 Returns \c true if the database connection is currently open;
758 otherwise returns \c false.
759*/
760
761bool QSqlDatabase::isOpen() const
762{
763 return d->driver->isOpen();
764}
765
766/*!
767 Returns \c true if there was an error opening the database
768 connection; otherwise returns \c false. Error information can be
769 retrieved using the lastError() function.
770*/
771
772bool QSqlDatabase::isOpenError() const
773{
774 return d->driver->isOpenError();
775}
776
777/*!
778 Begins a transaction on the database if the driver supports
779 transactions. Returns \c{true} if the operation succeeded.
780 Otherwise it returns \c{false}.
781
782 \sa QSqlDriver::hasFeature(), commit(), rollback()
783*/
784bool QSqlDatabase::transaction()
785{
786 if (!d->driver->hasFeature(f: QSqlDriver::Transactions))
787 return false;
788 return d->driver->beginTransaction();
789}
790
791/*!
792 Commits a transaction to the database if the driver supports
793 transactions and a transaction() has been started. Returns \c{true}
794 if the operation succeeded. Otherwise it returns \c{false}.
795
796 \note For some databases, the commit will fail and return \c{false}
797 if there is an \l{QSqlQuery::isActive()} {active query} using the
798 database for a \c{SELECT}. Make the query \l{QSqlQuery::isActive()}
799 {inactive} before doing the commit.
800
801 Call lastError() to get information about errors.
802
803 \sa QSqlQuery::isActive(), QSqlDriver::hasFeature(), rollback()
804*/
805bool QSqlDatabase::commit()
806{
807 if (!d->driver->hasFeature(f: QSqlDriver::Transactions))
808 return false;
809 return d->driver->commitTransaction();
810}
811
812/*!
813 Rolls back a transaction on the database, if the driver supports
814 transactions and a transaction() has been started. Returns \c{true}
815 if the operation succeeded. Otherwise it returns \c{false}.
816
817 \note For some databases, the rollback will fail and return
818 \c{false} if there is an \l{QSqlQuery::isActive()} {active query}
819 using the database for a \c{SELECT}. Make the query
820 \l{QSqlQuery::isActive()} {inactive} before doing the rollback.
821
822 Call lastError() to get information about errors.
823
824 \sa QSqlQuery::isActive(), QSqlDriver::hasFeature(), commit()
825*/
826bool QSqlDatabase::rollback()
827{
828 if (!d->driver->hasFeature(f: QSqlDriver::Transactions))
829 return false;
830 return d->driver->rollbackTransaction();
831}
832
833/*!
834 Sets the connection's database name to \a name. To have effect,
835 the database name must be set \e{before} the connection is
836 \l{open()} {opened}. Alternatively, you can close() the
837 connection, set the database name, and call open() again. \note
838 The \e{database name} is not the \e{connection name}. The
839 connection name must be passed to addDatabase() at connection
840 object create time.
841
842 For the QSQLITE driver, if the database name specified does not
843 exist, then it will create the file for you unless the
844 QSQLITE_OPEN_READONLY option is set.
845
846 Additionally, \a name can be set to \c ":memory:" which will
847 create a temporary database which is only available for the
848 lifetime of the application.
849
850 For the QOCI (Oracle) driver, the database name is the TNS
851 Service Name.
852
853 For the QODBC driver, the \a name can either be a DSN, a DSN
854 filename (in which case the file must have a \c .dsn extension),
855 or a connection string.
856
857 For example, Microsoft Access users can use the following
858 connection string to open an \c .mdb file directly, instead of
859 having to create a DSN entry in the ODBC manager:
860
861 \snippet code/src_sql_kernel_qsqldatabase.cpp 3
862
863 There is no default value.
864
865 \sa databaseName(), setUserName(), setPassword(), setHostName(),
866 setPort(), setConnectOptions(), open()
867*/
868
869void QSqlDatabase::setDatabaseName(const QString& name)
870{
871 if (isValid())
872 d->dbname = name;
873}
874
875/*!
876 Sets the connection's user name to \a name. To have effect, the
877 user name must be set \e{before} the connection is \l{open()}
878 {opened}. Alternatively, you can close() the connection, set the
879 user name, and call open() again.
880
881 There is no default value.
882
883 \sa userName(), setDatabaseName(), setPassword(), setHostName(),
884 setPort(), setConnectOptions(), open()
885*/
886
887void QSqlDatabase::setUserName(const QString& name)
888{
889 if (isValid())
890 d->uname = name;
891}
892
893/*!
894 Sets the connection's password to \a password. To have effect, the
895 password must be set \e{before} the connection is \l{open()}
896 {opened}. Alternatively, you can close() the connection, set the
897 password, and call open() again.
898
899 There is no default value.
900
901 \warning This function stores the password in plain text within
902 Qt. Use the open() call that takes a password as parameter to
903 avoid this behavior.
904
905 \sa password(), setUserName(), setDatabaseName(), setHostName(),
906 setPort(), setConnectOptions(), open()
907*/
908
909void QSqlDatabase::setPassword(const QString& password)
910{
911 if (isValid())
912 d->pword = password;
913}
914
915/*!
916 Sets the connection's host name to \a host. To have effect, the
917 host name must be set \e{before} the connection is \l{open()}
918 {opened}. Alternatively, you can close() the connection, set the
919 host name, and call open() again.
920
921 There is no default value.
922
923 \sa hostName(), setUserName(), setPassword(), setDatabaseName(),
924 setPort(), setConnectOptions(), open()
925*/
926
927void QSqlDatabase::setHostName(const QString& host)
928{
929 if (isValid())
930 d->hname = host;
931}
932
933/*!
934 Sets the connection's port number to \a port. To have effect, the
935 port number must be set \e{before} the connection is \l{open()}
936 {opened}. Alternatively, you can close() the connection, set the
937 port number, and call open() again..
938
939 There is no default value.
940
941 \sa port(), setUserName(), setPassword(), setHostName(),
942 setDatabaseName(), setConnectOptions(), open()
943*/
944
945void QSqlDatabase::setPort(int port)
946{
947 if (isValid())
948 d->port = port;
949}
950
951/*!
952 Returns the connection's database name, which may be empty.
953 \note The database name is not the connection name.
954
955 \sa setDatabaseName()
956*/
957QString QSqlDatabase::databaseName() const
958{
959 return d->dbname;
960}
961
962/*!
963 Returns the connection's user name; it may be empty.
964
965 \sa setUserName()
966*/
967QString QSqlDatabase::userName() const
968{
969 return d->uname;
970}
971
972/*!
973 Returns the connection's password. An empty string will be returned
974 if the password was not set with setPassword(), and if the password
975 was given in the open() call, or if no password was used.
976*/
977QString QSqlDatabase::password() const
978{
979 return d->pword;
980}
981
982/*!
983 Returns the connection's host name; it may be empty.
984
985 \sa setHostName()
986*/
987QString QSqlDatabase::hostName() const
988{
989 return d->hname;
990}
991
992/*!
993 Returns the connection's driver name.
994
995 \sa addDatabase(), driver()
996*/
997QString QSqlDatabase::driverName() const
998{
999 return d->drvName;
1000}
1001
1002/*!
1003 Returns the connection's port number. The value is undefined if
1004 the port number has not been set.
1005
1006 \sa setPort()
1007*/
1008int QSqlDatabase::port() const
1009{
1010 return d->port;
1011}
1012
1013/*!
1014 Returns the database driver used to access the database
1015 connection.
1016
1017 \sa addDatabase(), drivers()
1018*/
1019
1020QSqlDriver* QSqlDatabase::driver() const
1021{
1022 return d->driver;
1023}
1024
1025/*!
1026 Returns information about the last error that occurred on the
1027 database.
1028
1029 Failures that occur in conjunction with an individual query are
1030 reported by QSqlQuery::lastError().
1031
1032 \sa QSqlError, QSqlQuery::lastError()
1033*/
1034
1035QSqlError QSqlDatabase::lastError() const
1036{
1037 return d->driver->lastError();
1038}
1039
1040
1041/*!
1042 Returns a list of the database's tables, system tables and views,
1043 as specified by the parameter \a type.
1044
1045 \sa primaryIndex(), record()
1046*/
1047
1048QStringList QSqlDatabase::tables(QSql::TableType type) const
1049{
1050 return d->driver->tables(tableType: type);
1051}
1052
1053/*!
1054 Returns the primary index for table \a tablename. If no primary
1055 index exists, an empty QSqlIndex is returned.
1056
1057 \note Some drivers, such as the \l {QPSQL Case Sensitivity}{QPSQL}
1058 driver, may may require you to pass \a tablename in lower case if
1059 the table was not quoted when created. See the
1060 \l{sql-driver.html}{Qt SQL driver} documentation for more information.
1061
1062 \sa tables(), record()
1063*/
1064
1065QSqlIndex QSqlDatabase::primaryIndex(const QString& tablename) const
1066{
1067 return d->driver->primaryIndex(tableName: tablename);
1068}
1069
1070
1071/*!
1072 Returns a QSqlRecord populated with the names of all the fields in
1073 the table (or view) called \a tablename. The order in which the
1074 fields appear in the record is undefined. If no such table (or
1075 view) exists, an empty record is returned.
1076
1077 \note Some drivers, such as the \l {QPSQL Case Sensitivity}{QPSQL}
1078 driver, may may require you to pass \a tablename in lower case if
1079 the table was not quoted when created. See the
1080 \l{sql-driver.html}{Qt SQL driver} documentation for more information.
1081*/
1082
1083QSqlRecord QSqlDatabase::record(const QString& tablename) const
1084{
1085 return d->driver->record(tableName: tablename);
1086}
1087
1088
1089/*!
1090 Sets database-specific \a options. This must be done before the
1091 connection is opened, otherwise it has no effect. Another possibility
1092 is to close the connection, call QSqlDatabase::setConnectOptions(),
1093 and open() the connection again.
1094
1095 The format of the \a options string is a semicolon separated list
1096 of option names or option=value pairs. The options depend on the
1097 database client used and are described for each plugin in the
1098 \l{sql-driver.html}{SQL Database Drivers} page.
1099
1100 Examples:
1101 \snippet code/src_sql_kernel_qsqldatabase.cpp 4
1102
1103 Refer to the client library documentation for more information
1104 about the different options.
1105
1106 \sa connectOptions()
1107*/
1108
1109void QSqlDatabase::setConnectOptions(const QString &options)
1110{
1111 if (isValid())
1112 d->connOptions = options;
1113}
1114
1115/*!
1116 Returns the connection options string used for this connection.
1117 The string may be empty.
1118
1119 \sa setConnectOptions()
1120 */
1121QString QSqlDatabase::connectOptions() const
1122{
1123 return d->connOptions;
1124}
1125
1126/*!
1127 Returns \c true if a driver called \a name is available; otherwise
1128 returns \c false.
1129
1130 \sa drivers()
1131*/
1132
1133bool QSqlDatabase::isDriverAvailable(const QString& name)
1134{
1135 return drivers().contains(str: name);
1136}
1137
1138/*! \fn QSqlDatabase QSqlDatabase::addDatabase(QSqlDriver* driver, const QString& connectionName)
1139 \overload
1140
1141 This overload is useful when you want to create a database
1142 connection with a \l{QSqlDriver} {driver} you instantiated
1143 yourself. It might be your own database driver, or you might just
1144 need to instantiate one of the Qt drivers yourself. If you do
1145 this, it is recommended that you include the driver code in your
1146 application. For example, you can create a PostgreSQL connection
1147 with your own QPSQL driver like this:
1148
1149 \snippet code/src_sql_kernel_qsqldatabase_snippet.cpp 6
1150
1151 The above code sets up a PostgreSQL connection and instantiates a
1152 QPSQLDriver object. Next, addDatabase() is called to add the
1153 connection to the known connections so that it can be used by the
1154 Qt SQL classes. When a driver is instantiated with a connection
1155 handle (or set of handles), Qt assumes that you have already
1156 opened the database connection.
1157
1158 \note We assume that \c qtdir is the directory where Qt is
1159 installed. This will pull in the code that is needed to use the
1160 PostgreSQL client library and to instantiate a QPSQLDriver object,
1161 assuming that you have the PostgreSQL headers somewhere in your
1162 include search path.
1163
1164 Remember that you must link your application against the database
1165 client library. Make sure the client library is in your linker's
1166 search path, and add lines like these to your \c{.pro} file:
1167
1168 \snippet code/src_sql_kernel_qsqldatabase_snippet.cpp 7
1169
1170 The method described works for all the supplied drivers. The only
1171 difference will be in the driver constructor arguments. Here is a
1172 table of the drivers included with Qt, their source code files,
1173 and their constructor arguments:
1174
1175 \table
1176 \header \li Driver \li Class name \li Constructor arguments \li File to include
1177 \row
1178 \li QPSQL
1179 \li QPSQLDriver
1180 \li PGconn *connection
1181 \li \c qsql_psql.cpp
1182 \row
1183 \li QMYSQL
1184 \li QMYSQLDriver
1185 \li MYSQL *connection
1186 \li \c qsql_mysql.cpp
1187 \row
1188 \li QOCI
1189 \li QOCIDriver
1190 \li OCIEnv *environment, OCISvcCtx *serviceContext
1191 \li \c qsql_oci.cpp
1192 \row
1193 \li QODBC
1194 \li QODBCDriver
1195 \li SQLHANDLE environment, SQLHANDLE connection
1196 \li \c qsql_odbc.cpp
1197 \row
1198 \li QDB2
1199 \li QDB2
1200 \li SQLHANDLE environment, SQLHANDLE connection
1201 \li \c qsql_db2.cpp
1202 \row
1203 \li QSQLITE
1204 \li QSQLiteDriver
1205 \li sqlite *connection
1206 \li \c qsql_sqlite.cpp
1207 \row
1208 \li QMIMER
1209 \li QMimerSQLDriver
1210 \li MimerSession *connection
1211 \li \c qsql_mimer.cpp
1212 \row
1213 \li QIBASE
1214 \li QIBaseDriver
1215 \li isc_db_handle connection
1216 \li \c qsql_ibase.cpp
1217 \endtable
1218
1219 \warning Adding a database connection with the same connection
1220 name as an existing connection, causes the existing connection to
1221 be replaced by the new one.
1222
1223 \warning The SQL framework takes ownership of the \a driver. It
1224 must not be deleted. To remove the connection, use
1225 removeDatabase().
1226
1227 \sa drivers()
1228*/
1229QSqlDatabase QSqlDatabase::addDatabase(QSqlDriver* driver, const QString& connectionName)
1230{
1231 QSqlDatabase db(driver);
1232 QSqlDatabasePrivate::addDatabase(db, name: connectionName);
1233 return db;
1234}
1235
1236/*!
1237 Returns \c true if the QSqlDatabase has a valid driver.
1238
1239 Example:
1240 \snippet code/src_sql_kernel_qsqldatabase.cpp 8
1241*/
1242bool QSqlDatabase::isValid() const
1243{
1244 return d->driver && d->driver != d->shared_null()->driver;
1245}
1246
1247/*!
1248 Clones the database connection \a other and stores it as \a
1249 connectionName. All the settings from the original database, e.g.
1250 databaseName(), hostName(), etc., are copied across. Does nothing
1251 if \a other is an invalid database. Returns the newly created
1252 database connection.
1253
1254 \note The new connection has not been opened. Before using the new
1255 connection, you must call open().
1256
1257 \reentrant
1258*/
1259QSqlDatabase QSqlDatabase::cloneDatabase(const QSqlDatabase &other, const QString &connectionName)
1260{
1261 if (!other.isValid())
1262 return QSqlDatabase();
1263
1264 QSqlDatabase db(other.driverName());
1265 db.d->copy(other: other.d);
1266 QSqlDatabasePrivate::addDatabase(db, name: connectionName);
1267 return db;
1268}
1269
1270/*!
1271 \since 5.13
1272 \overload
1273
1274 Clones the database connection \a other and stores it as \a
1275 connectionName. All the settings from the original database, e.g.
1276 databaseName(), hostName(), etc., are copied across. Does nothing
1277 if \a other is an invalid database. Returns the newly created
1278 database connection.
1279
1280 \note The new connection has not been opened. Before using the new
1281 connection, you must call open().
1282
1283 This overload is useful when cloning the database in another thread to the
1284 one that is used by the database represented by \a other.
1285*/
1286
1287QSqlDatabase QSqlDatabase::cloneDatabase(const QString &other, const QString &connectionName)
1288{
1289 CHECK_QCOREAPPLICATION_RETVAL
1290 return cloneDatabase(other: s_sqlGlobals()->connection(key: other), connectionName);
1291}
1292
1293/*!
1294 Returns the connection name, which may be empty. \note The
1295 connection name is not the \l{databaseName()} {database name}.
1296
1297 \sa addDatabase()
1298*/
1299QString QSqlDatabase::connectionName() const
1300{
1301 return d->connName;
1302}
1303
1304/*!
1305 \property QSqlDatabase::numericalPrecisionPolicy
1306 \since 6.8
1307
1308 This property holds the default numerical precision policy used by
1309 queries created on this database connection.
1310
1311 Note: Drivers that don't support fetching numerical values with low
1312 precision will ignore the precision policy. You can use
1313 QSqlDriver::hasFeature() to find out whether a driver supports this
1314 feature.
1315
1316 Note: Setting the default precision policy to \a precisionPolicy
1317 doesn't affect any currently active queries.
1318
1319 \sa QSql::NumericalPrecisionPolicy, QSqlQuery::numericalPrecisionPolicy,
1320 QSqlDriver::numericalPrecisionPolicy
1321*/
1322/*!
1323 Sets \l numericalPrecisionPolicy to \a precisionPolicy.
1324 */
1325void QSqlDatabase::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
1326{
1327 if (driver())
1328 driver()->setNumericalPrecisionPolicy(precisionPolicy);
1329 d->precisionPolicy = precisionPolicy;
1330}
1331
1332/*!
1333 Returns the \l numericalPrecisionPolicy.
1334*/
1335QSql::NumericalPrecisionPolicy QSqlDatabase::numericalPrecisionPolicy() const
1336{
1337 if (driver())
1338 return driver()->numericalPrecisionPolicy();
1339 else
1340 return d->precisionPolicy;
1341}
1342
1343/*!
1344 \since 6.8
1345
1346 Changes the thread affinity for QSqlDatabase and its associated driver.
1347 This function returns \c true when the function succeeds. Event processing
1348 will continue in the \a targetThread.
1349
1350 During this operation you have to make sure that there is no QSqlQuery
1351 bound to this instance otherwise the QSqlDatabase will not be moved to
1352 the given thread and the function returns \c false.
1353
1354 Since the associated driver is derived from QObject, all constraints for
1355 moving a QObject to another thread also apply to this function.
1356
1357 \sa QObject::moveToThread(), {Threads and the SQL Module}
1358*/
1359bool QSqlDatabase::moveToThread(QThread *targetThread)
1360{
1361 if (auto drv = driver()) {
1362 if (drv != QSqlDatabasePrivate::shared_null()->driver) {
1363 // two instances are alive - the one here and the one in dbDict()
1364 if (d->ref.loadRelaxed() > 2) {
1365 qWarning(msg: "QSqlDatabasePrivate::moveToThread: connection '%ls' is still in use "
1366 "in the current thread.", qUtf16Printable(d->connName));
1367 return false;
1368 }
1369 return drv->moveToThread(thread: targetThread);
1370 }
1371 }
1372 return false;
1373}
1374
1375/*!
1376 \since 6.8
1377
1378 Returns a pointer to the associated QThread instance.
1379*/
1380QThread *QSqlDatabase::thread() const
1381{
1382 if (auto drv = driver())
1383 return drv->thread();
1384 return nullptr;
1385}
1386
1387
1388#ifndef QT_NO_DEBUG_STREAM
1389QDebug operator<<(QDebug dbg, const QSqlDatabase &d)
1390{
1391 QDebugStateSaver saver(dbg);
1392 dbg.nospace();
1393 dbg.noquote();
1394 if (!d.isValid()) {
1395 dbg << "QSqlDatabase(invalid)";
1396 return dbg;
1397 }
1398
1399 dbg << "QSqlDatabase(driver=\"" << d.driverName() << "\", database=\""
1400 << d.databaseName() << "\", host=\"" << d.hostName() << "\", port=" << d.port()
1401 << ", user=\"" << d.userName() << "\", open=" << d.isOpen() << ')';
1402 return dbg;
1403}
1404#endif
1405
1406QT_END_NAMESPACE
1407
1408#include "moc_qsqldatabase.cpp"
1409

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/src/sql/kernel/qsqldatabase.cpp