diff options
author | Honglei Zhang <honglei.zhang@nokia.com> | 2011-11-30 11:26:22 (GMT) |
---|---|---|
committer | Honglei Zhang <honglei.zhang@nokia.com> | 2011-11-30 11:26:22 (GMT) |
commit | 1ba0ce0cc1ab94f1397114ac8024a60dc7dfbdd8 (patch) | |
tree | 2fe5fe727fe3811a1b4cb83b053780a5c166f714 | |
parent | 20a154ffc3afacdbc22d00a3c4dd0a2916a14e33 (diff) | |
download | Qt-1ba0ce0cc1ab94f1397114ac8024a60dc7dfbdd8.zip Qt-1ba0ce0cc1ab94f1397114ac8024a60dc7dfbdd8.tar.gz Qt-1ba0ce0cc1ab94f1397114ac8024a60dc7dfbdd8.tar.bz2 |
QSQLITE support only one statement at a time
SQLite driver support only one statement at a time. This fix makes the
exec and prepare call failed if more than one statements are given.
This is bug fix for QTBUG-21884. Also the behaviour is documented in
the API specification.
Task-number: QTBUG-21884
Reviewed-by: Charles Yin
-rw-r--r-- | src/sql/drivers/sqlite/qsql_sqlite.cpp | 11 | ||||
-rw-r--r-- | src/sql/kernel/qsqlquery.cpp | 6 | ||||
-rw-r--r-- | tests/auto/qsqlquery/tst_qsqlquery.cpp | 47 |
3 files changed, 62 insertions, 2 deletions
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index 9fba6d6..8294a55 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -322,12 +322,14 @@ bool QSQLiteResult::prepare(const QString &query) setSelect(false); + const void *pzTail = NULL; + #if (SQLITE_VERSION_NUMBER >= 3003011) int res = sqlite3_prepare16_v2(d->access, query.constData(), (query.size() + 1) * sizeof(QChar), - &d->stmt, 0); + &d->stmt, &pzTail); #else int res = sqlite3_prepare16(d->access, query.constData(), (query.size() + 1) * sizeof(QChar), - &d->stmt, 0); + &d->stmt, &pzTail); #endif if (res != SQLITE_OK) { @@ -335,6 +337,11 @@ bool QSQLiteResult::prepare(const QString &query) "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", + "Unable to execute multiple statements at a time"), QSqlError::StatementError, SQLITE_MISUSE)); + d->finalize(); + return false; } return true; } diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp index 361730a..753e4f8 100644 --- a/src/sql/kernel/qsqlquery.cpp +++ b/src/sql/kernel/qsqlquery.cpp @@ -338,6 +338,9 @@ bool QSqlQuery::isNull(int field) const Note that the last error for this query is reset when exec() is called. + For SQLite, the query string can contain only one statement at a time. + If more than one statements is give, the function returns false. + Example: \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 34 @@ -887,6 +890,9 @@ void QSqlQuery::clear() syntactically wrong query succeeds, but every consecutive exec() will fail. + For SQLite, the query string can contain only one statement at a time. + If more than one statements are give, the function returns false. + Example: \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 9 diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 592b49a..3cbdb63 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -213,6 +213,8 @@ private slots: void QTBUG_5765(); void QTBUG_14132_data() { generic_data("QOCI"); } void QTBUG_14132(); + void QTBUG_21884_data() { generic_data("QSQLITE"); } + void QTBUG_21884(); void sqlite_constraint_data() { generic_data("QSQLITE"); } void sqlite_constraint(); @@ -328,6 +330,7 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) << qTableName("bug6421", __FILE__).toUpper() << qTableName("bug5765", __FILE__) << qTableName("bug6852", __FILE__) + << qTableName("bug21884", __FILE__) << qTableName( "qtest_lockedtable", __FILE__ ) << qTableName( "Planet", __FILE__ ) << qTableName( "task_250026", __FILE__ ) @@ -3104,6 +3107,50 @@ void tst_QSqlQuery::QTBUG_5765() QCOMPARE(q.value(0).toInt(), 123); } +/** +* This test case tests multiple statements in one execution. +* Sqlite driver doesn't support multiple statement at one time. +* If more than one statement is given, the exec or prepare function +* return failure to the client. +*/ +void tst_QSqlQuery::QTBUG_21884() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QSqlQuery q(db); + + QStringList stList; + QString tableName(qTableName("bug21884", __FILE__ )); + stList << "create table " + tableName + "(id integer primary key, note string)"; + stList << "select * from " + tableName + ";"; + stList << "select * from " + tableName + "; \t\n\r"; + stList << "drop table " + tableName; + + + foreach (const QString& st, stList) { + QVERIFY_SQL(q, exec(st)); + } + + foreach (const QString& st, stList) { + QVERIFY_SQL(q, prepare(st)); + QVERIFY_SQL(q, exec()); + } + + stList.clear(); + stList << "create table " + tableName + "(id integer primary key); select * from " + tableName; + stList << "create table " + tableName + "(id integer primary key); syntax error!;"; + stList << "create table " + tableName + "(id integer primary key);;"; + stList << "create table " + tableName + "(id integer primary key);\'\"\a\b\b\v"; + + foreach (const QString&st , stList) { + QVERIFY2(!q.prepare(st), qPrintable(QString("the statement is expected to fail! ") + st)); + QVERIFY2(!q.exec(st), qPrintable(QString("the statement is expected to fail! ") + st)); + } +} + + void tst_QSqlQuery::oraOCINumber() { QFETCH( QString, dbName ); |