From 7f6bc3136486ed7e63f28cb9d38d4d056b621e8c Mon Sep 17 00:00:00 2001 From: Rangel Reale Date: Sun, 17 Feb 2013 12:03:01 -0300 Subject: [PATCH] * Use sqlite3_stmt_readonly to determine if sqlite3_changes should be called * Remove sys.dual dependency, improving multi-threaded applications --- Data/SQLite/src/SQLiteStatementImpl.cpp | 21 ++-------- Data/SQLite/src/SessionImpl.cpp | 8 ---- Data/SQLite/testsuite/src/SQLiteTest.cpp | 50 ------------------------ Data/SQLite/testsuite/src/SQLiteTest.h | 1 - 4 files changed, 4 insertions(+), 76 deletions(-) diff --git a/Data/SQLite/src/SQLiteStatementImpl.cpp b/Data/SQLite/src/SQLiteStatementImpl.cpp index da11c4d5a..99b451639 100644 --- a/Data/SQLite/src/SQLiteStatementImpl.cpp +++ b/Data/SQLite/src/SQLiteStatementImpl.cpp @@ -80,26 +80,11 @@ void SQLiteStatementImpl::compileImpl() { if (!_pLeftover) { - // Executed to force reset of previous changes count to zero. - // Without this, execute() will not return accurate (zero) count if select - // statement returns no results previous [insert|update|delete] affected rows. - if (sqlite3_changes(_pDB)) - { - if (SQLITE_OK != sqlite3_exec(_pDB, "delete from sys.dual where 1 <> 1;", 0, 0, 0)) - throw ExecutionException("Error updating system database."); - } _bindBegin = bindings().begin(); } std::string statement(toString()); - if (isubstr(statement, std::string("drop")) != istring::npos && - isubstr(statement, std::string("table")) != istring::npos && - isubstr(statement, std::string("dual")) != istring::npos) - { - throw InvalidAccessException("Cannot drop system table!"); - } - sqlite3_stmt* pStmt = 0; const char* pSql = _pLeftover ? _pLeftover->c_str() : statement.c_str(); @@ -271,7 +256,8 @@ bool SQLiteStatementImpl::hasNext() _nextResponse = sqlite3_step(_pStmt); if (_affectedRowCount == POCO_SQLITE_INV_ROW_CNT) _affectedRowCount = 0; - _affectedRowCount += sqlite3_changes(_pDB); + if (!sqlite3_stmt_readonly(_pStmt)) + _affectedRowCount += sqlite3_changes(_pDB); if (_nextResponse != SQLITE_ROW && _nextResponse != SQLITE_OK && _nextResponse != SQLITE_DONE) Utility::throwException(_nextResponse); @@ -331,7 +317,8 @@ const MetaColumn& SQLiteStatementImpl::metaColumn(std::size_t pos) const std::size_t SQLiteStatementImpl::affectedRowCount() const { - return _affectedRowCount != POCO_SQLITE_INV_ROW_CNT ? _affectedRowCount : sqlite3_changes(_pDB); + if (_affectedRowCount != POCO_SQLITE_INV_ROW_CNT) return _affectedRowCount; + return _pStmt == 0 || sqlite3_stmt_readonly(_pStmt) ? 0 : sqlite3_changes(_pDB); } diff --git a/Data/SQLite/src/SessionImpl.cpp b/Data/SQLite/src/SessionImpl.cpp index 91bbb0029..c750e945c 100644 --- a/Data/SQLite/src/SessionImpl.cpp +++ b/Data/SQLite/src/SessionImpl.cpp @@ -195,14 +195,6 @@ void SessionImpl::open(const std::string& connect) throw ConnectionFailedException(ex.displayText()); } - if (SQLITE_OK != sqlite3_exec(_pDB, - "attach database ':memory:' as sys;" - "create table sys.dual (dummy);", - 0, 0, 0)) - { - throw ExecutionException("Cannot create system database."); - } - _connected = true; } diff --git a/Data/SQLite/testsuite/src/SQLiteTest.cpp b/Data/SQLite/testsuite/src/SQLiteTest.cpp index 443ed141b..fdde66f4c 100644 --- a/Data/SQLite/testsuite/src/SQLiteTest.cpp +++ b/Data/SQLite/testsuite/src/SQLiteTest.cpp @@ -2557,55 +2557,6 @@ void SQLiteTest::testReconnect() } -void SQLiteTest::testSystemTable() -{ - Session session (Poco::Data::SQLite::Connector::KEY, "dummy.db"); - int cntFile = 0; - session << "DROP TABLE IF EXISTS Test", now; - session << "CREATE TABLE Test (Test INTEGER)", now; - session << "INSERT INTO Test VALUES (1)", now; - session << "SELECT count(*) FROM Test", into(cntFile), now; - assert (1 == cntFile); - - int cntMem = -1; - session << "SELECT count(*) FROM sys.dual", into(cntMem), now; - assert (0 == cntMem); - - session << "INSERT INTO sys.dual VALUES ('test')", now; - session << "SELECT count(*) FROM sys.dual", into(cntMem), now; - assert (1 == cntMem); - - // connect another session - Session session2(Poco::Data::SQLite::Connector::KEY, "dummy.db"); - // verify it has it's own sys table - session2 << "SELECT count(*) FROM sys.dual", into(cntMem), now; - assert (0 == cntMem); - // verify it shares the file table - session2 << "SELECT count(*) FROM Test", into(cntFile), now; - assert (1 == cntFile); - session2 << "INSERT INTO sys.dual VALUES ('test')", now; - session2 << "SELECT count(*) FROM sys.dual", into(cntMem), now; - assert (1 == cntMem); - - session << "DELETE FROM sys.dual", now; - session << "SELECT count(*) FROM sys.dual", into(cntMem), now; - assert (0 == cntMem); - session2 << "SELECT count(*) FROM sys.dual", into(cntMem), now; - assert (1 == cntMem); - session2 << "DELETE FROM sys.dual", now; - session2 << "SELECT count(*) FROM sys.dual", into(cntMem), now; - assert (0 == cntMem); - - try - { - session << "DROP TABLE sys.dual", now; - fail ("must throw"); - } - catch (InvalidAccessException&) { } - -} - - void SQLiteTest::testThreadModes() { using namespace Poco::Data::SQLite; @@ -2747,7 +2698,6 @@ CppUnit::Test* SQLiteTest::suite() CppUnit_addTest(pSuite, SQLiteTest, testMultipleResults); CppUnit_addTest(pSuite, SQLiteTest, testPair); CppUnit_addTest(pSuite, SQLiteTest, testReconnect); - CppUnit_addTest(pSuite, SQLiteTest, testSystemTable); CppUnit_addTest(pSuite, SQLiteTest, testThreadModes); return pSuite; diff --git a/Data/SQLite/testsuite/src/SQLiteTest.h b/Data/SQLite/testsuite/src/SQLiteTest.h index 7229fa0c3..5d1fef599 100644 --- a/Data/SQLite/testsuite/src/SQLiteTest.h +++ b/Data/SQLite/testsuite/src/SQLiteTest.h @@ -132,7 +132,6 @@ public: void testMultipleResults(); void testReconnect(); - void testSystemTable(); void testThreadModes();