diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-02-13 11:58:07 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-02-14 14:24:57 +0100 |
commit | e65cd6f3794e12e6bc5c2ee985eae8e70ff5f333 (patch) | |
tree | 8965835c375422d63b2ccfa927b31a56e64bda1d /src/sql | |
parent | d1ee7189553e13337b198fe4ba66d79fb7a7f41d (diff) | |
parent | e95a758236cf2c68e33da4ddb62bff4fe8d9dd8b (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.qdocconf | 12 | ||||
-rw-r--r-- | src/sql/drivers/mysql/qsql_mysql.pri | 2 | ||||
-rw-r--r-- | src/sql/drivers/psql/qsql_psql.cpp | 3 | ||||
-rw-r--r-- | src/sql/drivers/psql/qsql_psql.pri | 2 | ||||
-rw-r--r-- | src/sql/drivers/sqlite/qsql_sqlite.pri | 2 | ||||
-rw-r--r-- | src/sql/drivers/tds/qsql_tds.pri | 2 | ||||
-rw-r--r-- | src/sql/kernel/kernel.pri | 1 | ||||
-rw-r--r-- | src/sql/kernel/qsqldatabase.cpp | 3 | ||||
-rw-r--r-- | src/sql/kernel/qsqlresult.cpp | 111 | ||||
-rw-r--r-- | src/sql/kernel/qsqlresult_p.h | 138 | ||||
-rw-r--r-- | src/sql/models/qsqlquerymodel.cpp | 21 | ||||
-rw-r--r-- | src/sql/models/qsqlquerymodel_p.h | 1 | ||||
-rw-r--r-- | src/sql/models/qsqltablemodel.cpp | 25 | ||||
-rw-r--r-- | src/sql/models/qsqltablemodel_p.h | 1 |
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 }; |