Fix #47 setBusyTimeout in constructor

- add corresponding Unit Test
This commit is contained in:
Sébastien Rombauts 2015-05-03 22:24:34 +02:00
parent 3c39f1ff1c
commit e537195625
3 changed files with 52 additions and 16 deletions

View File

@ -55,11 +55,15 @@ public:
* *
* @param[in] apFilename UTF-8 path/uri to the database file ("filename" sqlite3 parameter) * @param[in] apFilename UTF-8 path/uri to the database file ("filename" sqlite3 parameter)
* @param[in] aFlags SQLITE_OPEN_READONLY/SQLITE_OPEN_READWRITE/SQLITE_OPEN_CREATE... * @param[in] aFlags SQLITE_OPEN_READONLY/SQLITE_OPEN_READWRITE/SQLITE_OPEN_CREATE...
* @param[in] aTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY (see setBusyTimeout())
* @param[in] apVfs UTF-8 name of custom VFS to use, or nullptr for sqlite3 default * @param[in] apVfs UTF-8 name of custom VFS to use, or nullptr for sqlite3 default
* *
* @throw SQLite::Exception in case of error * @throw SQLite::Exception in case of error
*/ */
Database(const char* apFilename, const int aFlags = SQLITE_OPEN_READONLY, const char* apVfs = NULL); Database(const char* apFilename,
const int aFlags = SQLITE_OPEN_READONLY,
const int aTimeoutMs = 0,
const char* apVfs = NULL);
/** /**
* @brief Open the provided database UTF-8 filename. * @brief Open the provided database UTF-8 filename.
@ -73,11 +77,15 @@ public:
* *
* @param[in] aFilename UTF-8 path/uri to the database file ("filename" sqlite3 parameter) * @param[in] aFilename UTF-8 path/uri to the database file ("filename" sqlite3 parameter)
* @param[in] aFlags SQLITE_OPEN_READONLY/SQLITE_OPEN_READWRITE/SQLITE_OPEN_CREATE... * @param[in] aFlags SQLITE_OPEN_READONLY/SQLITE_OPEN_READWRITE/SQLITE_OPEN_CREATE...
* @param[in] aTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY (see setBusyTimeout())
* @param[in] aVfs UTF-8 name of custom VFS to use, or empty string for sqlite3 default * @param[in] aVfs UTF-8 name of custom VFS to use, or empty string for sqlite3 default
* *
* @throw SQLite::Exception in case of error * @throw SQLite::Exception in case of error
*/ */
Database(const std::string& aFilename, const int aFlags = SQLITE_OPEN_READONLY, const std::string& aVfs = ""); Database(const std::string& aFilename,
const int aFlags = SQLITE_OPEN_READONLY,
const int aTimeoutMs = 0,
const std::string& aVfs = "");
/** /**
* @brief Close the SQLite database connection. * @brief Close the SQLite database connection.

View File

@ -26,7 +26,10 @@ namespace SQLite
// Open the provided database UTF-8 filename with SQLITE_OPEN_xxx provided flags. // Open the provided database UTF-8 filename with SQLITE_OPEN_xxx provided flags.
Database::Database(const char* apFilename, const int aFlags /*= SQLITE_OPEN_READONLY*/, const char* apVfs /*= NULL*/) : Database::Database(const char* apFilename,
const int aFlags /* = SQLITE_OPEN_READONLY*/,
const int aTimeoutMs /* = 0 */,
const char* apVfs /* = NULL*/) :
mpSQLite(NULL), mpSQLite(NULL),
mFilename(apFilename) mFilename(apFilename)
{ {
@ -37,10 +40,18 @@ Database::Database(const char* apFilename, const int aFlags /*= SQLITE_OPEN_READ
sqlite3_close(mpSQLite); // close is required even in case of error on opening sqlite3_close(mpSQLite); // close is required even in case of error on opening
throw SQLite::Exception(strerr); throw SQLite::Exception(strerr);
} }
if (aTimeoutMs > 0)
{
setBusyTimeout(aTimeoutMs);
}
} }
// Open the provided database UTF-8 filename with SQLITE_OPEN_xxx provided flags. // Open the provided database UTF-8 filename with SQLITE_OPEN_xxx provided flags.
Database::Database(const std::string& aFilename, const int aFlags /*= SQLITE_OPEN_READONLY*/, const std::string& aVfs) : Database::Database(const std::string& aFilename,
const int aFlags /* = SQLITE_OPEN_READONLY*/,
const int aTimeoutMs /* = 0 */,
const std::string& aVfs /* = "" */) :
mpSQLite(NULL), mpSQLite(NULL),
mFilename(aFilename) mFilename(aFilename)
{ {
@ -51,6 +62,11 @@ Database::Database(const std::string& aFilename, const int aFlags /*= SQLITE_OPE
sqlite3_close(mpSQLite); // close is required even in case of error on opening sqlite3_close(mpSQLite); // close is required even in case of error on opening
throw SQLite::Exception(strerr); throw SQLite::Exception(strerr);
} }
if (aTimeoutMs > 0)
{
setBusyTimeout(aTimeoutMs);
}
} }
// Close the SQLite database connection. // Close the SQLite database connection.

View File

@ -32,7 +32,8 @@ TEST(Database, ctorExecCreateDropExist) {
remove("test.db3"); remove("test.db3");
{ {
// Try to open an unexisting database // Try to open an unexisting database
EXPECT_THROW(SQLite::Database not_found("test.db3"), SQLite::Exception); std::string filename = "test.db3";
EXPECT_THROW(SQLite::Database not_found(filename), SQLite::Exception);
// Create a new database // Create a new database
SQLite::Database db("test.db3", SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); SQLite::Database db("test.db3", SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
@ -92,9 +93,10 @@ TEST(Database, inMemory) {
} // Close an destroy DB } // Close an destroy DB
} }
#if SQLITE_VERSION_NUMBER >= 3007015 // first version with PRAGMA busy_timeout #if SQLITE_VERSION_NUMBER >= 3007015 // SQLite v3.7.15 is first version with PRAGMA busy_timeout
TEST(Database, busyTimeout) { TEST(Database, busyTimeout) {
// Create a new database {
// Create a new database with default timeout of 0ms
SQLite::Database db(":memory:"); SQLite::Database db(":memory:");
// Busy timeout default to 0ms: any contention between threads or process leads to SQLITE_BUSY error // Busy timeout default to 0ms: any contention between threads or process leads to SQLITE_BUSY error
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt()); EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
@ -103,9 +105,19 @@ TEST(Database, busyTimeout) {
db.setBusyTimeout(5000); db.setBusyTimeout(5000);
EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt()); EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt());
// Reset timeout to 0
db.setBusyTimeout(0);
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
}
{
// Create a new database with a non null busy timeout
SQLite::Database db(":memory:", SQLITE_OPEN_READWRITE, 5000);
EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt());
// Reset timeout to null // Reset timeout to null
db.setBusyTimeout(0); db.setBusyTimeout(0);
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt()); EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
}
} }
#endif // SQLITE_VERSION_NUMBER >= 3007015 #endif // SQLITE_VERSION_NUMBER >= 3007015