mirror of
				https://github.com/Telecominfraproject/wlan-cloud-lib-poco.git
				synced 2025-11-03 20:18:01 +00:00 
			
		
		
		
	* Use sqlite3_stmt_readonly to determine if sqlite3_changes should be called
* Remove sys.dual dependency, improving multi-threaded applications
This commit is contained in:
		@@ -80,26 +80,11 @@ void SQLiteStatementImpl::compileImpl()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	if (!_pLeftover)
 | 
						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();
 | 
							_bindBegin = bindings().begin();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string statement(toString());
 | 
						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;
 | 
						sqlite3_stmt* pStmt = 0;
 | 
				
			||||||
	const char* pSql = _pLeftover ? _pLeftover->c_str() : statement.c_str();
 | 
						const char* pSql = _pLeftover ? _pLeftover->c_str() : statement.c_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -271,7 +256,8 @@ bool SQLiteStatementImpl::hasNext()
 | 
				
			|||||||
	_nextResponse = sqlite3_step(_pStmt);
 | 
						_nextResponse = sqlite3_step(_pStmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (_affectedRowCount == POCO_SQLITE_INV_ROW_CNT) _affectedRowCount = 0;
 | 
						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)
 | 
						if (_nextResponse != SQLITE_ROW && _nextResponse != SQLITE_OK && _nextResponse != SQLITE_DONE)
 | 
				
			||||||
		Utility::throwException(_nextResponse);
 | 
							Utility::throwException(_nextResponse);
 | 
				
			||||||
@@ -331,7 +317,8 @@ const MetaColumn& SQLiteStatementImpl::metaColumn(std::size_t pos) const
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
std::size_t SQLiteStatementImpl::affectedRowCount() 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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -195,14 +195,6 @@ void SessionImpl::open(const std::string& connect)
 | 
				
			|||||||
		throw ConnectionFailedException(ex.displayText());
 | 
							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;
 | 
						_connected = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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()
 | 
					void SQLiteTest::testThreadModes()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	using namespace Poco::Data::SQLite;
 | 
						using namespace Poco::Data::SQLite;
 | 
				
			||||||
@@ -2747,7 +2698,6 @@ CppUnit::Test* SQLiteTest::suite()
 | 
				
			|||||||
	CppUnit_addTest(pSuite, SQLiteTest, testMultipleResults);
 | 
						CppUnit_addTest(pSuite, SQLiteTest, testMultipleResults);
 | 
				
			||||||
	CppUnit_addTest(pSuite, SQLiteTest, testPair);
 | 
						CppUnit_addTest(pSuite, SQLiteTest, testPair);
 | 
				
			||||||
	CppUnit_addTest(pSuite, SQLiteTest, testReconnect);
 | 
						CppUnit_addTest(pSuite, SQLiteTest, testReconnect);
 | 
				
			||||||
	CppUnit_addTest(pSuite, SQLiteTest, testSystemTable);
 | 
					 | 
				
			||||||
	CppUnit_addTest(pSuite, SQLiteTest, testThreadModes);
 | 
						CppUnit_addTest(pSuite, SQLiteTest, testThreadModes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pSuite;
 | 
						return pSuite;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -132,7 +132,6 @@ public:
 | 
				
			|||||||
	void testMultipleResults();
 | 
						void testMultipleResults();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void testReconnect();
 | 
						void testReconnect();
 | 
				
			||||||
	void testSystemTable();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void testThreadModes();
 | 
						void testThreadModes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user