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