summaryrefslogtreecommitdiffstats
path: root/src/sql/kernel/qsqlquery.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sql/kernel/qsqlquery.cpp')
-rw-r--r--src/sql/kernel/qsqlquery.cpp260
1 files changed, 174 insertions, 86 deletions
diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp
index d51d596d14..8395e56c4b 100644
--- a/src/sql/kernel/qsqlquery.cpp
+++ b/src/sql/kernel/qsqlquery.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtSql module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qsqlquery.h"
@@ -43,14 +7,16 @@
#include "qatomic.h"
#include "qdebug.h"
-#include "qelapsedtimer.h"
-#include "qmap.h"
#include "qsqlrecord.h"
#include "qsqlresult.h"
#include "qsqldriver.h"
#include "qsqldatabase.h"
#include "private/qsqlnulldriver_p.h"
+#ifdef QT_DEBUG_SQL
+#include "qelapsedtimer.h"
+#endif
+
QT_BEGIN_NAMESPACE
class QSqlQueryPrivate
@@ -243,12 +209,18 @@ QSqlQuery::QSqlQuery(QSqlResult *result)
QSqlQuery::~QSqlQuery()
{
- if (!d->ref.deref())
+ if (d && !d->ref.deref())
delete d;
}
+#if QT_DEPRECATED_SINCE(6, 2)
/*!
Constructs a copy of \a other.
+
+ \deprecated QSqlQuery cannot be meaningfully copied. Prepared
+ statements, bound values and so on will not work correctly, depending
+ on your database driver (for instance, changing the copy will affect
+ the original). Treat QSqlQuery as a move-only type instead.
*/
QSqlQuery::QSqlQuery(const QSqlQuery& other)
@@ -258,16 +230,53 @@ QSqlQuery::QSqlQuery(const QSqlQuery& other)
}
/*!
+ Assigns \a other to this object.
+
+ \deprecated QSqlQuery cannot be meaningfully copied. Prepared
+ statements, bound values and so on will not work correctly, depending
+ on your database driver (for instance, changing the copy will affect
+ the original). Treat QSqlQuery as a move-only type instead.
+*/
+
+QSqlQuery& QSqlQuery::operator=(const QSqlQuery& other)
+{
+ qAtomicAssign(d, other.d);
+ return *this;
+}
+#endif
+
+/*!
+ \fn QSqlQuery::QSqlQuery(QSqlQuery &&other) noexcept
+ \since 6.2
+ Move-constructs a QSqlQuery from \a other.
+*/
+
+/*!
+ \fn QSqlQuery &QSqlQuery::operator=(QSqlQuery &&other) noexcept
+ \since 6.2
+ Move-assigns \a other to this object.
+*/
+
+/*!
+ \fn void QSqlQuery::swap(QSqlQuery &other) noexcept
+ \since 6.2
+ Swaps \a other to this object. This operation is very
+ fast and never fails.
+*/
+
+/*!
\internal
*/
static void qInit(QSqlQuery *q, const QString& query, const QSqlDatabase &db)
{
QSqlDatabase database = db;
- if (!database.isValid())
- database = QSqlDatabase::database(QLatin1String(QSqlDatabase::defaultConnection), false);
- if (database.isValid()) {
- *q = QSqlQuery(database.driver()->createResult());
+ if (!database.isValid()) {
+ database =
+ QSqlDatabase::database(QLatin1StringView(QSqlDatabase::defaultConnection), false);
}
+ if (database.isValid())
+ *q = QSqlQuery(database.driver()->createResult());
+
if (!query.isEmpty())
q->exec(query);
}
@@ -299,17 +308,6 @@ QSqlQuery::QSqlQuery(const QSqlDatabase &db)
qInit(this, QString(), db);
}
-
-/*!
- Assigns \a other to this object.
-*/
-
-QSqlQuery& QSqlQuery::operator=(const QSqlQuery& other)
-{
- qAtomicAssign(d, other.d);
- return *this;
-}
-
/*!
Returns \c true if the query is not \l{isActive()}{active},
the query is not positioned on a valid record,
@@ -329,19 +327,26 @@ bool QSqlQuery::isNull(int field) const
/*!
\overload
+*/
+bool QSqlQuery::isNull(const QString &name) const
+{
+ return isNull(QStringView(name));
+}
+
+/*!
+ \overload
Returns \c true if there is no field with this \a name; otherwise
returns isNull(int index) for the corresponding field index.
This overload is less efficient than \l{QSqlQuery::}{isNull()}
*/
-
-bool QSqlQuery::isNull(const QString &name) const
+bool QSqlQuery::isNull(QStringView name) const
{
- int index = d->sqlResult->record().indexOf(name);
+ qsizetype index = d->sqlResult->record().indexOf(name);
if (index > -1)
return isNull(index);
- qWarning("QSqlQuery::isNull: unknown field name '%s'", qPrintable(name));
+ qWarning("QSqlQuery::isNull: unknown field name '%s'", qPrintable(name.toString()));
return true;
}
@@ -376,6 +381,10 @@ bool QSqlQuery::exec(const QString& query)
QElapsedTimer t;
t.start();
#endif
+ if (!driver()) {
+ qWarning("QSqlQuery::exec: called before driver has been set up");
+ return false;
+ }
if (d->ref.loadRelaxed() != 1) {
bool fo = isForwardOnly();
*this = QSqlQuery(driver()->createResult());
@@ -436,19 +445,26 @@ QVariant QSqlQuery::value(int index) const
/*!
\overload
+*/
+QVariant QSqlQuery::value(const QString &name) const
+{
+ return value(QStringView(name));
+}
+
+/*!
+ \overload
Returns the value of the field called \a name in the current record.
If field \a name does not exist an invalid variant is returned.
This overload is less efficient than \l{QSqlQuery::}{value()}
*/
-
-QVariant QSqlQuery::value(const QString& name) const
+QVariant QSqlQuery::value(QStringView name) const
{
- int index = d->sqlResult->record().indexOf(name);
+ qsizetype index = d->sqlResult->record().indexOf(name);
if (index > -1)
return value(index);
- qWarning("QSqlQuery::value: unknown field name '%s'", qPrintable(name));
+ qWarning("QSqlQuery::value: unknown field name '%s'", qPrintable(name.toString()));
return QVariant();
}
@@ -848,10 +864,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
{
@@ -859,7 +874,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.
@@ -888,7 +906,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)
{
@@ -918,7 +940,7 @@ QSqlRecord QSqlQuery::record() const
QSqlRecord rec = d->sqlResult->record();
if (isValid()) {
- for (int i = 0; i < rec.count(); ++i)
+ for (qsizetype i = 0; i < rec.count(); ++i)
rec.setValue(i, value(i));
}
return rec;
@@ -1027,8 +1049,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
@@ -1047,8 +1067,8 @@ bool QSqlQuery::exec()
To bind NULL values, a null QVariant of the relevant type has to be
added to the bound QVariantList; for example, \c
- {QVariant(QMetaType::QString)} should be used if you are using
- strings.
+ {QVariant(QMetaType::fromType<QString>())} should be used if you are
+ using strings.
\note Every bound QVariantList must contain the same amount of
variants.
@@ -1085,7 +1105,7 @@ bool QSqlQuery::execBatch(BatchExecutionMode mode)
the result into.
To bind a NULL value, use a null QVariant; for example, use
- \c {QVariant(QMetaType::QString)} if you are binding a string.
+ \c {QVariant(QMetaType::fromType<QString>())} if you are binding a string.
\sa addBindValue(), prepare(), exec(), boundValue(), boundValues()
*/
@@ -1115,7 +1135,7 @@ void QSqlQuery::bindValue(int pos, const QVariant& val, QSql::ParamType paramTyp
overwritten with data from the database after the exec() call.
To bind a NULL value, use a null QVariant; for example, use \c
- {QVariant(QMetaType::QString)} if you are binding a string.
+ {QVariant(QMetaType::fromType<QString>())} if you are binding a string.
\sa bindValue(), prepare(), exec(), boundValue(), boundValues()
*/
@@ -1136,6 +1156,7 @@ QVariant QSqlQuery::boundValue(const QString& placeholder) const
/*!
Returns the value for the placeholder at position \a pos.
+ \sa boundValues()
*/
QVariant QSqlQuery::boundValue(int pos) const
{
@@ -1154,7 +1175,7 @@ QVariant QSqlQuery::boundValue(int pos) const
\snippet sqldatabase/sqldatabase.cpp 14
- \sa boundValue(), bindValue(), addBindValue()
+ \sa boundValue(), bindValue(), addBindValue(), boundValueNames()
*/
QVariantList QSqlQuery::boundValues() const
@@ -1164,6 +1185,36 @@ QVariantList QSqlQuery::boundValues() const
}
/*!
+ \since 6.6
+
+ Returns the names of all bound values.
+
+ The order of the list is in binding order, irrespective of whether
+ named or positional binding is used.
+
+ \sa boundValues(), boundValueName()
+*/
+QStringList QSqlQuery::boundValueNames() const
+{
+ return d->sqlResult->boundValueNames();
+}
+
+/*!
+ \since 6.6
+
+ Returns the bound value name at position \a pos.
+
+ The order of the list is in binding order, irrespective of whether
+ named or positional binding is used.
+
+ \sa boundValueNames()
+*/
+QString QSqlQuery::boundValueName(int pos) const
+{
+ return d->sqlResult->boundValueName(pos);
+}
+
+/*!
Returns the last query that was successfully executed.
In most cases this function returns the same string as lastQuery().
@@ -1189,7 +1240,7 @@ QString QSqlQuery::executedQuery() const
For MySQL databases the row's auto-increment field will be returned.
- \note For this function to work in PSQL, the table table must
+ \note For this function to work in PSQL, the table must
contain OIDs, which may not have been created by default. Check the
\c default_with_oids configuration variable to be sure.
@@ -1201,6 +1252,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.
@@ -1219,17 +1272,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
{
@@ -1237,8 +1292,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
@@ -1260,8 +1348,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
@@ -1287,7 +1373,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()
@@ -1298,3 +1384,5 @@ bool QSqlQuery::nextResult()
}
QT_END_NAMESPACE
+
+#include "moc_qsqlquery.cpp"