summaryrefslogtreecommitdiffstats
path: root/src/sql
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-02-13 11:58:07 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-02-14 14:24:57 +0100
commite65cd6f3794e12e6bc5c2ee985eae8e70ff5f333 (patch)
tree8965835c375422d63b2ccfa927b31a56e64bda1d /src/sql
parentd1ee7189553e13337b198fe4ba66d79fb7a7f41d (diff)
parente95a758236cf2c68e33da4ddb62bff4fe8d9dd8b (diff)
Merge remote-tracking branch 'origin/stable' into dev
Conflicts: src/concurrent/doc/qtconcurrent.qdocconf src/corelib/doc/qtcore.qdocconf src/corelib/global/qglobal.h src/dbus/doc/qtdbus.qdocconf src/dbus/qdbusmessage.h src/gui/doc/qtgui.qdocconf src/gui/image/qimagereader.cpp src/network/doc/qtnetwork.qdocconf src/opengl/doc/qtopengl.qdocconf src/opengl/qgl.h src/plugins/platforms/windows/qwindowswindow.cpp src/printsupport/doc/qtprintsupport.qdocconf src/sql/doc/qtsql.qdocconf src/testlib/doc/qttestlib.qdocconf src/tools/qdoc/doc/config/qt-cpp-ignore.qdocconf src/widgets/doc/qtwidgets.qdocconf src/xml/doc/qtxml.qdocconf Change-Id: Ie9a1fa2cc44bec22a0b942e817a1095ca3414629
Diffstat (limited to 'src/sql')
-rw-r--r--src/sql/doc/qtsql.qdocconf12
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.pri2
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp3
-rw-r--r--src/sql/drivers/psql/qsql_psql.pri2
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.pri2
-rw-r--r--src/sql/drivers/tds/qsql_tds.pri2
-rw-r--r--src/sql/kernel/kernel.pri1
-rw-r--r--src/sql/kernel/qsqldatabase.cpp3
-rw-r--r--src/sql/kernel/qsqlresult.cpp111
-rw-r--r--src/sql/kernel/qsqlresult_p.h138
-rw-r--r--src/sql/models/qsqlquerymodel.cpp21
-rw-r--r--src/sql/models/qsqlquerymodel_p.h1
-rw-r--r--src/sql/models/qsqltablemodel.cpp25
-rw-r--r--src/sql/models/qsqltablemodel_p.h1
14 files changed, 196 insertions, 128 deletions
diff --git a/src/sql/doc/qtsql.qdocconf b/src/sql/doc/qtsql.qdocconf
index 19dd9eae1e..e53bd50b55 100644
--- a/src/sql/doc/qtsql.qdocconf
+++ b/src/sql/doc/qtsql.qdocconf
@@ -2,22 +2,22 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
project = QtSql
description = Qt SQL Reference Documentation
-url = http://qt-project.org/doc/qtsql
-version = 5.1.0
+url = http://qt-project.org/doc/qt-$QT_VER/qtsql
+version = $QT_VERSION
examplesinstallpath = sql
qhp.projects = QtSql
qhp.QtSql.file = qtsql.qhp
-qhp.QtSql.namespace = org.qt-project.qtsql.510
+qhp.QtSql.namespace = org.qt-project.qtsql.$QT_VERSION_TAG
qhp.QtSql.virtualFolder = qtsql
qhp.QtSql.indexTitle = Qt SQL
qhp.QtSql.indexRoot =
-qhp.QtSql.filterAttributes = qtsql 5.1.0 qtrefdoc
-qhp.QtSql.customFilters.Qt.name = QtSql 5.1.0
-qhp.QtSql.customFilters.Qt.filterAttributes = qtsql 5.1.0
+qhp.QtSql.filterAttributes = qtsql $QT_VERSION qtrefdoc
+qhp.QtSql.customFilters.Qt.name = QtSql $QT_VERSION
+qhp.QtSql.customFilters.Qt.filterAttributes = qtsql $QT_VERSION
qhp.QtSql.subprojects = classes
qhp.QtSql.subprojects.classes.title = C++ Classes
diff --git a/src/sql/drivers/mysql/qsql_mysql.pri b/src/sql/drivers/mysql/qsql_mysql.pri
index c9ec2575fa..0423eb4ed9 100644
--- a/src/sql/drivers/mysql/qsql_mysql.pri
+++ b/src/sql/drivers/mysql/qsql_mysql.pri
@@ -13,7 +13,7 @@ unix {
else:LIBS += -lmysqlclient
}
} else {
- LIBS *= $$QT_LFLAGS_MYSQL
+ LIBS += $$QT_LFLAGS_MYSQL
QMAKE_CXXFLAGS *= $$QT_CFLAGS_MYSQL
}
} else {
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index 678e83690a..1d96e9f93b 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -1208,8 +1208,7 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
if (field.value().toDateTime().isValid()) {
QDate dt = field.value().toDateTime().date();
QTime tm = field.value().toDateTime().time();
- // msecs need to be right aligned otherwise psql
- // interpretes them wrong
+ // msecs need to be right aligned otherwise psql interprets them wrong
r = QLatin1Char('\'') + QString::number(dt.year()) + QLatin1Char('-')
+ QString::number(dt.month()) + QLatin1Char('-')
+ QString::number(dt.day()) + QLatin1Char(' ')
diff --git a/src/sql/drivers/psql/qsql_psql.pri b/src/sql/drivers/psql/qsql_psql.pri
index 6da3540104..9b647d8200 100644
--- a/src/sql/drivers/psql/qsql_psql.pri
+++ b/src/sql/drivers/psql/qsql_psql.pri
@@ -2,7 +2,7 @@ HEADERS += $$PWD/qsql_psql.h
SOURCES += $$PWD/qsql_psql.cpp
unix|win32-g++* {
- LIBS *= $$QT_LFLAGS_PSQL
+ LIBS += $$QT_LFLAGS_PSQL
!contains(LIBS, .*pq.*):LIBS += -lpq
QMAKE_CXXFLAGS *= $$QT_CFLAGS_PSQL
} else {
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.pri b/src/sql/drivers/sqlite/qsql_sqlite.pri
index 7ad5936e25..a2e80d4c74 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.pri
+++ b/src/sql/drivers/sqlite/qsql_sqlite.pri
@@ -4,6 +4,6 @@ SOURCES += $$PWD/qsql_sqlite.cpp
!system-sqlite:!contains(LIBS, .*sqlite3.*) {
include($$PWD/../../../3rdparty/sqlite.pri)
} else {
- LIBS *= $$QT_LFLAGS_SQLITE
+ LIBS += $$QT_LFLAGS_SQLITE
QMAKE_CXXFLAGS *= $$QT_CFLAGS_SQLITE
}
diff --git a/src/sql/drivers/tds/qsql_tds.pri b/src/sql/drivers/tds/qsql_tds.pri
index 3b5a6895c9..38aab2f3e4 100644
--- a/src/sql/drivers/tds/qsql_tds.pri
+++ b/src/sql/drivers/tds/qsql_tds.pri
@@ -2,7 +2,7 @@ HEADERS += $$PWD/qsql_tds.h
SOURCES += $$PWD/qsql_tds.cpp
unix|win32-g++*: {
- LIBS *= $$QT_LFLAGS_TDS
+ LIBS += $$QT_LFLAGS_TDS
!contains(LIBS, .*sybdb.*):LIBS += -lsybdb
QMAKE_CXXFLAGS *= $$QT_CFLAGS_TDS
} else {
diff --git a/src/sql/kernel/kernel.pri b/src/sql/kernel/kernel.pri
index c6fe404737..fe7f1270f9 100644
--- a/src/sql/kernel/kernel.pri
+++ b/src/sql/kernel/kernel.pri
@@ -8,6 +8,7 @@ HEADERS += kernel/qsql.h \
kernel/qsqldriverplugin.h \
kernel/qsqlerror.h \
kernel/qsqlresult.h \
+ kernel/qsqlresult_p.h \
kernel/qsqlcachedresult_p.h \
kernel/qsqlindex.h
diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp
index 4f59855ac2..36422f5f62 100644
--- a/src/sql/kernel/qsqldatabase.cpp
+++ b/src/sql/kernel/qsqldatabase.cpp
@@ -794,9 +794,6 @@ void QSqlDatabasePrivate::init(const QString &type)
/*!
Destroys the object and frees any allocated resources.
- If this is the last QSqlDatabase object that uses a certain
- database connection, the database connection is automatically closed.
-
\sa close()
*/
diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp
index 3a45ccbcce..b3e7ad5b38 100644
--- a/src/sql/kernel/qsqlresult.cpp
+++ b/src/sql/kernel/qsqlresult.cpp
@@ -50,78 +50,11 @@
#include "qvector.h"
#include "qsqldriver.h"
#include "qpointer.h"
+#include "qsqlresult_p.h"
#include <QDebug>
QT_BEGIN_NAMESPACE
-struct QHolder {
- QHolder(const QString& hldr = QString(), int index = -1): holderName(hldr), holderPos(index) {}
- bool operator==(const QHolder& h) const { return h.holderPos == holderPos && h.holderName == holderName; }
- bool operator!=(const QHolder& h) const { return h.holderPos != holderPos || h.holderName != holderName; }
- QString holderName;
- int holderPos;
-};
-
-class QSqlResultPrivate
-{
-public:
- QSqlResultPrivate(QSqlResult* d)
- : q(d), idx(QSql::BeforeFirstRow), active(false),
- isSel(false), forwardOnly(false), precisionPolicy(QSql::LowPrecisionDouble), bindCount(0), binds(QSqlResult::PositionalBinding)
- {}
-
- void clearValues()
- {
- values.clear();
- bindCount = 0;
- }
-
- void resetBindCount()
- {
- bindCount = 0;
- }
-
- void clearIndex()
- {
- indexes.clear();
- holders.clear();
- types.clear();
- }
-
- void clear()
- {
- clearValues();
- clearIndex();;
- }
-
- QString positionalToNamedBinding();
- QString namedToPositionalBinding();
- QString holderAt(int index) const;
-
-public:
- QSqlResult* q;
- QPointer<QSqlDriver> sqldriver;
- int idx;
- QString sql;
- bool active;
- bool isSel;
- QSqlError error;
- bool forwardOnly;
- QSql::NumericalPrecisionPolicy precisionPolicy;
-
- int bindCount;
- QSqlResult::BindingSyntax binds;
-
- QString executedQuery;
- QHash<int, QSql::ParamType> types;
- QVector<QVariant> values;
- typedef QHash<QString, QList<int> > IndexMap;
- IndexMap indexes;
-
- typedef QVector<QHolder> QHolderVector;
- QHolderVector holders;
-};
-
static QString qFieldSerial(int);
QString QSqlResultPrivate::holderAt(int index) const
@@ -584,6 +517,8 @@ void QSqlResult::setForwardOnly(bool forward)
functionality where possible. Returns true if the query is
prepared successfully; otherwise returns false.
+ Note: This method should have been called "safePrepare()".
+
\sa prepare()
*/
bool QSqlResult::savePrepare(const QString& query)
@@ -595,13 +530,12 @@ bool QSqlResult::savePrepare(const QString& query)
if (!driver()->hasFeature(QSqlDriver::PreparedQueries))
return prepare(query);
- if (driver()->hasFeature(QSqlDriver::NamedPlaceholders)) {
- // parse the query to memorize parameter location
- d->namedToPositionalBinding();
+ // parse the query to memorize parameter location
+ d->executedQuery = d->namedToPositionalBinding();
+
+ if (driver()->hasFeature(QSqlDriver::NamedPlaceholders))
d->executedQuery = d->positionalToNamedBinding();
- } else {
- d->executedQuery = d->namedToPositionalBinding();
- }
+
return prepare(d->executedQuery);
}
@@ -614,34 +548,11 @@ bool QSqlResult::savePrepare(const QString& query)
*/
bool QSqlResult::prepare(const QString& query)
{
+ d->sql = query;
if (d->holders.isEmpty()) {
- int n = query.size();
-
- bool inQuote = false;
- int i = 0;
-
- while (i < n) {
- QChar ch = query.at(i);
- if (ch == QLatin1Char(':') && !inQuote
- && (i == 0 || query.at(i - 1) != QLatin1Char(':'))
- && (i + 1 < n && qIsAlnum(query.at(i + 1)))) {
- int pos = i + 2;
- while (pos < n && qIsAlnum(query.at(pos)))
- ++pos;
-
- QString holder(query.mid(i, pos - i));
- d->indexes[holder].append(d->holders.size());
- d->holders.append(QHolder(holder, i));
- i = pos;
- } else {
- if (ch == QLatin1Char('\''))
- inQuote = !inQuote;
- ++i;
- }
- }
- d->values.resize(d->holders.size());
+ // parse the query to memorize parameter location
+ d->namedToPositionalBinding();
}
- d->sql = query;
return true; // fake prepares should always succeed
}
diff --git a/src/sql/kernel/qsqlresult_p.h b/src/sql/kernel/qsqlresult_p.h
new file mode 100644
index 0000000000..65f9be7a05
--- /dev/null
+++ b/src/sql/kernel/qsqlresult_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt 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 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSQLRESULT_P_H
+#define QSQLRESULT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qsql*model.h . This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qpointer.h>
+#include <QtSql/qsqldriver.h>
+#include "qsqlerror.h"
+#include "qsqlresult.h"
+
+QT_BEGIN_NAMESPACE
+
+struct QHolder {
+ QHolder(const QString &hldr = QString(), int index = -1): holderName(hldr), holderPos(index) { }
+ bool operator==(const QHolder &h) const { return h.holderPos == holderPos && h.holderName == holderName; }
+ bool operator!=(const QHolder &h) const { return h.holderPos != holderPos || h.holderName != holderName; }
+ QString holderName;
+ int holderPos;
+};
+
+class Q_SQL_EXPORT QSqlResultPrivate
+{
+public:
+ QSqlResultPrivate(QSqlResult *d)
+ : q(d),
+ idx(QSql::BeforeFirstRow),
+ active(false),
+ isSel(false),
+ forwardOnly(false),
+ precisionPolicy(QSql::LowPrecisionDouble),
+ bindCount(0),
+ binds(QSqlResult::PositionalBinding)
+ { }
+
+ void clearValues()
+ {
+ values.clear();
+ bindCount = 0;
+ }
+
+ void resetBindCount()
+ {
+ bindCount = 0;
+ }
+
+ void clearIndex()
+ {
+ indexes.clear();
+ holders.clear();
+ types.clear();
+ }
+
+ void clear()
+ {
+ clearValues();
+ clearIndex();;
+ }
+
+ QString positionalToNamedBinding();
+ QString namedToPositionalBinding();
+ QString holderAt(int index) const;
+
+ QSqlResult *q;
+ QPointer<QSqlDriver> sqldriver;
+ int idx;
+ QString sql;
+ bool active;
+ bool isSel;
+ QSqlError error;
+ bool forwardOnly;
+ QSql::NumericalPrecisionPolicy precisionPolicy;
+
+ int bindCount;
+ QSqlResult::BindingSyntax binds;
+
+ QString executedQuery;
+ QHash<int, QSql::ParamType> types;
+ QVector<QVariant> values;
+ typedef QHash<QString, QList<int> > IndexMap;
+ IndexMap indexes;
+
+ typedef QVector<QHolder> QHolderVector;
+ QHolderVector holders;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSQLRESULT_P_H
diff --git a/src/sql/models/qsqlquerymodel.cpp b/src/sql/models/qsqlquerymodel.cpp
index 59103b72d3..00fc410ca5 100644
--- a/src/sql/models/qsqlquerymodel.cpp
+++ b/src/sql/models/qsqlquerymodel.cpp
@@ -95,6 +95,13 @@ void QSqlQueryModelPrivate::initColOffsets(int size)
memset(colOffsets.data(), 0, colOffsets.size() * sizeof(int));
}
+int QSqlQueryModelPrivate::columnInQuery(int modelColumn) const
+{
+ if (modelColumn < 0 || modelColumn >= rec.count() || !rec.isGenerated(modelColumn) || modelColumn >= colOffsets.size())
+ return -1;
+ return modelColumn - colOffsets[modelColumn];
+}
+
/*!
\class QSqlQueryModel
\brief The QSqlQueryModel class provides a read-only data model for SQL
@@ -370,11 +377,7 @@ QVariant QSqlQueryModel::headerData(int section, Qt::Orientation orientation, in
val = d->headers.value(section).value(Qt::EditRole);
if (val.isValid())
return val;
-
- // See if it's an inserted column (iiq.column() != -1)
- QModelIndex dItem = indexInQuery(createIndex(0, section));
-
- if (role == Qt::DisplayRole && d->rec.count() > section && dItem.column() != -1)
+ if (role == Qt::DisplayRole && d->rec.count() > section && d->columnInQuery(section) != -1)
return d->rec.fieldName(section);
}
return QAbstractItemModel::headerData(section, orientation, role);
@@ -668,12 +671,10 @@ bool QSqlQueryModel::removeColumns(int column, int count, const QModelIndex &par
QModelIndex QSqlQueryModel::indexInQuery(const QModelIndex &item) const
{
Q_D(const QSqlQueryModel);
- if (item.column() < 0 || item.column() >= d->rec.count()
- || !d->rec.isGenerated(item.column())
- || item.column() >= d->colOffsets.size())
+ int modelColumn = d->columnInQuery(item.column());
+ if (modelColumn < 0)
return QModelIndex();
- return createIndex(item.row(), item.column() - d->colOffsets[item.column()],
- item.internalPointer());
+ return createIndex(item.row(), modelColumn, item.internalPointer());
}
QT_END_NAMESPACE
diff --git a/src/sql/models/qsqlquerymodel_p.h b/src/sql/models/qsqlquerymodel_p.h
index ecf69003f4..a79b62cda1 100644
--- a/src/sql/models/qsqlquerymodel_p.h
+++ b/src/sql/models/qsqlquerymodel_p.h
@@ -72,6 +72,7 @@ public:
void prefetch(int);
void initColOffsets(int size);
+ int columnInQuery(int modelColumn) const;
mutable QSqlQuery query;
mutable QSqlError error;
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 32dd517a7a..2e395b0a59 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -355,6 +355,16 @@ void QSqlTableModel::setTable(const QString &tableName)
if (d->rec.count() == 0)
d->error = QSqlError(QLatin1String("Unable to find table ") + d->tableName, QString(),
QSqlError::StatementError);
+
+ // Remember the auto index column if there is one now.
+ // The record that will be obtained from the query after select lacks this feature.
+ d->autoColumn.clear();
+ for (int c = 0; c < d->rec.count(); ++c) {
+ if (d->rec.field(c).isAutoValue()) {
+ d->autoColumn = d->rec.fieldName(c);
+ break;
+ }
+ }
}
/*!
@@ -587,7 +597,10 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in
if (!(flags(index) & Qt::ItemIsEditable))
return false;
- if (QSqlTableModel::data(index, role) == value)
+ const QVariant oldValue = QSqlTableModel::data(index, role);
+ if (value == oldValue
+ && value.isNull() == oldValue.isNull()
+ && d->cache.value(index.row()).op() != QSqlTableModelPrivate::Insert)
return true;
QSqlTableModelPrivate::ModifiedRow &row = d->cache[index.row()];
@@ -772,6 +785,11 @@ bool QSqlTableModel::submitAll()
}
if (success) {
+ if (d->strategy != OnManualSubmit && mrow.op() == QSqlTableModelPrivate::Insert) {
+ int c = mrow.rec().indexOf(d->autoColumn);
+ if (c != -1 && !mrow.rec().isGenerated(c))
+ mrow.setValue(c, d->editQuery.lastInsertId());
+ }
mrow.setSubmitted();
if (d->strategy != OnManualSubmit)
success = selectRow(row);
@@ -821,7 +839,8 @@ bool QSqlTableModel::submit()
user canceled editing the current row.
Reverts the changes if the model's strategy is set to
- OnRowChange. Does nothing for the other edit strategies.
+ OnRowChange or OnFieldChange. Does nothing for the OnManualSubmit
+ strategy.
Use revertAll() to revert all pending changes for the
OnManualSubmit strategy or revertRow() to revert a specific row.
@@ -831,7 +850,7 @@ bool QSqlTableModel::submit()
void QSqlTableModel::revert()
{
Q_D(QSqlTableModel);
- if (d->strategy == OnRowChange)
+ if (d->strategy == OnRowChange || d->strategy == OnFieldChange)
revertAll();
}
diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h
index 56db09b7e0..825490ea39 100644
--- a/src/sql/models/qsqltablemodel_p.h
+++ b/src/sql/models/qsqltablemodel_p.h
@@ -96,6 +96,7 @@ public:
QSqlIndex primaryIndex;
QString tableName;
QString filter;
+ QString autoColumn;
enum Op { None, Insert, Update, Delete };