summaryrefslogtreecommitdiffstats
path: root/src/sql/drivers/sqlite/qsql_sqlite.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sql/drivers/sqlite/qsql_sqlite.cpp')
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.cpp125
1 files changed, 73 insertions, 52 deletions
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp
index 4286f5b338..2a45b73d14 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.cpp
+++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** 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:LGPL21$
+** $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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** 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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** 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$
**
@@ -105,8 +111,9 @@ class QSQLiteResultPrivate;
class QSQLiteResult : public QSqlCachedResult
{
+ Q_DECLARE_PRIVATE(QSQLiteResult)
friend class QSQLiteDriver;
- friend class QSQLiteResultPrivate;
+
public:
explicit QSQLiteResult(const QSQLiteDriver* db);
~QSQLiteResult();
@@ -123,13 +130,12 @@ protected:
QSqlRecord record() const Q_DECL_OVERRIDE;
void detachFromResultSet() Q_DECL_OVERRIDE;
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
-
-private:
- QSQLiteResultPrivate* d;
};
class QSQLiteDriverPrivate : public QSqlDriverPrivate
{
+ Q_DECLARE_PUBLIC(QSQLiteDriver)
+
public:
inline QSQLiteDriverPrivate() : QSqlDriverPrivate(), access(0) { dbmsType = QSqlDriver::SQLite; }
sqlite3 *access;
@@ -137,19 +143,19 @@ public:
};
-class QSQLiteResultPrivate
+class QSQLiteResultPrivate: public QSqlCachedResultPrivate
{
+ Q_DECLARE_PUBLIC(QSQLiteResult)
+
public:
- QSQLiteResultPrivate(QSQLiteResult *res);
+ Q_DECLARE_SQLDRIVER_PRIVATE(QSQLiteDriver)
+ QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv);
void cleanup();
bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
// initializes the recordInfo and the cache
void initColumns(bool emptyResultset);
void finalize();
- QSQLiteResult* q;
- sqlite3 *access;
-
sqlite3_stmt *stmt;
bool skippedStatus; // the status of the fetchNext() that's skipped
@@ -158,13 +164,17 @@ public:
QVector<QVariant> firstRow;
};
-QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult* res) : q(res), access(0),
- stmt(0), skippedStatus(false), skipRow(false)
+QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv)
+ : QSqlCachedResultPrivate(q, drv),
+ stmt(0),
+ skippedStatus(false),
+ skipRow(false)
{
}
void QSQLiteResultPrivate::cleanup()
{
+ Q_Q(QSQLiteResult);
finalize();
rInf.clear();
skippedStatus = false;
@@ -185,6 +195,7 @@ void QSQLiteResultPrivate::finalize()
void QSQLiteResultPrivate::initColumns(bool emptyResultset)
{
+ Q_Q(QSQLiteResult);
int nCols = sqlite3_column_count(stmt);
if (nCols <= 0)
return;
@@ -236,6 +247,7 @@ void QSQLiteResultPrivate::initColumns(bool emptyResultset)
bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch)
{
+ Q_Q(QSQLiteResult);
int res;
int i;
@@ -318,7 +330,7 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i
// SQLITE_ERROR is a generic error code and we must call sqlite3_reset()
// to get the specific error message.
res = sqlite3_reset(stmt);
- q->setLastError(qMakeError(access, QCoreApplication::translate("QSQLiteResult",
+ q->setLastError(qMakeError(drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to fetch row"), QSqlError::ConnectionError, res));
q->setAt(QSql::AfterLastRow);
return false;
@@ -326,7 +338,7 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i
case SQLITE_BUSY:
default:
// something wrong, don't get col info, but still return false
- q->setLastError(qMakeError(access, QCoreApplication::translate("QSQLiteResult",
+ q->setLastError(qMakeError(drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to fetch row"), QSqlError::ConnectionError, res));
sqlite3_reset(stmt);
q->setAt(QSql::AfterLastRow);
@@ -336,20 +348,18 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i
}
QSQLiteResult::QSQLiteResult(const QSQLiteDriver* db)
- : QSqlCachedResult(db)
+ : QSqlCachedResult(*new QSQLiteResultPrivate(this, db))
{
- d = new QSQLiteResultPrivate(this);
- d->access = db->d_func()->access;
- const_cast<QSQLiteDriverPrivate*>(db->d_func())->results.append(this);
+ Q_D(QSQLiteResult);
+ const_cast<QSQLiteDriverPrivate*>(d->drv_d_func())->results.append(this);
}
QSQLiteResult::~QSQLiteResult()
{
- const QSqlDriver *sqlDriver = driver();
- if (sqlDriver)
- const_cast<QSQLiteDriverPrivate*>(qobject_cast<const QSQLiteDriver *>(sqlDriver)->d_func())->results.removeOne(this);
+ Q_D(QSQLiteResult);
+ if (d->drv_d_func())
+ const_cast<QSQLiteDriverPrivate*>(d->drv_d_func())->results.removeOne(this);
d->cleanup();
- delete d;
}
void QSQLiteResult::virtual_hook(int id, void *data)
@@ -366,6 +376,7 @@ bool QSQLiteResult::reset(const QString &query)
bool QSQLiteResult::prepare(const QString &query)
{
+ Q_D(QSQLiteResult);
if (!driver() || !driver()->isOpen() || driver()->isOpenError())
return false;
@@ -376,7 +387,7 @@ bool QSQLiteResult::prepare(const QString &query)
const void *pzTail = NULL;
#if (SQLITE_VERSION_NUMBER >= 3003011)
- int res = sqlite3_prepare16_v2(d->access, query.constData(), (query.size() + 1) * sizeof(QChar),
+ int res = sqlite3_prepare16_v2(d->drv_d_func()->access, query.constData(), (query.size() + 1) * sizeof(QChar),
&d->stmt, &pzTail);
#else
int res = sqlite3_prepare16(d->access, query.constData(), (query.size() + 1) * sizeof(QChar),
@@ -384,12 +395,12 @@ bool QSQLiteResult::prepare(const QString &query)
#endif
if (res != SQLITE_OK) {
- setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
+ setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to execute statement"), QSqlError::StatementError, res));
d->finalize();
return false;
} else if (pzTail && !QString(reinterpret_cast<const QChar *>(pzTail)).trimmed().isEmpty()) {
- setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
+ setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to execute multiple statements at a time"), QSqlError::StatementError, SQLITE_MISUSE));
d->finalize();
return false;
@@ -399,6 +410,7 @@ bool QSQLiteResult::prepare(const QString &query)
bool QSQLiteResult::exec()
{
+ Q_D(QSQLiteResult);
const QVector<QVariant> values = boundValues();
d->skippedStatus = false;
@@ -409,7 +421,7 @@ bool QSQLiteResult::exec()
int res = sqlite3_reset(d->stmt);
if (res != SQLITE_OK) {
- setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
+ setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to reset statement"), QSqlError::StatementError, res));
d->finalize();
return false;
@@ -469,7 +481,7 @@ bool QSQLiteResult::exec()
}
}
if (res != SQLITE_OK) {
- setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
+ setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to bind parameters"), QSqlError::StatementError, res));
d->finalize();
return false;
@@ -493,6 +505,7 @@ bool QSQLiteResult::exec()
bool QSQLiteResult::gotoNext(QSqlCachedResult::ValueCache& row, int idx)
{
+ Q_D(QSQLiteResult);
return d->fetchNext(row, idx, false);
}
@@ -503,13 +516,15 @@ int QSQLiteResult::size()
int QSQLiteResult::numRowsAffected()
{
- return sqlite3_changes(d->access);
+ Q_D(const QSQLiteResult);
+ return sqlite3_changes(d->drv_d_func()->access);
}
QVariant QSQLiteResult::lastInsertId() const
{
+ Q_D(const QSQLiteResult);
if (isActive()) {
- qint64 id = sqlite3_last_insert_rowid(d->access);
+ qint64 id = sqlite3_last_insert_rowid(d->drv_d_func()->access);
if (id)
return id;
}
@@ -518,6 +533,7 @@ QVariant QSQLiteResult::lastInsertId() const
QSqlRecord QSQLiteResult::record() const
{
+ Q_D(const QSQLiteResult);
if (!isActive() || !isSelect())
return QSqlRecord();
return d->rInf;
@@ -525,12 +541,14 @@ QSqlRecord QSQLiteResult::record() const
void QSQLiteResult::detachFromResultSet()
{
+ Q_D(QSQLiteResult);
if (d->stmt)
sqlite3_reset(d->stmt);
}
QVariant QSQLiteResult::handle() const
{
+ Q_D(const QSQLiteResult);
return QVariant::fromValue(d->stmt);
}
@@ -595,13 +613,17 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c
bool openReadOnlyOption = false;
bool openUriOption = false;
- const QStringList opts = QString(conOpts).remove(QLatin1Char(' ')).split(QLatin1Char(';'));
- foreach (const QString &option, opts) {
- if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) {
- bool ok;
- const int nt = option.midRef(21).toInt(&ok);
- if (ok)
- timeOut = nt;
+ const auto opts = conOpts.splitRef(QLatin1Char(';'));
+ for (auto option : opts) {
+ option = option.trimmed();
+ if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT"))) {
+ option = option.mid(20).trimmed();
+ if (option.startsWith(QLatin1Char('='))) {
+ bool ok;
+ const int nt = option.mid(1).trimmed().toInt(&ok);
+ if (ok)
+ timeOut = nt;
+ }
} else if (option == QLatin1String("QSQLITE_OPEN_READONLY")) {
openReadOnlyOption = true;
} else if (option == QLatin1String("QSQLITE_OPEN_URI")) {
@@ -639,9 +661,8 @@ void QSQLiteDriver::close()
{
Q_D(QSQLiteDriver);
if (isOpen()) {
- foreach (QSQLiteResult *result, d->results) {
- result->d->finalize();
- }
+ for (QSQLiteResult *result : qAsConst(d->results))
+ result->d_func()->finalize();
if (sqlite3_close(d->access) != SQLITE_OK)
setLastError(qMakeError(d->access, tr("Error closing database"),