summaryrefslogtreecommitdiffstats
path: root/src/sql
diff options
context:
space:
mode:
Diffstat (limited to 'src/sql')
-rw-r--r--src/sql/CMakeLists.txt2
-rw-r--r--src/sql/compat/removed_api.cpp88
-rw-r--r--src/sql/doc/qtsql.qdocconf7
-rw-r--r--src/sql/doc/snippets/CMakeLists.txt2
-rw-r--r--src/sql/doc/snippets/code/CMakeLists.txt2
-rw-r--r--src/sql/doc/snippets/code/doc_src_sql-driver.qdoc2
-rw-r--r--src/sql/doc/snippets/sqldatabase/CMakeLists.txt2
-rw-r--r--src/sql/doc/src/qsqldatatype-table.qdoc105
-rw-r--r--src/sql/doc/src/sql-driver.qdoc31
-rw-r--r--src/sql/doc/src/sql-programming.qdoc4
-rw-r--r--src/sql/kernel/qsqldatabase.cpp258
-rw-r--r--src/sql/kernel/qsqldatabase.h12
-rw-r--r--src/sql/kernel/qsqldriver.cpp30
-rw-r--r--src/sql/kernel/qsqldriver.h5
-rw-r--r--src/sql/kernel/qsqlfield.cpp239
-rw-r--r--src/sql/kernel/qsqlfield.h23
-rw-r--r--src/sql/kernel/qsqlindex.cpp50
-rw-r--r--src/sql/kernel/qsqlindex.h18
-rw-r--r--src/sql/kernel/qsqlquery.cpp119
-rw-r--r--src/sql/kernel/qsqlquery.h17
-rw-r--r--src/sql/kernel/qsqlrecord.cpp116
-rw-r--r--src/sql/kernel/qsqlrecord.h55
-rw-r--r--src/sql/kernel/qsqlresult.cpp52
-rw-r--r--src/sql/kernel/qsqlresult.h13
-rw-r--r--src/sql/kernel/qsqlresult_p.h1
-rw-r--r--src/sql/kernel/qtsqlglobal.h1
-rw-r--r--src/sql/models/qsqlquerymodel.cpp14
-rw-r--r--src/sql/models/qsqlrelationaltablemodel.cpp20
-rw-r--r--src/sql/models/qsqltablemodel.cpp33
-rw-r--r--src/sql/models/qsqltablemodel_p.h6
30 files changed, 853 insertions, 474 deletions
diff --git a/src/sql/CMakeLists.txt b/src/sql/CMakeLists.txt
index a7e139655a..0a51f62c4b 100644
--- a/src/sql/CMakeLists.txt
+++ b/src/sql/CMakeLists.txt
@@ -23,8 +23,10 @@ qt_internal_add_module(Sql
kernel/qtsqlglobal.h kernel/qtsqlglobal_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
+ QT_NO_CONTEXTLESS_CONNECT
QT_NO_FOREACH
QT_NO_USING_NAMESPACE
+ QT_USE_NODISCARD_FILE_OPEN
LIBRARIES
Qt::CorePrivate
PUBLIC_LIBRARIES
diff --git a/src/sql/compat/removed_api.cpp b/src/sql/compat/removed_api.cpp
index ff223b9967..2c2b353a3f 100644
--- a/src/sql/compat/removed_api.cpp
+++ b/src/sql/compat/removed_api.cpp
@@ -9,10 +9,6 @@ QT_USE_NAMESPACE
#if QT_SQL_REMOVED_SINCE(6, 4)
-// #include <qotherheader.h>
-// // implement removed functions from qotherheader.h
-// order sections alphabetically to reduce chances of merge conflicts
-
#endif // QT_SQL_REMOVED_SINCE(6, 4)
#if QT_SQL_REMOVED_SINCE(6, 5)
@@ -36,8 +32,90 @@ void QSqlTableModel::setQuery(const QSqlQuery &query)
#endif // QT_CONFIG(sqlmodel)
+#endif // QT_SQL_REMOVED_SINCE(6, 5)
+
+#if QT_SQL_REMOVED_SINCE(6, 6)
+
+#include "qsqlresult.h"
+#include <QtSql/private/qsqlresult_p.h>
+
// #include <qotherheader.h>
// // implement removed functions from qotherheader.h
// order sections alphabetically to reduce chances of merge conflicts
-#endif // QT_SQL_REMOVED_SINCE(6, 5)
+QList<QVariant> &QSqlResult::boundValues() const
+{
+ Q_D(const QSqlResult);
+ return const_cast<QSqlResultPrivate *>(d)->values;
+}
+
+#endif // QT_SQL_REMOVED_SINCE(6, 6)
+
+#if QT_SQL_REMOVED_SINCE(6, 8)
+
+#include "qsqlrecord.h"
+#include "qsqlfield.h"
+
+// #include <qotherheader.h>
+// // implement removed functions from qotherheader.h
+// order sections alphabetically to reduce chances of merge conflicts
+
+bool QSqlRecord::contains(const QString &name) const
+{
+ return contains(QStringView(name));
+}
+
+QSqlField QSqlRecord::field(const QString &name) const
+{
+ return field(QStringView(name));
+}
+
+int QSqlRecord::indexOf(const QString &name) const
+{
+ return indexOf(QStringView(name));
+}
+
+bool QSqlRecord::isGenerated(const QString &name) const
+{
+ return isGenerated(QStringView(name));
+}
+
+bool QSqlRecord::isNull(const QString &name) const
+{
+ return isNull(QStringView(name));
+}
+
+void QSqlRecord::setGenerated(const QString &name, bool generated)
+{
+ setGenerated(QStringView(name), generated);
+}
+
+void QSqlRecord::setNull(const QString &name)
+{
+ setNull(QStringView(name));
+}
+
+void QSqlRecord::setValue(const QString &name, const QVariant &val)
+{
+ setValue(QStringView(name), val);
+}
+
+QVariant QSqlRecord::value(const QString &name) const
+{
+ return value(QStringView(name));
+}
+
+
+#include "qsqlquery.h"
+
+bool QSqlQuery::isNull(const QString &name) const
+{
+ return isNull(QStringView(name));
+}
+
+QVariant QSqlQuery::value(const QString &name) const
+{
+ return value(QStringView(name));
+}
+
+#endif // QT_SQL_REMOVED_SINCE(6, 8)
diff --git a/src/sql/doc/qtsql.qdocconf b/src/sql/doc/qtsql.qdocconf
index 877411d326..9f6e1a31e0 100644
--- a/src/sql/doc/qtsql.qdocconf
+++ b/src/sql/doc/qtsql.qdocconf
@@ -40,5 +40,10 @@ imagedirs += images \
navigation.landingpage = "Qt SQL"
navigation.cppclassespage = "Qt SQL C++ Classes"
-# Fail the documentation build if there are more warnings than the limit
+# Highlighted examples in Data Processing & IO category
+manifestmeta.highlighted.names = \
+ "QtSql/Master Detail Example" \
+ "QtSql/SQL Browser"
+
+# Enforce zero documentation warnings
warninglimit = 0
diff --git a/src/sql/doc/snippets/CMakeLists.txt b/src/sql/doc/snippets/CMakeLists.txt
index 780ee9261d..a5c34d5688 100644
--- a/src/sql/doc/snippets/CMakeLists.txt
+++ b/src/sql/doc/snippets/CMakeLists.txt
@@ -1,5 +1,5 @@
# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#! [cmake_use]
find_package(Qt6 REQUIRED COMPONENTS Sql)
diff --git a/src/sql/doc/snippets/code/CMakeLists.txt b/src/sql/doc/snippets/code/CMakeLists.txt
index 54ced0e56d..b6899137fe 100644
--- a/src/sql/doc/snippets/code/CMakeLists.txt
+++ b/src/sql/doc/snippets/code/CMakeLists.txt
@@ -1,5 +1,5 @@
# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
add_library(code_snippets OBJECT
doc_src_sql-driver.cpp
diff --git a/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc b/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc
index 9c329aa2a4..896839a1d9 100644
--- a/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc
+++ b/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
//! [0]
[...]
diff --git a/src/sql/doc/snippets/sqldatabase/CMakeLists.txt b/src/sql/doc/snippets/sqldatabase/CMakeLists.txt
index 2028cdac1d..5179c694d0 100644
--- a/src/sql/doc/snippets/sqldatabase/CMakeLists.txt
+++ b/src/sql/doc/snippets/sqldatabase/CMakeLists.txt
@@ -1,5 +1,5 @@
# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
add_library(sqldatabase_snippets OBJECT
sqldatabase.cpp
diff --git a/src/sql/doc/src/qsqldatatype-table.qdoc b/src/sql/doc/src/qsqldatatype-table.qdoc
index 6eabf269c8..77aa56d21a 100644
--- a/src/sql/doc/src/qsqldatatype-table.qdoc
+++ b/src/sql/doc/src/qsqldatatype-table.qdoc
@@ -495,62 +495,80 @@
\li 32-bit signed integer
\li typedef qint32
\row
+ \li INTEGER(n)
+ \li Integer with up to 45 digits precision
+ \li Mapped to QString
+ \row
\li BIGINT
\li 64-bit signed integer
\li typedef qint64
\row
\li REAL
- \li 32-bit Single-precision floating point
- \li typedef qreal
+ \li 32-bit Single-precision IEEE floating point
+ \li typedef float
\row
\li DOUBLE PRECISION
- \li 64-bit Double-precision floating point
+ \li 64-bit Double-precision IEEE floating point
\li Mapped to QString for high precision doubles, otherwise qreal
\row
\li FLOAT
- \li 64-bit Double-precision floating point
- \li typedef qreal
+ \li 64-bit Double-precision IEEE floating point
+ \li Mapped to QString for high precision doubles, otherwise qreal
+ \row
+ \li FLOAT(n)
+ \li Floating point with up to 45 digits precision
+ \li Mapped to QString
+ \row
+ \li DECIMAL(p,s)
+ \li Decimal with up to 45 digits precision and scale
+ \li Mapped to QString
\row
\li CHAR
- \li Fixed-length, null-terminated character string
+ \li Fixed-length character Latin-1 string (CHAR or character)
\li Mapped to QString
\row
\li VARCHAR
- \li Null-terminated varying length string
+ \li Variable length Latin-1 string (VARCHAR or CHARACTER VARYING)
\li Mapped to QString
\row
\li NCHAR
- \li Fixed-length, null-terminated Unicode character string
+ \li Fixed-length Unicode string (NCHAR or NATIONAL CHARACTER)
\li Mapped to QString
\row
\li NVARCHAR
- \li Null-terminated varying length Unicode string
+ \li Variable length Unicode string (NVARCHAR or NATIONAL CHARACTER VARYING)
\li Mapped to QString
\row
+ \li BINARY
+ \li Fixed length binary data
+ \li Mapped to QByteArray
+ \row
+ \li VARBINARY
+ \li Variable length binary data (VARBINARY or BINARY VARYING)
+ \li Mapped to QByteArray
+ \row
\li BLOB
- \li Not null-terminated varying binary string with 4-byte string
- length indicator
+ \li Binary large object (BLOB or BINARY LARGE OBJECT)
\li Mapped to QByteArray
\row
\li CLOB
- \li Character large string object
+ \li Latin-1 character large object (CLOB or CHARACTER LARGE OBJECT)
\li Mapped to QString
\row
\li NCLOB
- \li National Character large string object
+ \li Unicode character large object (NCLOB or NATIONAL CHARACTER LARGE OBJECT)
\li Mapped to QString
\row
\li DATE
- \li Null-terminated character string of the following format:
- yyyy-mm-dd
+ \li Date consisting of year, month, and day
\li Mapped to QDate
\row
\li TIME
- \li Null-terminated character string of the following format: hh.mm.ss
+ \li Time consisting of hours, minute, seconds with optional fractional seconds
\li Mapped to QTime
\row
\li TIMESTAMP
- \li Null-terminated character string of the following format: yyyy-mm-dd-hh.mm.ss.nnnnnn
+ \li Date and time with optional fractional seconds
\li Mapped to QDateTime
\row
\li BUILTIN.UUID
@@ -561,7 +579,56 @@
\li Boolean
\li bool
\row
- \li DECIMAL(p,s)
- \li By default mapping to QString
+ \li INTERVAL YEAR(7)
+ \li Year, format '±yyyyyyy' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL YEAR(7) TO MONTH
+ \li Year to month, format '±yyyyyyy-mm' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL MONTH(7)
+ \li Month, format '±mmmmmmm' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL DAY(7)
+ \li Day, format '±ddddddd' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL DAY(7) TO HOUR
+ \li Day to hour, format '±ddddddd hh' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL DAY(7) TO MINUTE
+ \li Day to minute, format '±ddddddd hh:mm' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL DAY(7) TO SECOND(9)
+ \li Day to second, format '±ddddddd hh:mm:ss[.fffffffff]' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL HOUR(8)
+ \li Hour, format '±hhhhhhhh' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL HOUR(8) TO MINUTE
+ \li Hour to minute, format '±hhhhhhhh:mm' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL HOUR(8) TO SECOND(9)
+ \li Hour to second, format '±hhhhhhhh:mm:ss[.fffffffff]' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL MINUTE(10)
+ \li Minute, format '±mmmmmmmmmm' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL MINUTE(10) TO SECOND(9)
+ \li Minute to second, format '±mmmmmmmmmm:ss[.fffffffff]' (max precision)
+ \li Mapped to QString
+ \row
+ \li INTERVAL SECOND(12,9)
+ \li Second, format '±ssssssssssss[.fffffffff]' (max precision)
+ \li Mapped to QString
\endtable
*/
diff --git a/src/sql/doc/src/sql-driver.qdoc b/src/sql/doc/src/sql-driver.qdoc
index 97af8c620d..4cc5b0d050 100644
--- a/src/sql/doc/src/sql-driver.qdoc
+++ b/src/sql/doc/src/sql-driver.qdoc
@@ -23,7 +23,7 @@
\table
\header \li Driver name \li DBMS
\row \li \l{#QDB2}{QDB2} \li IBM DB2 (version 7.1 and above)
- \row \li \l{#QIBASE} \li Borland InterBase / Firebird
+ \row \li \l{#QIBASE}{QIBASE} \li Borland InterBase / Firebird
\row \li \l{#QMYSQL}{QMYSQL / MARIADB} \li MySQL or MariaDB (version 5.6 and above)
\row \li \l{#QOCI}{QOCI} \li Oracle Call Interface Driver (version 12.1 and above)
\row \li \l{#QODBC}{QODBC}
@@ -404,15 +404,20 @@
of the ODBC driver. ODBC support can be used as a fallback for compliant
databases if no native driver is available.
- On Windows, an ODBC driver manager should be installed by default.
+ On Windows, an ODBC driver manager is installed by default.
For Unix systems, there are some implementations which must be
installed first. Note that every end user of your application is
required to have an ODBC driver manager installed, otherwise the
QODBC plugin will not work.
When connecting to an ODBC datasource, you should pass the name
- of the ODBC datasource to the QSqlDatabase::setDatabaseName()
+ of the ODBC datasource (DSN) to the QSqlDatabase::setDatabaseName()
function, rather than the actual database name.
+ It's also possible to pass a FILEDSN (*.dsn) filename or a complete
+ ODBC driver string. When passing a driver string you must make sure,
+ that all parameters (username, password, ...) are properly escaped.
+ Passing the username or password through the QSqlDatabase functions,
+ the escaping is done by the QODBC plugin.
The QODBC Plugin needs an ODBC compliant driver manager version 2.0 or
later. Some ODBC drivers claim to be version-2.0-compliant,
@@ -723,6 +728,17 @@
\li Busy handler timeout in milliseconds (val <= 0: disabled),
see \l {https://www.sqlite.org/c3ref/busy_timeout.html}
{SQLite documentation} for more information
+
+ \row
+ \li QSQLITE_USE_QT_VFS
+ \li If set, the database is opened using Qt's VFS which allows to
+ open databases using QFile. This way it can open databases from
+ any read-write locations (e.g.android shared storage) but also
+ from read-only resources (e.g. qrc or android assets). Be aware
+ that when opening databases from read-only resources make sure
+ you add QSQLITE_OPEN_READONLY attribute as well.
+ Otherwise it will fail to open it.
+
\row
\li QSQLITE_OPEN_READONLY
\li If set, the database is open in read-only mode which will fail
@@ -745,7 +761,14 @@
\row
\li QSQLITE_NO_USE_EXTENDED_RESULT_CODES
\li Disables the usage of the \l {https://www.sqlite.org/c3ref/extended_result_codes.html}
- {extended result code} feature in SQLite (for backwards compatibility)
+ {extended result code} feature in SQLite
+ \row
+ \li QSQLITE_ENABLE_NON_ASCII_CASE_FOLDING
+ \li If set, the plugin replaces the functions 'lower' and 'upper' with
+ QString functions for correct case folding of non-ascii characters
+ \row
+ \li QSQLITE_OPEN_NOFOLLOW
+ \li If set, the database filename is not allowed to contain a symbolic link
\endtable
\section3 How to Build the QSQLITE Plugin
diff --git a/src/sql/doc/src/sql-programming.qdoc b/src/sql/doc/src/sql-programming.qdoc
index 3dfd005516..a7f87fe73f 100644
--- a/src/sql/doc/src/sql-programming.qdoc
+++ b/src/sql/doc/src/sql-programming.qdoc
@@ -496,11 +496,11 @@
submitted.
The items in the view are rendered using a delegate. The default
- delegate, QItemDelegate, handles the most common data types (\c
+ delegate, QStyledItemDelegate, handles the most common data types (\c
int, QString, QImage, etc.). The delegate is also responsible for
providing editor widgets (e.g., a combobox) when the user starts
editing an item in the view. You can create your own delegates by
- subclassing QAbstractItemDelegate or QItemDelegate. See
+ subclassing QAbstractItemDelegate or QStyledItemDelegate. See
\l{Model/View Programming} for more information.
QSqlTableModel is optimized to operate on a single table at a
diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp
index 4a966dcfa7..e44533291a 100644
--- a/src/sql/kernel/qsqldatabase.cpp
+++ b/src/sql/kernel/qsqldatabase.cpp
@@ -3,10 +3,11 @@
#include "qsqldatabase.h"
#include "qsqlquery.h"
-#include "qdebug.h"
+#include "qloggingcategory.h"
#include "qcoreapplication.h"
#include "qreadwritelock.h"
#include "qsqldriver.h"
+#include "qsqldriver_p.h"
#include "qsqldriverplugin.h"
#include "qsqlindex.h"
#include "QtCore/qapplicationstatic.h"
@@ -17,43 +18,51 @@
QT_BEGIN_NAMESPACE
+Q_STATIC_LOGGING_CATEGORY(lcSqlDb, "qt.sql.qsqldatabase")
+
using namespace Qt::StringLiterals;
+#define CHECK_QCOREAPPLICATION \
+ if (Q_UNLIKELY(!QCoreApplication::instance())) { \
+ qCWarning(lcSqlDb, "QSqlDatabase requires a QCoreApplication"); \
+ return; \
+ }
+#define CHECK_QCOREAPPLICATION_RETVAL \
+ if (Q_UNLIKELY(!QCoreApplication::instance())) { \
+ qCWarning(lcSqlDb, "QSqlDatabase requires a QCoreApplication"); \
+ return {}; \
+ }
+
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QSqlDriverFactoryInterface_iid, "/sqldrivers"_L1))
const char *QSqlDatabase::defaultConnection = "qt_sql_default_connection";
-class QConnectionDict: public QHash<QString, QSqlDatabase>
-{
-public:
- QSqlDatabase value_ts(const QString &key) const
- {
- QReadLocker locker(&lock);
- return value(key);
- }
- bool contains_ts(const QString &key) const
- {
- QReadLocker locker(&lock);
- return contains(key);
- }
- QStringList keys_ts() const
- {
- QReadLocker locker(&lock);
- return keys();
- }
-
- mutable QReadWriteLock lock;
-};
-Q_GLOBAL_STATIC(QConnectionDict, dbDict)
-
namespace {
- struct DriverDict : public QHash<QString, QSqlDriverCreatorBase*>
+ struct QtSqlGlobals
{
- ~DriverDict();
+ ~QtSqlGlobals();
+ QSqlDatabase connection(const QString &key) const
+ {
+ QReadLocker locker(&lock);
+ return connections.value(key);
+ }
+ bool connectionExists(const QString &key) const
+ {
+ QReadLocker locker(&lock);
+ return connections.contains(key);
+ }
+ QStringList connectionNames() const
+ {
+ QReadLocker locker(&lock);
+ return connections.keys();
+ }
+ mutable QReadWriteLock lock;
+ QHash<QString, QSqlDriverCreatorBase*> registeredDrivers;
+ QHash<QString, QSqlDatabase> connections;
};
}
-Q_APPLICATION_STATIC(DriverDict, qtDriverDict)
+Q_APPLICATION_STATIC(QtSqlGlobals, s_sqlGlobals)
class QSqlDatabasePrivate
{
@@ -88,8 +97,6 @@ public:
static void addDatabase(const QSqlDatabase &db, const QString & name);
static void removeDatabase(const QString& name);
static void invalidateDb(const QSqlDatabase &db, const QString &name, bool doWarn = true);
- static DriverDict &driverDict();
- static void cleanConnections();
};
QSqlDatabasePrivate::QSqlDatabasePrivate(const QSqlDatabasePrivate &other) : ref(1)
@@ -113,29 +120,11 @@ QSqlDatabasePrivate::~QSqlDatabasePrivate()
delete driver;
}
-void QSqlDatabasePrivate::cleanConnections()
+QtSqlGlobals::~QtSqlGlobals()
{
- QConnectionDict *dict = dbDict();
- Q_ASSERT(dict);
- QWriteLocker locker(&dict->lock);
-
- QConnectionDict::iterator it = dict->begin();
- while (it != dict->end()) {
- invalidateDb(it.value(), it.key(), false);
- ++it;
- }
- dict->clear();
-}
-
-DriverDict::~DriverDict()
-{
- qDeleteAll(*this);
- QSqlDatabasePrivate::cleanConnections();
-}
-
-DriverDict &QSqlDatabasePrivate::driverDict()
-{
- return *qtDriverDict();
+ qDeleteAll(registeredDrivers);
+ for (const auto &[k, v] : std::as_const(connections).asKeyValueRange())
+ QSqlDatabasePrivate::invalidateDb(v, k, false);
}
QSqlDatabasePrivate *QSqlDatabasePrivate::shared_null()
@@ -148,8 +137,8 @@ QSqlDatabasePrivate *QSqlDatabasePrivate::shared_null()
void QSqlDatabasePrivate::invalidateDb(const QSqlDatabase &db, const QString &name, bool doWarn)
{
if (db.d->ref.loadRelaxed() != 1 && doWarn) {
- qWarning("QSqlDatabasePrivate::removeDatabase: connection '%s' is still in use, "
- "all queries will cease to work.", name.toLocal8Bit().constData());
+ qCWarning(lcSqlDb, "QSqlDatabasePrivate::removeDatabase: connection '%ls' is still in use, "
+ "all queries will cease to work.", qUtf16Printable(name));
db.d->disable();
db.d->connName.clear();
}
@@ -157,28 +146,28 @@ void QSqlDatabasePrivate::invalidateDb(const QSqlDatabase &db, const QString &na
void QSqlDatabasePrivate::removeDatabase(const QString &name)
{
- QConnectionDict *dict = dbDict();
- Q_ASSERT(dict);
- QWriteLocker locker(&dict->lock);
+ CHECK_QCOREAPPLICATION
+ QtSqlGlobals *sqlGlobals = s_sqlGlobals();
+ QWriteLocker locker(&sqlGlobals->lock);
- if (!dict->contains(name))
+ if (!sqlGlobals->connections.contains(name))
return;
- invalidateDb(dict->take(name), name);
+ invalidateDb(sqlGlobals->connections.take(name), name);
}
void QSqlDatabasePrivate::addDatabase(const QSqlDatabase &db, const QString &name)
{
- QConnectionDict *dict = dbDict();
- Q_ASSERT(dict);
- QWriteLocker locker(&dict->lock);
-
- if (dict->contains(name)) {
- invalidateDb(dict->take(name), name);
- qWarning("QSqlDatabasePrivate::addDatabase: duplicate connection name '%s', old "
- "connection removed.", name.toLocal8Bit().data());
+ CHECK_QCOREAPPLICATION
+ QtSqlGlobals *sqlGlobals = s_sqlGlobals();
+ QWriteLocker locker(&sqlGlobals->lock);
+
+ if (sqlGlobals->connections.contains(name)) {
+ invalidateDb(sqlGlobals->connections.take(name), name);
+ qCWarning(lcSqlDb, "QSqlDatabasePrivate::addDatabase: duplicate connection name '%ls', old "
+ "connection removed.", qUtf16Printable(name));
}
- dict->insert(name, db);
+ sqlGlobals->connections.insert(name, db);
db.d->connName = name;
}
@@ -186,20 +175,18 @@ void QSqlDatabasePrivate::addDatabase(const QSqlDatabase &db, const QString &nam
*/
QSqlDatabase QSqlDatabasePrivate::database(const QString& name, bool open)
{
- const QConnectionDict *dict = dbDict();
- Q_ASSERT(dict);
-
- QSqlDatabase db = dict->value_ts(name);
+ CHECK_QCOREAPPLICATION_RETVAL
+ QSqlDatabase db = s_sqlGlobals()->connection(name);
if (!db.isValid())
return db;
if (db.driver()->thread() != QThread::currentThread()) {
- qWarning("QSqlDatabasePrivate::database: requested database does not belong to the calling thread.");
+ qCWarning(lcSqlDb, "QSqlDatabasePrivate::database: requested database does not belong to the calling thread.");
return QSqlDatabase();
}
if (open && !db.isOpen()) {
if (!db.open())
- qWarning() << "QSqlDatabasePrivate::database: unable to open database:" << db.lastError().text();
+ qCWarning(lcSqlDb) << "QSqlDatabasePrivate::database: unable to open database:" << db.lastError().text();
}
return db;
@@ -252,6 +239,8 @@ void QSqlDatabasePrivate::disable()
Destroys the SQL driver creator object.
*/
+QSqlDriverCreatorBase::~QSqlDriverCreatorBase()
+ = default;
/*!
\fn QSqlDriver *QSqlDriverCreatorBase::createObject() const
@@ -296,6 +285,10 @@ void QSqlDatabasePrivate::disable()
QSqlDriver. Alternatively, you can subclass your own database
driver from QSqlDriver. See \l{How to Write Your Own Database
Driver} for more information.
+ A QSqlDatabase instance must only be accessed by the thread it
+ was created in. Therefore you have to make sure to create them
+ in the correct context. Alternatively you can change the context
+ with QSqlDatabase::moveToThread().
Create a connection (i.e., an instance of QSqlDatabase) by calling
one of the static addDatabase() functions, where you specify
@@ -490,6 +483,7 @@ void QSqlDatabase::removeDatabase(const QString& connectionName)
QStringList QSqlDatabase::drivers()
{
+ CHECK_QCOREAPPLICATION_RETVAL
QStringList list;
if (QFactoryLoader *fl = loader()) {
@@ -502,8 +496,9 @@ QStringList QSqlDatabase::drivers()
}
}
- QReadLocker locker(&dbDict()->lock);
- const DriverDict &dict = QSqlDatabasePrivate::driverDict();
+ QtSqlGlobals *sqlGlobals = s_sqlGlobals();
+ QReadLocker locker(&sqlGlobals->lock);
+ const auto &dict = sqlGlobals->registeredDrivers;
for (const auto &[k, _] : dict.asKeyValueRange()) {
if (!list.contains(k))
list << k;
@@ -527,10 +522,12 @@ QStringList QSqlDatabase::drivers()
*/
void QSqlDatabase::registerSqlDriver(const QString& name, QSqlDriverCreatorBase *creator)
{
- QWriteLocker locker(&dbDict()->lock);
- delete QSqlDatabasePrivate::driverDict().take(name);
+ CHECK_QCOREAPPLICATION
+ QtSqlGlobals *sqlGlobals = s_sqlGlobals();
+ QWriteLocker locker(&sqlGlobals->lock);
+ delete sqlGlobals->registeredDrivers.take(name);
if (creator)
- QSqlDatabasePrivate::driverDict().insert(name, creator);
+ sqlGlobals->registeredDrivers.insert(name, creator);
}
/*!
@@ -544,7 +541,8 @@ void QSqlDatabase::registerSqlDriver(const QString& name, QSqlDriverCreatorBase
bool QSqlDatabase::contains(const QString& connectionName)
{
- return dbDict()->contains_ts(connectionName);
+ CHECK_QCOREAPPLICATION_RETVAL
+ return s_sqlGlobals()->connectionExists(connectionName);
}
/*!
@@ -556,7 +554,8 @@ bool QSqlDatabase::contains(const QString& connectionName)
*/
QStringList QSqlDatabase::connectionNames()
{
- return dbDict()->keys_ts();
+ CHECK_QCOREAPPLICATION_RETVAL
+ return s_sqlGlobals()->connectionNames();
}
/*!
@@ -640,28 +639,27 @@ QSqlDatabase &QSqlDatabase::operator=(const QSqlDatabase &other)
void QSqlDatabasePrivate::init(const QString &type)
{
+ CHECK_QCOREAPPLICATION
drvName = type;
if (!driver) {
- QReadLocker locker(&dbDict()->lock);
- const DriverDict &dict = QSqlDatabasePrivate::driverDict();
- for (DriverDict::const_iterator it = dict.constBegin();
- it != dict.constEnd() && !driver; ++it) {
- if (type == it.key()) {
- driver = ((QSqlDriverCreatorBase*)(*it))->createObject();
- }
- }
+ QtSqlGlobals *sqlGlobals = s_sqlGlobals();
+ QReadLocker locker(&sqlGlobals->lock);
+ const auto &dict = sqlGlobals->registeredDrivers;
+ auto it = dict.find(type);
+ if (it != dict.end())
+ driver = it.value()->createObject();
}
if (!driver && loader())
driver = qLoadPlugin<QSqlDriver, QSqlDriverPlugin>(loader(), type);
if (!driver) {
- qWarning("QSqlDatabase: %s driver not loaded", type.toLatin1().data());
- qWarning("QSqlDatabase: available drivers: %s",
- QSqlDatabase::drivers().join(u' ').toLatin1().data());
+ qCWarning(lcSqlDb, "QSqlDatabase: %ls driver not loaded", qUtf16Printable(type));
+ qCWarning(lcSqlDb, "QSqlDatabase: available drivers: %ls",
+ qUtf16Printable(QSqlDatabase::drivers().join(u' ')));
if (QCoreApplication::instance() == nullptr)
- qWarning("QSqlDatabase: an instance of QCoreApplication is required for loading driver plugins");
+ qCWarning(lcSqlDb, "QSqlDatabase: an instance of QCoreApplication is required for loading driver plugins");
driver = shared_null()->driver;
}
}
@@ -1138,6 +1136,7 @@ bool QSqlDatabase::isDriverAvailable(const QString& name)
}
/*! \fn QSqlDatabase QSqlDatabase::addDatabase(QSqlDriver* driver, const QString& connectionName)
+ \overload
This overload is useful when you want to create a database
connection with a \l{QSqlDriver} {driver} you instantiated
@@ -1287,15 +1286,11 @@ QSqlDatabase QSqlDatabase::cloneDatabase(const QSqlDatabase &other, const QStrin
QSqlDatabase QSqlDatabase::cloneDatabase(const QString &other, const QString &connectionName)
{
- const QConnectionDict *dict = dbDict();
- Q_ASSERT(dict);
-
- return cloneDatabase(dict->value_ts(other), connectionName);
+ CHECK_QCOREAPPLICATION_RETVAL
+ return cloneDatabase(s_sqlGlobals()->connection(other), connectionName);
}
/*!
- \since 4.4
-
Returns the connection name, which may be empty. \note The
connection name is not the \l{databaseName()} {database name}.
@@ -1307,10 +1302,11 @@ QString QSqlDatabase::connectionName() const
}
/*!
- \since 4.6
+ \property QSqlDatabase::numericalPrecisionPolicy
+ \since 6.8
- Sets the default numerical precision policy used by queries created
- on this database connection to \a precisionPolicy.
+ This property holds the default numerical precision policy used by
+ queries created on this database connection.
Note: Drivers that don't support fetching numerical values with low
precision will ignore the precision policy. You can use
@@ -1320,9 +1316,12 @@ QString QSqlDatabase::connectionName() const
Note: Setting the default precision policy to \a precisionPolicy
doesn't affect any currently active queries.
- \sa QSql::NumericalPrecisionPolicy, numericalPrecisionPolicy(),
- QSqlQuery::setNumericalPrecisionPolicy(), QSqlQuery::numericalPrecisionPolicy()
+ \sa QSql::NumericalPrecisionPolicy, QSqlQuery::numericalPrecisionPolicy,
+ QSqlDriver::numericalPrecisionPolicy
*/
+/*!
+ Sets \l numericalPrecisionPolicy to \a precisionPolicy.
+ */
void QSqlDatabase::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
{
if (driver())
@@ -1331,12 +1330,7 @@ void QSqlDatabase::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy pr
}
/*!
- \since 4.6
-
- Returns the current default precision policy for the database connection.
-
- \sa QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy(),
- QSqlQuery::numericalPrecisionPolicy(), QSqlQuery::setNumericalPrecisionPolicy()
+ Returns the \l numericalPrecisionPolicy.
*/
QSql::NumericalPrecisionPolicy QSqlDatabase::numericalPrecisionPolicy() const
{
@@ -1346,6 +1340,50 @@ QSql::NumericalPrecisionPolicy QSqlDatabase::numericalPrecisionPolicy() const
return d->precisionPolicy;
}
+/*!
+ \since 6.8
+
+ Changes the thread affinity for QSqlDatabase and its associated driver.
+ This function returns \c true when the function succeeds. Event processing
+ will continue in the \a targetThread.
+
+ During this operation you have to make sure that there is no QSqlQuery
+ bound to this instance otherwise the QSqlDatabase will not be moved to
+ the given thread and the function returns \c false.
+
+ Since the associated driver is derived from QObject, all constraints for
+ moving a QObject to another thread also apply to this function.
+
+ \sa QObject::moveToThread(), {Threads and the SQL Module}
+*/
+bool QSqlDatabase::moveToThread(QThread *targetThread)
+{
+ if (auto drv = driver()) {
+ if (drv != QSqlDatabasePrivate::shared_null()->driver) {
+ // two instances are alive - the one here and the one in dbDict()
+ if (d->ref.loadRelaxed() > 2) {
+ qWarning("QSqlDatabasePrivate::moveToThread: connection '%ls' is still in use "
+ "in the current thread.", qUtf16Printable(d->connName));
+ return false;
+ }
+ return drv->moveToThread(targetThread);
+ }
+ }
+ return false;
+}
+
+/*!
+ \since 6.8
+
+ Returns a pointer to the associated QThread instance.
+*/
+QThread *QSqlDatabase::thread() const
+{
+ if (auto drv = driver())
+ return drv->thread();
+ return nullptr;
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QSqlDatabase &d)
@@ -1366,3 +1404,5 @@ QDebug operator<<(QDebug dbg, const QSqlDatabase &d)
#endif
QT_END_NAMESPACE
+
+#include "moc_qsqldatabase.cpp"
diff --git a/src/sql/kernel/qsqldatabase.h b/src/sql/kernel/qsqldatabase.h
index 1fb1eb3966..85d6b4d9d9 100644
--- a/src/sql/kernel/qsqldatabase.h
+++ b/src/sql/kernel/qsqldatabase.h
@@ -5,8 +5,10 @@
#define QSQLDATABASE_H
#include <QtSql/qtsqlglobal.h>
+#include <QtCore/qmetaobject.h>
#include <QtCore/qstring.h>
+// clazy:excludeall=qproperty-without-notify
QT_BEGIN_NAMESPACE
@@ -16,11 +18,12 @@ class QSqlIndex;
class QSqlRecord;
class QSqlQuery;
class QSqlDatabasePrivate;
+class QThread;
class Q_SQL_EXPORT QSqlDriverCreatorBase
{
public:
- virtual ~QSqlDriverCreatorBase() {}
+ virtual ~QSqlDriverCreatorBase();
virtual QSqlDriver *createObject() const = 0;
};
@@ -33,7 +36,10 @@ public:
class Q_SQL_EXPORT QSqlDatabase
{
+ Q_GADGET
public:
+ Q_PROPERTY(QSql::NumericalPrecisionPolicy numericalPrecisionPolicy READ numericalPrecisionPolicy WRITE setNumericalPrecisionPolicy)
+
QSqlDatabase();
QSqlDatabase(const QSqlDatabase &other);
~QSqlDatabase();
@@ -49,7 +55,7 @@ public:
QSqlIndex primaryIndex(const QString& tablename) const;
QSqlRecord record(const QString& tablename) const;
#if QT_DEPRECATED_SINCE(6, 6)
- QT_DEPRECATED_VERSION_X_6_6("QSqlQuery::exec() instead.")
+ QT_DEPRECATED_VERSION_X_6_6("Use QSqlQuery::exec() instead.")
QSqlQuery exec(const QString& query = QString()) const;
#endif
QSqlError lastError() const;
@@ -75,6 +81,8 @@ public:
QString connectionName() const;
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy);
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
+ bool moveToThread(QThread *targetThread);
+ QThread *thread() const;
QSqlDriver* driver() const;
diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp
index f629d8a941..c0cb0374a9 100644
--- a/src/sql/kernel/qsqldriver.cpp
+++ b/src/sql/kernel/qsqldriver.cpp
@@ -215,7 +215,7 @@ bool QSqlDriver::isOpenError() const
\value SQLite
\value Interbase
\value DB2
- \value MimerSQL
+ \value [since 6.6] MimerSQL
*/
/*!
@@ -404,7 +404,6 @@ bool QSqlDriver::isIdentifierEscaped(const QString &identifier, IdentifierType t
Reimplement this function if you want to provide your own implementation in your
QSqlDriver subclass,
- \since 4.5
\sa isIdentifierEscaped()
*/
QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType type) const
@@ -680,7 +679,6 @@ QVariant QSqlDriver::handle() const
Reimplement this function if you want to provide event notification support in your
own QSqlDriver subclass,
- \since 4.4
\sa unsubscribeFromNotification(), subscribedToNotifications(), QSqlDriver::hasFeature()
*/
bool QSqlDriver::subscribeToNotification(const QString &name)
@@ -704,7 +702,6 @@ bool QSqlDriver::subscribeToNotification(const QString &name)
Reimplement this function if you want to provide event notification support in your
own QSqlDriver subclass,
- \since 4.4
\sa subscribeToNotification(), subscribedToNotifications()
*/
bool QSqlDriver::unsubscribeFromNotification(const QString &name)
@@ -719,7 +716,6 @@ bool QSqlDriver::unsubscribeFromNotification(const QString &name)
Reimplement this function if you want to provide event notification support in your
own QSqlDriver subclass,
- \since 4.4
\sa subscribeToNotification(), unsubscribeFromNotification()
*/
QStringList QSqlDriver::subscribedToNotifications() const
@@ -728,16 +724,7 @@ QStringList QSqlDriver::subscribedToNotifications() const
}
/*!
- \since 4.6
-
- Sets the default numerical precision policy used by queries created
- by this driver to \a precisionPolicy.
-
- Note: Setting the default precision policy to \a precisionPolicy
- doesn't affect any currently active queries.
-
- \sa QSql::NumericalPrecisionPolicy, numericalPrecisionPolicy(),
- QSqlQuery::setNumericalPrecisionPolicy(), QSqlQuery::numericalPrecisionPolicy()
+ Sets \l numericalPrecisionPolicy to \a precisionPolicy.
*/
void QSqlDriver::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
{
@@ -746,12 +733,17 @@ void QSqlDriver::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy prec
}
/*!
- \since 4.6
+ \property QSqlDriver::numericalPrecisionPolicy
+ \since 6.8
- Returns the current default precision policy for the database connection.
+ This property holds the precision policy for the database connection.
+ \note Setting the precision policy doesn't affect any currently active queries.
- \sa QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy(),
- QSqlQuery::numericalPrecisionPolicy(), QSqlQuery::setNumericalPrecisionPolicy()
+ \sa QSql::NumericalPrecisionPolicy, QSqlQuery::numericalPrecisionPolicy,
+ QSqlDatabase::numericalPrecisionPolicy
+*/
+/*!
+ Returns the \l numericalPrecisionPolicy.
*/
QSql::NumericalPrecisionPolicy QSqlDriver::numericalPrecisionPolicy() const
{
diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h
index 58ced82c47..a5fe40fa15 100644
--- a/src/sql/kernel/qsqldriver.h
+++ b/src/sql/kernel/qsqldriver.h
@@ -9,6 +9,7 @@
#include <QtCore/qstring.h>
#include <QtCore/qstringlist.h>
+// clazy:excludeall=qproperty-without-notify
QT_BEGIN_NAMESPACE
@@ -51,9 +52,11 @@ public:
SQLite,
Interbase,
DB2,
- MimerSQL
+ MimerSQL,
};
+ Q_PROPERTY(QSql::NumericalPrecisionPolicy numericalPrecisionPolicy READ numericalPrecisionPolicy WRITE setNumericalPrecisionPolicy)
+
explicit QSqlDriver(QObject *parent = nullptr);
~QSqlDriver();
virtual bool isOpen() const;
diff --git a/src/sql/kernel/qsqlfield.cpp b/src/sql/kernel/qsqlfield.cpp
index 9fdb24f330..0bd0ca5161 100644
--- a/src/sql/kernel/qsqlfield.cpp
+++ b/src/sql/kernel/qsqlfield.cpp
@@ -99,7 +99,7 @@ QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QSqlFieldPrivate)
\value Unknown The database driver couldn't determine whether the field is required or
optional.
- \sa requiredStatus()
+ \sa requiredStatus
*/
/*!
@@ -109,9 +109,14 @@ QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QSqlFieldPrivate)
Constructs an empty field called \a fieldName of variant type \a
type in \a table.
+*/
+
+/*!
+ \fn void QSqlField::swap(QSqlField &other)
+ \since 6.6
- \sa setRequiredStatus(), setLength(), setPrecision(), setDefaultValue(),
- setGenerated(), setReadOnly()
+ Swaps this field with \a other. This function is very fast and
+ never fails.
*/
/*!
@@ -120,9 +125,6 @@ QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QSqlFieldPrivate)
\overload
Constructs an empty field called \a fieldName of type \a
type in \a table.
-
- \sa setRequiredStatus(), setLength(), setPrecision(), setDefaultValue(),
- setGenerated(), setReadOnly()
*/
QSqlField::QSqlField(const QString &fieldName, QMetaType type, const QString &table)
: val(QVariant(type, nullptr)),
@@ -167,10 +169,7 @@ QSqlField::~QSqlField()
= default;
/*!
- Sets the required status of this field to \a required.
-
- \sa requiredStatus(), setMetaType(), setLength(), setPrecision(),
- setDefaultValue(), setGenerated(), setReadOnly()
+ Sets \l requiredStatus to \a required.
*/
void QSqlField::setRequiredStatus(RequiredStatus required)
{
@@ -183,16 +182,11 @@ void QSqlField::setRequiredStatus(RequiredStatus required)
Sets the required status of this field to \l Required if \a
required is true; otherwise sets it to \l Optional.
- \sa setRequiredStatus(), requiredStatus()
+ \sa requiredStatus
*/
/*!
- Sets the field's length to \a fieldLength. For strings this is the
- maximum number of characters the string can hold; the meaning
- varies for other types.
-
- \sa length(), setMetaType(), setRequiredStatus(), setPrecision(),
- setDefaultValue(), setGenerated(), setReadOnly()
+ Sets \l length to \a fieldLength.
*/
void QSqlField::setLength(int fieldLength)
{
@@ -201,10 +195,7 @@ void QSqlField::setLength(int fieldLength)
}
/*!
- Sets the field's \a precision. This only affects numeric fields.
-
- \sa precision(), setMetaType(), setRequiredStatus(), setLength(),
- setDefaultValue(), setGenerated(), setReadOnly()
+ Sets \l precision to \a precision.
*/
void QSqlField::setPrecision(int precision)
{
@@ -213,10 +204,16 @@ void QSqlField::setPrecision(int precision)
}
/*!
- Sets the default value used for this field to \a value.
+ \property QSqlField::defaultValue
+ \since 6.8
+
+ This property holds the default value for this field.
+ Only some database drivers supports this property. Currently
+ those are SQLite, PostgreSQL, Oracle and MySQL/MariaDB.
+*/
- \sa defaultValue(), value(), setMetaType(), setRequiredStatus(),
- setLength(), setPrecision(), setGenerated(), setReadOnly()
+/*!
+ Sets \l defaultValue to \a value.
*/
void QSqlField::setDefaultValue(const QVariant &value)
{
@@ -224,23 +221,20 @@ void QSqlField::setDefaultValue(const QVariant &value)
d->def = value;
}
+#if QT_DEPRECATED_SINCE(6, 8)
/*!
\internal
+ \deprecated [6.8] This internal value is no longer used.
*/
void QSqlField::setSqlType(int type)
{
detach();
d->tp = type;
}
+#endif
/*!
- Sets the generated state. If \a gen is false, no SQL will
- be generated for this field; otherwise, Qt classes such as
- QSqlQueryModel and QSqlTableModel will generate SQL for this
- field.
-
- \sa isGenerated(), setMetaType(), setRequiredStatus(), setLength(),
- setPrecision(), setDefaultValue(), setReadOnly()
+ Sets \l generated to \a gen.
*/
void QSqlField::setGenerated(bool gen)
{
@@ -250,19 +244,28 @@ void QSqlField::setGenerated(bool gen)
/*!
- Sets the value of the field to \a value. If the field is read-only
- (isReadOnly() returns \c true), nothing happens.
+ \property QSqlField::value
+ \since 6.8
+ This property holds the \a value as a QVariant
+
+ Setting a \a value to a read-only QSqlField is a no-op.
If the data type of \a value differs from the field's current
data type, an attempt is made to cast it to the proper type. This
preserves the data type of the field in the case of assignment,
e.g. a QString to an integer data type.
To set the value to NULL, use clear().
-
- \sa value(), isReadOnly(), defaultValue()
*/
+/*!
+ \fn QVariant QSqlField::value() const
+
+ Returns the value of \l value.
+*/
+/*!
+ Sets \l value to \a value.
+*/
void QSqlField::setValue(const QVariant& value)
{
if (isReadOnly())
@@ -273,8 +276,6 @@ void QSqlField::setValue(const QVariant& value)
/*!
Clears the value of the field and sets it to NULL.
If the field is read-only, nothing happens.
-
- \sa setValue(), isReadOnly(), requiredStatus()
*/
void QSqlField::clear()
@@ -284,12 +285,10 @@ void QSqlField::clear()
val = QVariant(d->type, nullptr);
}
-/*!
- Sets the name of the field to \a name.
- \sa name()
+/*!
+ Sets \l name to \a name.
*/
-
void QSqlField::setName(const QString& name)
{
detach();
@@ -297,9 +296,7 @@ void QSqlField::setName(const QString& name)
}
/*!
- Sets the read only flag of the field's value to \a readOnly. A
- read-only field cannot have its value set with setValue() and
- cannot be cleared to NULL with clear().
+ Sets \l readOnly to \a readOnly.
*/
void QSqlField::setReadOnly(bool readOnly)
{
@@ -308,17 +305,14 @@ void QSqlField::setReadOnly(bool readOnly)
}
/*!
- \fn QVariant QSqlField::value() const
-
- Returns the value of the field as a QVariant.
+ \property QSqlField::name
- Use isNull() to check if the field's value is NULL.
+ This property holds the name of the field.
+ This can be the column name or a user given alias.
*/
/*!
- Returns the name of the field.
-
- \sa setName()
+ Returns the value of \l name.
*/
QString QSqlField::name() const
{
@@ -326,13 +320,20 @@ QString QSqlField::name() const
}
/*!
- Returns the field's type as stored in the database.
+ \property QSqlField::metaType
+ \since 6.8
+
+ This property holds the field's type as stored in the database.
Note that the actual value might have a different type,
Numerical values that are too large to store in a long
int or double are usually stored as strings to prevent
precision loss.
- \sa setMetaType()
+ \sa QSqlDatabase::numericalPrecisionPolicy
+*/
+
+/*!
+ Returns the value of \l metaType.
*/
QMetaType QSqlField::metaType() const
{
@@ -340,10 +341,7 @@ QMetaType QSqlField::metaType() const
}
/*!
- Set's the field's variant type to \a type.
-
- \sa metaType(), setRequiredStatus(), setLength(), setPrecision(),
- setDefaultValue(), setGenerated(), setReadOnly()
+ Sets \l metaType to \a type.
*/
void QSqlField::setMetaType(QMetaType type)
{
@@ -363,7 +361,7 @@ void QSqlField::setMetaType(QMetaType type)
int or double are usually stored as strings to prevent
precision loss.
- \sa metaType()
+ \sa metaType
*/
/*!
@@ -372,27 +370,36 @@ void QSqlField::setMetaType(QMetaType type)
Sets the field's variant type to \a type.
- \sa setMetaType()
+ \sa metaType
*/
/*!
- Returns \c true if the field's value is read-only; otherwise returns
- false.
+ \property QSqlField::readOnly
+ \since 6.8
+
+ When this property is \c true then this QSqlField cannot be modified.
+ A read-only field cannot have its value set with setValue() and
+ cannot be cleared to NULL with clear().
+*/
- \sa setReadOnly(), metaType(), requiredStatus(), length(), precision(),
- defaultValue(), isGenerated()
+/*!
+ Returns the value of \l readOnly.
*/
bool QSqlField::isReadOnly() const
-{ return d->ro; }
+{
+ return d->ro;
+}
/*!
Returns \c true if the field's value is NULL; otherwise returns
false.
- \sa value()
+ \sa value
*/
bool QSqlField::isNull() const
-{ return val.isNull(); }
+{
+ return val.isNull();
+}
/*! \internal
*/
@@ -402,11 +409,17 @@ void QSqlField::detach()
}
/*!
- Returns \c true if this is a required field; otherwise returns \c false.
+ \property QSqlField::requiredStatus
+ \since 6.8
+
+ This property holds the RequiredStatus of the field.
An \c INSERT will fail if a required field does not have a value.
- \sa setRequiredStatus(), metaType(), length(), precision(), defaultValue(),
- isGenerated()
+ \sa RequiredStatus
+*/
+
+/*!
+ Returns the value of \l requiredStatus.
*/
QSqlField::RequiredStatus QSqlField::requiredStatus() const
{
@@ -414,13 +427,19 @@ QSqlField::RequiredStatus QSqlField::requiredStatus() const
}
/*!
- Returns the field's length.
+ \property QSqlField::length
+ \since 6.8
- If the returned value is negative, it means that the information
+ This property holds the field's length.
+
+ If the value is negative, it means that the information
is not available from the database.
+ For strings this is the maximum number of characters the string
+ can hold; the meaning varies for other types.
+*/
- \sa setLength(), metaType(), requiredStatus(), precision(), defaultValue(),
- isGenerated()
+/*!
+ Returns the value of \l length.
*/
int QSqlField::length() const
{
@@ -428,14 +447,17 @@ int QSqlField::length() const
}
/*!
- Returns the field's precision; this is only meaningful for numeric
- types.
+ \property QSqlField::precision
+ \since 6.8
+
+ This property holds the field's precision; this is only meaningful
+ for numeric types.
If the returned value is negative, it means that the information
is not available from the database.
-
- \sa setPrecision(), metaType(), requiredStatus(), length(), defaultValue(),
- isGenerated()
+*/
+/*!
+ Returns the value of \l precision.
*/
int QSqlField::precision() const
{
@@ -443,18 +465,17 @@ int QSqlField::precision() const
}
/*!
- Returns the field's default value (which may be NULL).
-
- \sa setDefaultValue(), metaType(), requiredStatus(), length(), precision(),
- isGenerated()
+ Sets the value of \l defaultValue.
*/
QVariant QSqlField::defaultValue() const
{
return d->def;
}
+#if QT_DEPRECATED_SINCE(6, 8)
/*!
\internal
+ \deprecated [6.8] This internal value is no longer used.
Returns the type ID for the field.
@@ -465,13 +486,19 @@ int QSqlField::typeID() const
{
return d->tp;
}
+#endif
/*!
- Returns \c true if the field is generated; otherwise returns
- false.
+ \property QSqlField::generated
+ \since 6.8
- \sa setGenerated(), metaType(), requiredStatus(), length(), precision(),
- defaultValue()
+ This property holds the generated state. If \a generated is \c false,
+ no SQL will be generated for this field; otherwise, Qt classes such as
+ QSqlQueryModel and QSqlTableModel will generate SQL for this field.
+*/
+
+/*!
+ Returns the value of \l generated.
*/
bool QSqlField::isGenerated() const
{
@@ -502,8 +529,6 @@ QDebug operator<<(QDebug dbg, const QSqlField &f)
dbg << ", required: "
<< (f.requiredStatus() == QSqlField::Required ? "yes" : "no");
dbg << ", generated: " << (f.isGenerated() ? "yes" : "no");
- if (f.typeID() >= 0)
- dbg << ", typeID: " << f.typeID();
if (!f.defaultValue().isNull())
dbg << ", defaultValue: \"" << f.defaultValue() << '\"';
dbg << ", autoValue: " << f.isAutoValue()
@@ -513,16 +538,21 @@ QDebug operator<<(QDebug dbg, const QSqlField &f)
#endif
/*!
- Returns \c true if the value is auto-generated by the database,
- for example auto-increment primary key values.
+ \property QSqlField::autoValue
+ \since 6.8
+
+ If the value is auto-generated by the database,
+ for example auto-increment primary key values, this value is \c true.
\note When using the ODBC driver, due to limitations in the ODBC API,
the \c isAutoValue() field is only populated in a QSqlField resulting from a
QSqlRecord obtained by executing a \c SELECT query. It is \c false in a QSqlField
resulting from a QSqlRecord returned from QSqlDatabase::record() or
QSqlDatabase::primaryIndex().
+*/
- \sa setAutoValue()
+/*!
+ Returns the value of \l autoValue.
*/
bool QSqlField::isAutoValue() const
{
@@ -530,11 +560,8 @@ bool QSqlField::isAutoValue() const
}
/*!
- Marks the field as an auto-generated value if \a autoVal
- is true.
-
- \sa isAutoValue()
- */
+ Sets \l autoValue to \a autoVal.
+*/
void QSqlField::setAutoValue(bool autoVal)
{
detach();
@@ -542,24 +569,26 @@ void QSqlField::setAutoValue(bool autoVal)
}
/*!
- Sets the tableName of the field to \a table.
-
- \sa tableName()
+ Sets \l tableName to \a tableName.
*/
-void QSqlField::setTableName(const QString &table)
+void QSqlField::setTableName(const QString &tableName)
{
detach();
- d->table = table;
+ d->table = tableName;
}
/*!
- Returns the tableName of the field.
+ \property QSqlField::tableName
+ \since 6.8
+
+ This property holds the tableName of the field.
\note When using the QPSQL driver, due to limitations in the libpq library,
the \c tableName() field is not populated in a QSqlField resulting
from a QSqlRecord obtained by QSqlQuery::record() of a forward-only query.
-
- \sa setTableName()
+*/
+/*!
+ Returns the \l tableName.
*/
QString QSqlField::tableName() const
{
@@ -567,3 +596,5 @@ QString QSqlField::tableName() const
}
QT_END_NAMESPACE
+
+#include "moc_qsqlfield.cpp"
diff --git a/src/sql/kernel/qsqlfield.h b/src/sql/kernel/qsqlfield.h
index 1b43d41485..451f70f3b6 100644
--- a/src/sql/kernel/qsqlfield.h
+++ b/src/sql/kernel/qsqlfield.h
@@ -17,9 +17,22 @@ QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QSqlFieldPrivate, Q_SQL_EXPORT)
class Q_SQL_EXPORT QSqlField
{
+ Q_GADGET
public:
enum RequiredStatus { Unknown = -1, Optional = 0, Required = 1 };
+ Q_PROPERTY(QVariant value READ value WRITE setValue)
+ Q_PROPERTY(QVariant defaultValue READ defaultValue WRITE setDefaultValue)
+ Q_PROPERTY(QString name READ name WRITE setName)
+ Q_PROPERTY(QString tableName READ tableName WRITE setTableName)
+ Q_PROPERTY(QMetaType metaType READ metaType WRITE setMetaType)
+ Q_PROPERTY(RequiredStatus requiredStatus READ requiredStatus WRITE setRequiredStatus)
+ Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
+ Q_PROPERTY(bool generated READ isGenerated WRITE setGenerated)
+ Q_PROPERTY(bool autoValue READ isAutoValue WRITE setAutoValue)
+ Q_PROPERTY(int length READ length WRITE setLength)
+ Q_PROPERTY(int precision READ precision WRITE setPrecision)
+
explicit QSqlField(const QString& fieldName = QString(), QMetaType type = QMetaType(), const QString &tableName = QString());
QSqlField(const QSqlField& other);
@@ -69,7 +82,6 @@ public:
void setLength(int fieldLength);
void setPrecision(int precision);
void setDefaultValue(const QVariant &value);
- void setSqlType(int type);
void setGenerated(bool gen);
void setAutoValue(bool autoVal);
@@ -77,10 +89,15 @@ public:
int length() const;
int precision() const;
QVariant defaultValue() const;
- int typeID() const;
bool isGenerated() const;
bool isValid() const;
+#if QT_DEPRECATED_SINCE(6, 8)
+ QT_DEPRECATED_VERSION_X_6_8("This internal value is no longer used.")
+ void setSqlType(int type);
+ QT_DEPRECATED_VERSION_X_6_8("This internal value is no longer used.")
+ int typeID() const;
+#endif
private:
void detach();
// ### Qt7: move to private class
@@ -88,6 +105,8 @@ private:
QExplicitlySharedDataPointer<QSqlFieldPrivate> d;
};
+Q_DECLARE_SHARED(QSqlField)
+
#ifndef QT_NO_DEBUG_STREAM
Q_SQL_EXPORT QDebug operator<<(QDebug, const QSqlField &);
#endif
diff --git a/src/sql/kernel/qsqlindex.cpp b/src/sql/kernel/qsqlindex.cpp
index 77af6f0fb8..15ee489928 100644
--- a/src/sql/kernel/qsqlindex.cpp
+++ b/src/sql/kernel/qsqlindex.cpp
@@ -84,21 +84,23 @@ QSqlIndex::~QSqlIndex()
}
/*!
- Sets the name of the index to \a name.
+ \property QSqlIndex::name
+ \since 6.8
+ This property holds the name of the index.
+*/
+/*!
+ \fn QString QSqlIndex::name() const
+ Returns the \l name.
+*/
+/*!
+ Sets \l name to \a name.
*/
-
void QSqlIndex::setName(const QString& name)
{
nm = name;
}
/*!
- \fn QString QSqlIndex::name() const
-
- Returns the name of the index.
-*/
-
-/*!
Appends the field \a field to the list of indexed fields. The
field is appended with an ascending sort order.
*/
@@ -147,34 +149,18 @@ void QSqlIndex::setDescending(int i, bool desc)
sorts[i] = desc;
}
-/*! \internal
-
- Creates a string representing the field number \a i using prefix \a
- prefix. If \a verbose is true, ASC or DESC is included in the field
- description if the field is sorted in ASCending or DESCending order.
+/*!
+ \property QSqlIndex::cursorName
+ \since 6.8
+ This property holds the name of the cursor which the index
+ is associated with.
*/
-
-QString QSqlIndex::createField(int i, const QString& prefix, bool verbose) const
-{
- QString f;
- if (!prefix.isEmpty())
- f += prefix + u'.';
- f += field(i).name();
- if (verbose)
- f += u' ' + QString((isDescending(i) ? "DESC"_L1 : "ASC"_L1));
- return f;
-}
-
/*!
\fn QString QSqlIndex::cursorName() const
-
- Returns the name of the cursor which the index is associated with.
+ Returns the \l cursorName.
*/
-
-
/*!
- Sets the name of the cursor that the index is associated with to
- \a cursorName.
+ Sets \l cursorName to \a cursorName.
*/
void QSqlIndex::setCursorName(const QString& cursorName)
{
@@ -182,3 +168,5 @@ void QSqlIndex::setCursorName(const QString& cursorName)
}
QT_END_NAMESPACE
+
+#include "moc_qsqlindex.cpp"
diff --git a/src/sql/kernel/qsqlindex.h b/src/sql/kernel/qsqlindex.h
index 67eeb2a9e0..3d5d95b373 100644
--- a/src/sql/kernel/qsqlindex.h
+++ b/src/sql/kernel/qsqlindex.h
@@ -7,20 +7,33 @@
#include <QtSql/qtsqlglobal.h>
#include <QtSql/qsqlrecord.h>
#include <QtCore/qlist.h>
+#include <QtCore/qmetaobject.h>
#include <QtCore/qstring.h>
+// clazy:excludeall=qproperty-without-notify
QT_BEGIN_NAMESPACE
class Q_SQL_EXPORT QSqlIndex : public QSqlRecord
{
+ Q_GADGET
public:
+ Q_PROPERTY(QString name READ name WRITE setName)
+ Q_PROPERTY(QString cursorName READ cursorName WRITE setCursorName)
+
explicit QSqlIndex(const QString &cursorName = QString(), const QString &name = QString());
QSqlIndex(const QSqlIndex &other);
QSqlIndex(QSqlIndex &&other) noexcept = default;
~QSqlIndex();
QSqlIndex &operator=(const QSqlIndex &other);
- QSqlIndex &operator=(QSqlIndex &&other) = default;
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QSqlIndex)
+
+ void swap(QSqlIndex &other) noexcept {
+ QSqlRecord::swap(other);
+ cursor.swap(other.cursor);
+ nm.swap(other.nm);
+ sorts.swap(other.sorts);
+ };
void setCursorName(const QString &cursorName);
inline QString cursorName() const { return cursor; }
@@ -34,13 +47,14 @@ public:
void setDescending(int i, bool desc);
private:
- QString createField(int i, const QString& prefix, bool verbose) const;
// ### Qt7: move to d-ptr
QString cursor;
QString nm;
QList<bool> sorts;
};
+Q_DECLARE_SHARED(QSqlIndex)
+
QT_END_NAMESPACE
#endif // QSQLINDEX_H
diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp
index f93ca168d1..63f782fe22 100644
--- a/src/sql/kernel/qsqlquery.cpp
+++ b/src/sql/kernel/qsqlquery.cpp
@@ -7,6 +7,7 @@
#include "qatomic.h"
#include "qdebug.h"
+#include "qloggingcategory.h"
#include "qsqlrecord.h"
#include "qsqlresult.h"
#include "qsqldriver.h"
@@ -19,6 +20,8 @@
QT_BEGIN_NAMESPACE
+Q_STATIC_LOGGING_CATEGORY(lcSqlQuery, "qt.sql.qsqlquery")
+
class QSqlQueryPrivate
{
public:
@@ -333,13 +336,12 @@ bool QSqlQuery::isNull(int field) const
This overload is less efficient than \l{QSqlQuery::}{isNull()}
*/
-
-bool QSqlQuery::isNull(const QString &name) const
+bool QSqlQuery::isNull(QAnyStringView name) const
{
qsizetype index = d->sqlResult->record().indexOf(name);
if (index > -1)
return isNull(index);
- qWarning("QSqlQuery::isNull: unknown field name '%s'", qPrintable(name));
+ qCWarning(lcSqlQuery, "QSqlQuery::isNull: unknown field name '%ls'", qUtf16Printable(name.toString()));
return true;
}
@@ -375,7 +377,7 @@ bool QSqlQuery::exec(const QString& query)
t.start();
#endif
if (!driver()) {
- qWarning("QSqlQuery::exec: called before driver has been set up");
+ qCWarning(lcSqlQuery, "QSqlQuery::exec: called before driver has been set up");
return false;
}
if (d->ref.loadRelaxed() != 1) {
@@ -392,19 +394,20 @@ bool QSqlQuery::exec(const QString& query)
}
d->sqlResult->setQuery(query.trimmed());
if (!driver()->isOpen() || driver()->isOpenError()) {
- qWarning("QSqlQuery::exec: database not open");
+ qCWarning(lcSqlQuery, "QSqlQuery::exec: database not open");
return false;
}
if (query.isEmpty()) {
- qWarning("QSqlQuery::exec: empty query");
+ qCWarning(lcSqlQuery, "QSqlQuery::exec: empty query");
return false;
}
bool retval = d->sqlResult->reset(query);
#ifdef QT_DEBUG_SQL
- qDebug().nospace() << "Executed query (" << t.elapsed() << "ms, " << d->sqlResult->size()
- << " results, " << d->sqlResult->numRowsAffected()
- << " affected): " << d->sqlResult->lastQuery();
+ qCDebug(lcSqlQuery()).nospace() << "Executed query (" << t.elapsed() << "ms, "
+ << d->sqlResult->size()
+ << " results, " << d->sqlResult->numRowsAffected()
+ << " affected): " << d->sqlResult->lastQuery();
#endif
return retval;
}
@@ -432,7 +435,7 @@ QVariant QSqlQuery::value(int index) const
{
if (isActive() && isValid() && (index > -1))
return d->sqlResult->data(index);
- qWarning("QSqlQuery::value: not positioned on a valid record");
+ qCWarning(lcSqlQuery, "QSqlQuery::value: not positioned on a valid record");
return QVariant();
}
@@ -444,13 +447,12 @@ QVariant QSqlQuery::value(int index) const
This overload is less efficient than \l{QSqlQuery::}{value()}
*/
-
-QVariant QSqlQuery::value(const QString& name) const
+QVariant QSqlQuery::value(QAnyStringView name) const
{
qsizetype index = d->sqlResult->record().indexOf(name);
if (index > -1)
return value(index);
- qWarning("QSqlQuery::value: unknown field name '%s'", qPrintable(name));
+ qCWarning(lcSqlQuery, "QSqlQuery::value: unknown field name '%ls'", qUtf16Printable(name.toString()));
return QVariant();
}
@@ -596,7 +598,7 @@ bool QSqlQuery::seek(int index, bool relative)
}
// let drivers optimize
if (isForwardOnly() && actualIdx < at()) {
- qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query");
+ qCWarning(lcSqlQuery, "QSqlQuery::seek: cannot seek backwards in a forward only query");
return false;
}
if (actualIdx == (at() + 1) && at() != QSql::BeforeFirstRow) {
@@ -702,7 +704,7 @@ bool QSqlQuery::previous()
if (!isSelect() || !isActive())
return false;
if (isForwardOnly()) {
- qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query");
+ qCWarning(lcSqlQuery, "QSqlQuery::seek: cannot seek backwards in a forward only query");
return false;
}
@@ -735,7 +737,7 @@ bool QSqlQuery::first()
if (!isSelect() || !isActive())
return false;
if (isForwardOnly() && at() > QSql::BeforeFirstRow) {
- qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query");
+ qCWarning(lcSqlQuery, "QSqlQuery::seek: cannot seek backwards in a forward only query");
return false;
}
return d->sqlResult->fetchFirst();
@@ -850,10 +852,9 @@ bool QSqlQuery::isSelect() const
}
/*!
- Returns \c true if you can only scroll forward through a result set;
- otherwise returns \c false.
+ Returns \l forwardOnly.
- \sa setForwardOnly(), next()
+ \sa forwardOnly, next(), seek()
*/
bool QSqlQuery::isForwardOnly() const
{
@@ -861,7 +862,10 @@ bool QSqlQuery::isForwardOnly() const
}
/*!
- Sets forward only mode to \a forward. If \a forward is true, only
+ \property QSqlQuery::forwardOnly
+ \since 6.8
+
+ This property holds the forward only mode. If \a forward is true, only
next() and seek() with positive values, are allowed for navigating
the results.
@@ -890,7 +894,11 @@ bool QSqlQuery::isForwardOnly() const
mode, do not execute any other SQL command on the same database
connection. This will cause the query results to be lost.
- \sa isForwardOnly(), next(), seek(), QSqlResult::setForwardOnly()
+ \sa next(), seek()
+*/
+/*!
+ Sets \l forwardOnly to \a forward.
+ \sa forwardOnly, next(), seek()
*/
void QSqlQuery::setForwardOnly(bool forward)
{
@@ -976,19 +984,19 @@ bool QSqlQuery::prepare(const QString& query)
d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
}
if (!driver()) {
- qWarning("QSqlQuery::prepare: no driver");
+ qCWarning(lcSqlQuery, "QSqlQuery::prepare: no driver");
return false;
}
if (!driver()->isOpen() || driver()->isOpenError()) {
- qWarning("QSqlQuery::prepare: database not open");
+ qCWarning(lcSqlQuery, "QSqlQuery::prepare: database not open");
return false;
}
if (query.isEmpty()) {
- qWarning("QSqlQuery::prepare: empty query");
+ qCWarning(lcSqlQuery, "QSqlQuery::prepare: empty query");
return false;
}
#ifdef QT_DEBUG_SQL
- qDebug("\n QSqlQuery::prepare: %s", query.toLocal8Bit().constData());
+ qCDebug(lcSqlQuery, "\n QSqlQuery::prepare: %ls", qUtf16Printable(query));
#endif
return d->sqlResult->savePrepare(query);
}
@@ -1015,9 +1023,9 @@ bool QSqlQuery::exec()
bool retval = d->sqlResult->exec();
#ifdef QT_DEBUG_SQL
- qDebug().nospace() << "Executed prepared query (" << t.elapsed() << "ms, "
- << d->sqlResult->size() << " results, " << d->sqlResult->numRowsAffected()
- << " affected): " << d->sqlResult->lastQuery();
+ qCDebug(lcSqlQuery).nospace() << "Executed prepared query (" << t.elapsed() << "ms, "
+ << d->sqlResult->size() << " results, " << d->sqlResult->numRowsAffected()
+ << " affected): " << d->sqlResult->lastQuery();
#endif
return retval;
}
@@ -1029,8 +1037,6 @@ bool QSqlQuery::exec()
*/
/*!
- \since 4.2
-
Executes a previously prepared SQL query in a batch. All the bound
parameters have to be lists of variants. If the database doesn't
support batch executions, the driver will simulate it using
@@ -1234,6 +1240,8 @@ QVariant QSqlQuery::lastInsertId() const
}
/*!
+ \property QSqlQuery::numericalPrecisionPolicy
+ \since 6.8
Instruct the database driver to return numerical values with a
precision specified by \a precisionPolicy.
@@ -1252,17 +1260,19 @@ QVariant QSqlQuery::lastInsertId() const
active query. Call \l{exec()}{exec(QString)} or prepare() in order
to activate the policy.
- \sa QSql::NumericalPrecisionPolicy, numericalPrecisionPolicy()
+ \sa QSql::NumericalPrecisionPolicy, QSqlDriver::numericalPrecisionPolicy,
+ QSqlDatabase::numericalPrecisionPolicy
*/
+/*!
+ Sets \l numericalPrecisionPolicy to \a precisionPolicy.
+ */
void QSqlQuery::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
{
d->sqlResult->setNumericalPrecisionPolicy(precisionPolicy);
}
/*!
- Returns the current precision policy.
-
- \sa QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy()
+ Returns the \l numericalPrecisionPolicy.
*/
QSql::NumericalPrecisionPolicy QSqlQuery::numericalPrecisionPolicy() const
{
@@ -1270,8 +1280,41 @@ QSql::NumericalPrecisionPolicy QSqlQuery::numericalPrecisionPolicy() const
}
/*!
- \since 4.3.2
+ \property QSqlQuery::positionalBindingEnabled
+ \since 6.8
+ This property enables or disables the positional \l {Approaches to Binding Values}{binding}
+ for this query, depending on \a enable (default is \c true).
+ Disabling positional bindings is useful if the query itself contains a '?'
+ which must not be handled as a positional binding parameter but, for example,
+ as a JSON operator for a PostgreSQL database.
+
+ This property will have no effect when the database has native
+ support for positional bindings with question marks (see also
+ \l{QSqlDriver::PositionalPlaceholders}).
+*/
+
+/*!
+ Sets \l positionalBindingEnabled to \a enable.
+ \since 6.7
+ \sa positionalBindingEnabled
+*/
+void QSqlQuery::setPositionalBindingEnabled(bool enable)
+{
+ d->sqlResult->setPositionalBindingEnabled(enable);
+}
+
+/*!
+ Returns \l positionalBindingEnabled.
+ \since 6.7
+ \sa positionalBindingEnabled
+*/
+bool QSqlQuery::isPositionalBindingEnabled() const
+{
+ return d->sqlResult->isPositionalBindingEnabled();
+}
+
+/*!
Instruct the database driver that no more data will be fetched from
this query until it is re-executed. There is normally no need to
call this function, but it may be helpful in order to free resources
@@ -1293,8 +1336,6 @@ void QSqlQuery::finish()
}
/*!
- \since 4.4
-
Discards the current result set and navigates to the next if available.
Some databases are capable of returning multiple result sets for
@@ -1320,7 +1361,7 @@ void QSqlQuery::finish()
databases may have restrictions on which statements are allowed to
be used in a SQL batch.
- \sa QSqlDriver::hasFeature(), setForwardOnly(), next(), isSelect(),
+ \sa QSqlDriver::hasFeature(), forwardOnly, next(), isSelect(),
numRowsAffected(), isActive(), lastError()
*/
bool QSqlQuery::nextResult()
@@ -1331,3 +1372,5 @@ bool QSqlQuery::nextResult()
}
QT_END_NAMESPACE
+
+#include "moc_qsqlquery.cpp"
diff --git a/src/sql/kernel/qsqlquery.h b/src/sql/kernel/qsqlquery.h
index 9d019d5cd2..bd3fea9e3e 100644
--- a/src/sql/kernel/qsqlquery.h
+++ b/src/sql/kernel/qsqlquery.h
@@ -9,6 +9,7 @@
#include <QtCore/qstring.h>
#include <QtCore/qvariant.h>
+// clazy:excludeall=qproperty-without-notify
QT_BEGIN_NAMESPACE
@@ -21,7 +22,12 @@ class QSqlQueryPrivate;
class Q_SQL_EXPORT QSqlQuery
{
+ Q_GADGET
public:
+ Q_PROPERTY(bool forwardOnly READ isForwardOnly WRITE setForwardOnly)
+ Q_PROPERTY(bool positionalBindingEnabled READ isPositionalBindingEnabled WRITE setPositionalBindingEnabled)
+ Q_PROPERTY(QSql::NumericalPrecisionPolicy numericalPrecisionPolicy READ numericalPrecisionPolicy WRITE setNumericalPrecisionPolicy)
+
explicit QSqlQuery(QSqlResult *r);
explicit QSqlQuery(const QString& query = QString(), const QSqlDatabase &db = QSqlDatabase());
explicit QSqlQuery(const QSqlDatabase &db);
@@ -49,7 +55,10 @@ public:
bool isValid() const;
bool isActive() const;
bool isNull(int field) const;
+#if QT_SQL_REMOVED_SINCE(6, 8)
bool isNull(const QString &name) const;
+#endif
+ bool isNull(QAnyStringView name) const;
int at() const;
QString lastQuery() const;
int numRowsAffected() const;
@@ -64,11 +73,17 @@ public:
void setForwardOnly(bool forward);
bool exec(const QString& query);
QVariant value(int i) const;
- QVariant value(const QString& name) const;
+#if QT_SQL_REMOVED_SINCE(6, 8)
+ QVariant value(const QString &name) const;
+#endif
+ QVariant value(QAnyStringView name) const;
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy);
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
+ void setPositionalBindingEnabled(bool enable);
+ bool isPositionalBindingEnabled() const;
+
bool seek(int i, bool relative = false);
bool next();
bool previous();
diff --git a/src/sql/kernel/qsqlrecord.cpp b/src/sql/kernel/qsqlrecord.cpp
index e4d2c96c6b..89af1a52fe 100644
--- a/src/sql/kernel/qsqlrecord.cpp
+++ b/src/sql/kernel/qsqlrecord.cpp
@@ -19,6 +19,33 @@ public:
return index >= 0 && index < fields.size();
}
+ template <typename T>
+ qsizetype indexOfImpl(T name)
+ {
+ T tableName;
+ T fieldName;
+ const auto it = std::find(name.begin(), name.end(), u'.');
+ const auto idx = (it == name.end()) ? -1 : it - name.begin();
+ if (idx != -1) {
+ tableName = name.left(idx);
+ fieldName = name.mid(idx + 1);
+ }
+ const auto cnt = fields.size();
+ for (qsizetype i = 0; i < cnt; ++i) {
+ // Check the passed in name first in case it is an alias using a dot.
+ // Then check if both the table and field match when there is a table name specified.
+ const auto &currentField = fields.at(i);
+ const auto &currentFieldName = currentField.name();
+ if (name.compare(currentFieldName, Qt::CaseInsensitive) == 0)
+ return i;
+ if (idx != -1 &&
+ tableName.compare(currentField.tableName(), Qt::CaseInsensitive) == 0 &&
+ fieldName.compare(currentFieldName, Qt::CaseInsensitive) == 0)
+ return i;
+ }
+ return -1;
+ }
+
QList<QSqlField> fields;
};
QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QSqlRecordPrivate)
@@ -75,7 +102,7 @@ QSqlRecord::QSqlRecord()
of a record in \l{constant time}.
*/
-QSqlRecord::QSqlRecord(const QSqlRecord& other)
+QSqlRecord::QSqlRecord(const QSqlRecord &other)
= default;
/*!
@@ -116,7 +143,7 @@ QSqlRecord::QSqlRecord(const QSqlRecord& other)
of a record in \l{constant time}.
*/
-QSqlRecord& QSqlRecord::operator=(const QSqlRecord& other)
+QSqlRecord& QSqlRecord::operator=(const QSqlRecord &other)
= default;
/*!
@@ -166,10 +193,9 @@ QVariant QSqlRecord::value(int index) const
Returns the value of the field called \a name in the record. If
field \a name does not exist an invalid variant is returned.
- \sa indexOf()
+ \sa indexOf(), isNull()
*/
-
-QVariant QSqlRecord::value(const QString& name) const
+QVariant QSqlRecord::value(QAnyStringView name) const
{
return value(indexOf(name));
}
@@ -193,30 +219,13 @@ QString QSqlRecord::fieldName(int index) const
returned.
\sa fieldName()
-*/
-
-int QSqlRecord::indexOf(const QString& name) const
+ */
+int QSqlRecord::indexOf(QAnyStringView name) const
{
- QStringView tableName;
- QStringView fieldName(name);
- const qsizetype idx = name.indexOf(u'.');
- if (idx != -1) {
- tableName = fieldName.left(idx);
- fieldName = fieldName.mid(idx + 1);
- }
- const int cnt = count();
- for (int i = 0; i < cnt; ++i) {
- // Check the passed in name first in case it is an alias using a dot.
- // Then check if both the table and field match when there is a table name specified.
- const auto &currentField = d->fields.at(i);
- const auto &currentFieldName = currentField.name();
- if (currentFieldName.compare(name, Qt::CaseInsensitive) == 0
- || (idx != -1 && currentFieldName.compare(fieldName, Qt::CaseInsensitive) == 0
- && currentField.tableName().compare(tableName, Qt::CaseInsensitive) == 0)) {
- return i;
- }
- }
- return -1;
+ return name.visit([&](auto v)
+ {
+ return d->indexOfImpl(v);
+ });
}
/*!
@@ -229,10 +238,14 @@ QSqlField QSqlRecord::field(int index) const
return d->fields.value(index);
}
-/*! \overload
- Returns the field called \a name.
+/*!
+ \overload
+
+ Returns the field called \a name. If the field called
+ \a name is not found, function returns
+ a \l{default-constructed value}.
*/
-QSqlField QSqlRecord::field(const QString &name) const
+QSqlField QSqlRecord::field(QAnyStringView name) const
{
return field(indexOf(name));
}
@@ -244,7 +257,7 @@ QSqlField QSqlRecord::field(const QString &name) const
\sa insert(), replace(), remove()
*/
-void QSqlRecord::append(const QSqlField& field)
+void QSqlRecord::append(const QSqlField &field)
{
detach();
d->fields.append(field);
@@ -255,7 +268,7 @@ void QSqlRecord::append(const QSqlField& field)
\sa append(), replace(), remove()
*/
-void QSqlRecord::insert(int pos, const QSqlField& field)
+void QSqlRecord::insert(int pos, const QSqlField &field)
{
detach();
d->fields.insert(pos, field);
@@ -268,7 +281,7 @@ void QSqlRecord::insert(int pos, const QSqlField& field)
\sa append(), insert(), remove()
*/
-void QSqlRecord::replace(int pos, const QSqlField& field)
+void QSqlRecord::replace(int pos, const QSqlField &field)
{
if (!d->contains(pos))
return;
@@ -317,13 +330,11 @@ bool QSqlRecord::isEmpty() const
return d->fields.isEmpty();
}
-
/*!
Returns \c true if there is a field in the record called \a name;
otherwise returns \c false.
*/
-
-bool QSqlRecord::contains(const QString& name) const
+bool QSqlRecord::contains(QAnyStringView name) const
{
return indexOf(name) >= 0;
}
@@ -350,15 +361,12 @@ void QSqlRecord::clearValues()
\sa isGenerated()
*/
-
-void QSqlRecord::setGenerated(const QString& name, bool generated)
+void QSqlRecord::setGenerated(QAnyStringView name, bool generated)
{
setGenerated(indexOf(name), generated);
}
/*!
- \overload
-
Sets the generated flag for the field \a index to \a generated.
\sa isGenerated()
@@ -373,10 +381,10 @@ void QSqlRecord::setGenerated(int index, bool generated)
}
/*!
- \overload
-
Returns \c true if the field \a index is null or if there is no field at
position \a index; otherwise returns \c false.
+
+ \sa setNull()
*/
bool QSqlRecord::isNull(int index) const
{
@@ -384,12 +392,14 @@ bool QSqlRecord::isNull(int index) const
}
/*!
+ \overload
+
Returns \c true if the field called \a name is null or if there is no
field called \a name; otherwise returns \c false.
\sa setNull()
*/
-bool QSqlRecord::isNull(const QString& name) const
+bool QSqlRecord::isNull(QAnyStringView name) const
{
return isNull(indexOf(name));
}
@@ -414,25 +424,25 @@ void QSqlRecord::setNull(int index)
Sets the value of the field called \a name to null. If the field
does not exist, nothing happens.
*/
-void QSqlRecord::setNull(const QString& name)
+void QSqlRecord::setNull(QAnyStringView name)
{
setNull(indexOf(name));
}
-
/*!
+ \overload
+
Returns \c true if the record has a field called \a name and this
field is to be generated (the default); otherwise returns \c false.
\sa setGenerated()
*/
-bool QSqlRecord::isGenerated(const QString& name) const
+bool QSqlRecord::isGenerated(QAnyStringView name) const
{
return isGenerated(indexOf(name));
}
-/*! \overload
-
+/*!
Returns \c true if the record has a field at position \a index and this
field is to be generated (the default); otherwise returns \c false.
@@ -461,7 +471,7 @@ int QSqlRecord::count() const
\sa setNull()
*/
-void QSqlRecord::setValue(int index, const QVariant& val)
+void QSqlRecord::setValue(int index, const QVariant &val)
{
if (!d->contains(index))
return;
@@ -469,15 +479,15 @@ void QSqlRecord::setValue(int index, const QVariant& val)
d->fields[index].setValue(val);
}
-
/*!
\overload
Sets the value of the field called \a name to \a val. If the field
does not exist, nothing happens.
-*/
-void QSqlRecord::setValue(const QString& name, const QVariant& val)
+ \sa setNull()
+*/
+void QSqlRecord::setValue(QAnyStringView name, const QVariant &val)
{
setValue(indexOf(name), val);
}
diff --git a/src/sql/kernel/qsqlrecord.h b/src/sql/kernel/qsqlrecord.h
index 2ae7ff38c3..aea9af7295 100644
--- a/src/sql/kernel/qsqlrecord.h
+++ b/src/sql/kernel/qsqlrecord.h
@@ -20,9 +20,9 @@ class Q_SQL_EXPORT QSqlRecord
{
public:
QSqlRecord();
- QSqlRecord(const QSqlRecord& other);
+ QSqlRecord(const QSqlRecord &other);
QSqlRecord(QSqlRecord &&other) noexcept = default;
- QSqlRecord& operator=(const QSqlRecord& other);
+ QSqlRecord& operator=(const QSqlRecord &other);
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QSqlRecord)
~QSqlRecord();
@@ -32,33 +32,60 @@ public:
inline bool operator!=(const QSqlRecord &other) const { return !operator==(other); }
QVariant value(int i) const;
- QVariant value(const QString& name) const;
- void setValue(int i, const QVariant& val);
- void setValue(const QString& name, const QVariant& val);
+#if QT_SQL_REMOVED_SINCE(6, 8)
+ QVariant value(const QString &name) const;
+#endif
+ QVariant value(QAnyStringView name) const;
+ void setValue(int i, const QVariant &val);
+#if QT_SQL_REMOVED_SINCE(6, 8)
+ void setValue(const QString &name, const QVariant &val);
+#endif
+ void setValue(QAnyStringView name, const QVariant &val);
void setNull(int i);
- void setNull(const QString& name);
+#if QT_SQL_REMOVED_SINCE(6, 8)
+ void setNull(const QString &name);
+#endif
+ void setNull(QAnyStringView name);
bool isNull(int i) const;
- bool isNull(const QString& name) const;
+#if QT_SQL_REMOVED_SINCE(6, 8)
+ bool isNull(const QString &name) const;
+#endif
+ bool isNull(QAnyStringView name) const;
+#if QT_SQL_REMOVED_SINCE(6, 8)
int indexOf(const QString &name) const;
+#endif
+ int indexOf(QAnyStringView name) const;
QString fieldName(int i) const;
QSqlField field(int i) const;
+#if QT_SQL_REMOVED_SINCE(6, 8)
QSqlField field(const QString &name) const;
+#endif
+ QSqlField field(QAnyStringView name) const;
bool isGenerated(int i) const;
- bool isGenerated(const QString& name) const;
- void setGenerated(const QString& name, bool generated);
+#if QT_SQL_REMOVED_SINCE(6, 8)
+ bool isGenerated(const QString &name) const;
+#endif
+ bool isGenerated(QAnyStringView name) const;
+#if QT_SQL_REMOVED_SINCE(6, 8)
+ void setGenerated(const QString &name, bool generated);
+#endif
+ void setGenerated(QAnyStringView name, bool generated);
void setGenerated(int i, bool generated);
- void append(const QSqlField& field);
- void replace(int pos, const QSqlField& field);
- void insert(int pos, const QSqlField& field);
+ void append(const QSqlField &field);
+ void replace(int pos, const QSqlField &field);
+ void insert(int pos, const QSqlField &field);
void remove(int pos);
bool isEmpty() const;
- bool contains(const QString& name) const;
+#if QT_SQL_REMOVED_SINCE(6, 8)
+ bool contains(const QString &name) const;
+#endif
+ bool contains(QAnyStringView name) const;
void clear();
void clearValues();
int count() const;
@@ -69,6 +96,8 @@ private:
QExplicitlySharedDataPointer<QSqlRecordPrivate> d;
};
+Q_DECLARE_SHARED(QSqlRecord)
+
#ifndef QT_NO_DEBUG_STREAM
Q_SQL_EXPORT QDebug operator<<(QDebug, const QSqlRecord &);
#endif
diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp
index 1b7daa8d0f..59e9879cf0 100644
--- a/src/sql/kernel/qsqlresult.cpp
+++ b/src/sql/kernel/qsqlresult.cpp
@@ -37,6 +37,9 @@ static bool qIsAlnum(QChar ch)
QString QSqlResultPrivate::positionalToNamedBinding(const QString &query) const
{
+ if (!positionalBindingEnabled)
+ return query;
+
const qsizetype n = query.size();
QString result;
@@ -92,6 +95,7 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query)
int count = 0;
qsizetype i = 0;
bool ignoreBraces = (sqldriver->dbmsType() == QSqlDriver::PostgreSQL);
+ const bool qmarkNotationSupported = (sqldriver->dbmsType() != QSqlDriver::PostgreSQL);
while (i < n) {
QChar ch = query.at(i);
@@ -115,10 +119,16 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query)
int pos = i + 2;
while (pos < n && qIsAlnum(query.at(pos)))
++pos;
+ // if question mark notation is not supported we have to use
+ // the native binding. fieldSerial() should be renamed
+ // to toNativeBinding() and used unconditionally here
+ if (qmarkNotationSupported)
+ result += u'?';
+ else
+ result += fieldSerial(count);
QString holder(query.mid(i, pos - i));
indexes[holder].append(count++);
holders.append(QHolder(holder, i));
- result += u'?';
i = pos;
} else {
if (ch == u'\'' || ch == u'"' || ch == u'`')
@@ -784,17 +794,32 @@ int QSqlResult::boundValueCount() const
}
/*!
- Returns a vector of the result's bound values for the current
+ Returns a list of the result's bound values for the current
record (row).
\sa boundValueCount()
*/
-QList<QVariant> &QSqlResult::boundValues() const
+QVariantList QSqlResult::boundValues(QT6_IMPL_NEW_OVERLOAD) const
{
Q_D(const QSqlResult);
- return const_cast<QSqlResultPrivate *>(d)->values;
+ return d->values;
+}
+
+/*!
+ \overload
+
+ Returns a mutable reference to the list of the result's bound values
+ for the current record (row).
+
+ \sa boundValueCount()
+*/
+QVariantList &QSqlResult::boundValues(QT6_IMPL_NEW_OVERLOAD)
+{
+ Q_D(QSqlResult);
+ return d->values;
}
+
/*!
Returns the binding syntax used by prepared queries.
*/
@@ -921,8 +946,6 @@ void QSqlResult::virtual_hook(int, void *)
}
/*! \internal
- \since 4.2
-
Executes a prepared query in batch mode if the driver supports it,
otherwise emulates a batch execution using bindValue() and exec().
QSqlDriver::hasFeature() can be used to find out whether a driver
@@ -990,6 +1013,23 @@ QSql::NumericalPrecisionPolicy QSqlResult::numericalPrecisionPolicy() const
}
/*! \internal
+ */
+void QSqlResult::setPositionalBindingEnabled(bool enable)
+{
+ Q_D(QSqlResult);
+ d->positionalBindingEnabled = enable;
+}
+
+/*! \internal
+ */
+bool QSqlResult::isPositionalBindingEnabled() const
+{
+ Q_D(const QSqlResult);
+ return d->positionalBindingEnabled;
+}
+
+
+/*! \internal
*/
bool QSqlResult::nextResult()
{
diff --git a/src/sql/kernel/qsqlresult.h b/src/sql/kernel/qsqlresult.h
index c16564a516..4200bbde34 100644
--- a/src/sql/kernel/qsqlresult.h
+++ b/src/sql/kernel/qsqlresult.h
@@ -8,9 +8,6 @@
#include <QtCore/qvariant.h>
#include <QtCore/qcontainerfwd.h>
-// for testing:
-class tst_QSqlQuery;
-
QT_BEGIN_NAMESPACE
@@ -26,8 +23,6 @@ class Q_SQL_EXPORT QSqlResult
Q_DECLARE_PRIVATE(QSqlResult)
friend class QSqlQuery;
friend class QSqlTableModelPrivate;
- // for testing:
- friend class ::tst_QSqlQuery;
public:
virtual ~QSqlResult();
@@ -69,8 +64,12 @@ protected:
QSql::ParamType bindValueType(const QString& placeholder) const;
QSql::ParamType bindValueType(int pos) const;
int boundValueCount() const;
- // ### Qt 7 - don't return a non-const reference from a const function
+#if QT_SQL_REMOVED_SINCE(6, 6)
QList<QVariant> &boundValues() const;
+#endif
+ QVariantList &boundValues(QT6_DECL_NEW_OVERLOAD);
+ QVariantList boundValues(QT6_DECL_NEW_OVERLOAD) const;
+
QString executedQuery() const;
QStringList boundValueNames() const;
QString boundValueName(int pos) const;
@@ -98,6 +97,8 @@ protected:
virtual void detachFromResultSet();
virtual void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy);
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
+ void setPositionalBindingEnabled(bool enable);
+ bool isPositionalBindingEnabled() const;
virtual bool nextResult();
void resetBindCount(); // HACK
diff --git a/src/sql/kernel/qsqlresult_p.h b/src/sql/kernel/qsqlresult_p.h
index 1e8e8a3033..6eebdaaba4 100644
--- a/src/sql/kernel/qsqlresult_p.h
+++ b/src/sql/kernel/qsqlresult_p.h
@@ -98,6 +98,7 @@ public:
bool active = false;
bool isSel = false;
bool forwardOnly = false;
+ bool positionalBindingEnabled = true;
static bool isVariantNull(const QVariant &variant);
};
diff --git a/src/sql/kernel/qtsqlglobal.h b/src/sql/kernel/qtsqlglobal.h
index b01010d653..977d97abbf 100644
--- a/src/sql/kernel/qtsqlglobal.h
+++ b/src/sql/kernel/qtsqlglobal.h
@@ -6,7 +6,6 @@
#if 0
#pragma qt_class(QSql)
-#pragma qt_deprecates(qsql.h)
#endif
#include <QtCore/qglobal.h>
diff --git a/src/sql/models/qsqlquerymodel.cpp b/src/sql/models/qsqlquerymodel.cpp
index 0a7470d5c8..1aae088c64 100644
--- a/src/sql/models/qsqlquerymodel.cpp
+++ b/src/sql/models/qsqlquerymodel.cpp
@@ -139,8 +139,6 @@ QSqlQueryModel::~QSqlQueryModel()
}
/*!
- \since 4.1
-
Fetches more rows from a database.
This only affects databases that don't report back the size of a query
(see QSqlDriver::hasFeature()).
@@ -162,8 +160,6 @@ void QSqlQueryModel::fetchMore(const QModelIndex &parent)
}
/*!
- \since 4.1
-
Returns \c true if it is possible to read more rows from the database.
This only affects databases that don't report back the size of a query
(see QSqlDriver::hasFeature()).
@@ -295,7 +291,6 @@ void QSqlQueryModel::endResetModel()
}
/*! \fn int QSqlQueryModel::rowCount(const QModelIndex &parent) const
- \since 4.1
If the database supports returning the size of a query
(see QSqlDriver::hasFeature()), the number of rows of the current
@@ -388,8 +383,6 @@ void QSqlQueryModel::queryChange()
/*!
\deprecated [6.2] Use the \c{setQuery(QSqlQuery &&query)} overload instead.
\overload
- \since 4.5
-
*/
void QSqlQueryModel::setQuery(const QSqlQuery &query)
{
@@ -625,7 +618,7 @@ bool QSqlQueryModel::insertColumns(int column, int count, const QModelIndex &par
d->colOffsets.append(nVal);
Q_ASSERT(d->colOffsets.size() >= d->rec.count());
}
- for (int i = column + 1; i < d->colOffsets.size(); ++i)
+ for (qsizetype i = column + 1; i < d->colOffsets.size(); ++i)
++d->colOffsets[i];
}
endInsertColumns();
@@ -651,10 +644,9 @@ bool QSqlQueryModel::removeColumns(int column, int count, const QModelIndex &par
beginRemoveColumns(parent, column, column + count - 1);
- int i;
- for (i = 0; i < count; ++i)
+ for (int i = 0; i < count; ++i)
d->rec.remove(column);
- for (i = column; i < d->colOffsets.size(); ++i)
+ for (qsizetype i = column; i < d->colOffsets.size(); ++i)
d->colOffsets[i] -= count;
endRemoveColumns();
diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp
index acd20b98da..1218514778 100644
--- a/src/sql/models/qsqlrelationaltablemodel.cpp
+++ b/src/sql/models/qsqlrelationaltablemodel.cpp
@@ -21,7 +21,7 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
-class QSqlRelationalTableModelSql: public QSqlTableModelSql
+class QSqlRelationalTableModelSql: public QSqlQueryModelSql
{
public:
inline const static QString relTablePrefix(int i) { return QString::number(i).prepend("relTblAl_"_L1); }
@@ -108,12 +108,12 @@ struct QRelation
void populateModel();
- bool isDictionaryInitialized();
+ bool isDictionaryInitialized() const;
void populateDictionary();
void clearDictionary();
void clear();
- bool isValid();
+ bool isValid() const;
QSqlRelation rel;
QRelatedTableModel *model;
@@ -158,7 +158,7 @@ void QRelation::populateModel()
}
}
-bool QRelation::isDictionaryInitialized()
+bool QRelation::isDictionaryInitialized() const
{
return m_dictInitialized;
}
@@ -204,7 +204,7 @@ void QRelation::clear()
clearDictionary();
}
-bool QRelation::isValid()
+bool QRelation::isValid() const
{
return (rel.isValid() && m_parent != nullptr);
}
@@ -253,10 +253,8 @@ public:
void QSqlRelationalTableModelPrivate::clearChanges()
{
- for (int i = 0; i < relations.size(); ++i) {
- QRelation &rel = relations[i];
+ for (auto &rel : relations)
rel.clear();
- }
}
void QSqlRelationalTableModelPrivate::revertCachedRow(int row)
@@ -277,8 +275,8 @@ int QSqlRelationalTableModelPrivate::nameToIndex(const QString &name) const
void QSqlRelationalTableModelPrivate::clearCache()
{
- for (int i = 0; i < relations.size(); ++i)
- relations[i].clearDictionary();
+ for (auto &rel : relations)
+ rel.clearDictionary();
QSqlTableModelPrivate::clearCache();
}
@@ -644,7 +642,6 @@ void QSqlRelationalTableModel::clear()
\value LeftJoin - Left join mode, returns all rows from the left table (table_name1), even if there are no matches in the right table (table_name2).
\sa QSqlRelationalTableModel::setJoinMode()
- \since 4.8
*/
/*!
@@ -653,7 +650,6 @@ void QSqlRelationalTableModel::clear()
LeftJoin mode if you want to show them.
\sa QSqlRelationalTableModel::JoinMode
- \since 4.8
*/
void QSqlRelationalTableModel::setJoinMode( QSqlRelationalTableModel::JoinMode joinMode )
{
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 265d7782a0..0d17194287 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -19,12 +19,7 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
-using SqlTm = QSqlTableModelSql;
-
-QSqlTableModelPrivate::~QSqlTableModelPrivate()
-{
-
-}
+using SqlTm = QSqlQueryModelSql;
/*! \internal
Populates our record with values.
@@ -143,11 +138,10 @@ bool QSqlTableModelPrivate::exec(const QString &stmt, bool prepStatement,
return false;
}
}
- int i;
- for (i = 0; i < rec.count(); ++i)
+ for (int i = 0; i < rec.count(); ++i)
if (rec.isGenerated(i))
editQuery.addBindValue(rec.value(i));
- for (i = 0; i < whereValues.count(); ++i)
+ for (int i = 0; i < whereValues.count(); ++i)
if (whereValues.isGenerated(i) && !whereValues.isNull(i))
editQuery.addBindValue(whereValues.value(i));
@@ -475,10 +469,8 @@ QVariant QSqlTableModel::headerData(int section, Qt::Orientation orientation, in
bool QSqlTableModel::isDirty() const
{
Q_D(const QSqlTableModel);
- QSqlTableModelPrivate::CacheMap::ConstIterator i = d->cache.constBegin();
- const QSqlTableModelPrivate::CacheMap::ConstIterator e = d->cache.constEnd();
- for (; i != e; ++i) {
- if (!i.value().submitted())
+ for (const auto &val : std::as_const(d->cache)) {
+ if (!val.submitted())
return true;
}
return false;
@@ -1360,8 +1352,7 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &values)
return false;
// Check field names and remember mapping
- typedef QMap<int, int> Map;
- Map map;
+ QMap<int, int> map;
for (int i = 0; i < values.count(); ++i) {
int idx = d->nameToIndex(values.fieldName(i));
if (idx == -1)
@@ -1374,18 +1365,16 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &values)
mrow = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Update,
QSqlQueryModel::record(row));
- Map::const_iterator i = map.constBegin();
- const Map::const_iterator e = map.constEnd();
- for ( ; i != e; ++i) {
+ for (const auto i : map.asKeyValueRange()) {
// have to use virtual setData() here rather than mrow.setValue()
EditStrategy strategy = d->strategy;
d->strategy = OnManualSubmit;
- QModelIndex cIndex = createIndex(row, i.value());
- setData(cIndex, values.value(i.key()));
+ QModelIndex cIndex = createIndex(row, i.second);
+ setData(cIndex, values.value(i.first));
d->strategy = strategy;
// setData() sets generated to TRUE, but source record should prevail.
- if (!values.isGenerated(i.key()))
- mrow.recRef().setGenerated(i.value(), false);
+ if (!values.isGenerated(i.first))
+ mrow.recRef().setGenerated(i.second, false);
}
if (d->strategy != OnManualSubmit)
diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h
index 9c6425ded4..864c977ebb 100644
--- a/src/sql/models/qsqltablemodel_p.h
+++ b/src/sql/models/qsqltablemodel_p.h
@@ -35,7 +35,6 @@ public:
strategy(QSqlTableModel::OnRowChange),
busyInsertingRows(false)
{}
- ~QSqlTableModelPrivate();
void clear();
virtual void clearCache();
@@ -154,11 +153,6 @@ public:
CacheMap cache;
};
-class QSqlTableModelSql: public QSqlQueryModelSql
-{
-public:
-};
-
QT_END_NAMESPACE
#endif // QSQLTABLEMODEL_P_H