Sqlite: Improve database opening

Change-Id: I9074cda4d9da12a061f094ca72fa156d89ca0f87
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2023-03-14 11:12:58 +01:00
parent 0e3c125505
commit 157b5039c1
4 changed files with 38 additions and 19 deletions

View File

@@ -69,7 +69,7 @@ void Database::activateLogging()
void Database::open(LockingMode lockingMode) void Database::open(LockingMode lockingMode)
{ {
m_databaseBackend.open(m_databaseFilePath, m_openMode); m_databaseBackend.open(m_databaseFilePath, m_openMode, m_journalMode);
if (m_busyTimeout > 0ms) if (m_busyTimeout > 0ms)
m_databaseBackend.setBusyTimeout(m_busyTimeout); m_databaseBackend.setBusyTimeout(m_busyTimeout);
else else

View File

@@ -84,18 +84,19 @@ void DatabaseBackend::checkpointFullWalLog()
checkIfLogCouldBeCheckpointed(resultCode); checkIfLogCouldBeCheckpointed(resultCode);
} }
void DatabaseBackend::open(Utils::SmallStringView databaseFilePath, OpenMode mode) void DatabaseBackend::open(Utils::SmallStringView databaseFilePath,
OpenMode openMode,
JournalMode journalMode)
{ {
checkCanOpenDatabase(databaseFilePath); checkCanOpenDatabase(databaseFilePath);
int resultCode = sqlite3_open_v2(std::string(databaseFilePath).c_str(), int resultCode = sqlite3_open_v2(std::string(databaseFilePath).c_str(),
&m_databaseHandle, &m_databaseHandle,
openMode(mode), createOpenFlags(openMode, journalMode),
nullptr); nullptr);
checkDatabaseCouldBeOpened(resultCode); checkDatabaseCouldBeOpened(resultCode);
sqlite3_extended_result_codes(m_databaseHandle, true);
resultCode = sqlite3_carray_init(m_databaseHandle, nullptr, nullptr); resultCode = sqlite3_carray_init(m_databaseHandle, nullptr, nullptr);
checkCarrayCannotBeIntialized(resultCode); checkCarrayCannotBeIntialized(resultCode);
@@ -392,16 +393,23 @@ JournalMode DatabaseBackend::pragmaToJournalMode(Utils::SmallStringView pragma)
return static_cast<JournalMode>(index); return static_cast<JournalMode>(index);
} }
int DatabaseBackend::openMode(OpenMode mode) int DatabaseBackend::createOpenFlags(OpenMode openMode, JournalMode journalMode)
{ {
int sqliteMode = SQLITE_OPEN_CREATE; int sqliteOpenFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_EXRESCODE;
switch (mode) { if (journalMode == JournalMode::Memory)
case OpenMode::ReadOnly: sqliteMode |= SQLITE_OPEN_READONLY; break; sqliteOpenFlags |= SQLITE_OPEN_MEMORY;
case OpenMode::ReadWrite: sqliteMode |= SQLITE_OPEN_READWRITE; break;
switch (openMode) {
case OpenMode::ReadOnly:
sqliteOpenFlags |= SQLITE_OPEN_READONLY;
break;
case OpenMode::ReadWrite:
sqliteOpenFlags |= SQLITE_OPEN_READWRITE;
break;
} }
return sqliteMode; return sqliteOpenFlags;
} }
void DatabaseBackend::setBusyTimeout(std::chrono::milliseconds timeout) void DatabaseBackend::setBusyTimeout(std::chrono::milliseconds timeout)

View File

@@ -39,7 +39,7 @@ public:
static void shutdownSqliteLibrary(); static void shutdownSqliteLibrary();
void checkpointFullWalLog(); void checkpointFullWalLog();
void open(Utils::SmallStringView databaseFilePath, OpenMode openMode); void open(Utils::SmallStringView databaseFilePath, OpenMode openMode, JournalMode journalMode);
void close(); void close();
void closeWithoutException(); void closeWithoutException();
@@ -67,7 +67,7 @@ public:
template<typename Type> template<typename Type>
Type toValue(Utils::SmallStringView sqlStatement) const; Type toValue(Utils::SmallStringView sqlStatement) const;
static int openMode(OpenMode); static int createOpenFlags(OpenMode openMode, JournalMode journalMode);
void setBusyTimeout(std::chrono::milliseconds timeout); void setBusyTimeout(std::chrono::milliseconds timeout);

View File

@@ -31,7 +31,7 @@ protected:
{ {
database.lock(); database.lock();
QDir::temp().remove(QStringLiteral("SqliteDatabaseBackendTest.db")); QDir::temp().remove(QStringLiteral("SqliteDatabaseBackendTest.db"));
databaseBackend.open(databaseFilePath, OpenMode::ReadWrite); databaseBackend.open(databaseFilePath, OpenMode::ReadWrite, Sqlite::JournalMode::Wal);
} }
~SqliteDatabaseBackend() noexcept(true) ~SqliteDatabaseBackend() noexcept(true)
@@ -49,7 +49,7 @@ using SqliteDatabaseBackendSlowTest = SqliteDatabaseBackend;
TEST_F(SqliteDatabaseBackend, OpenAlreadyOpenDatabase) TEST_F(SqliteDatabaseBackend, OpenAlreadyOpenDatabase)
{ {
ASSERT_THROW(databaseBackend.open(databaseFilePath, OpenMode::ReadWrite), ASSERT_THROW(databaseBackend.open(databaseFilePath, OpenMode::ReadWrite, Sqlite::JournalMode::Wal),
Sqlite::DatabaseIsAlreadyOpen); Sqlite::DatabaseIsAlreadyOpen);
} }
@@ -62,7 +62,9 @@ TEST_F(SqliteDatabaseBackend, CloseAlreadyClosedDatabase)
TEST_F(SqliteDatabaseBackend, OpenWithWrongPath) TEST_F(SqliteDatabaseBackend, OpenWithWrongPath)
{ {
ASSERT_THROW(databaseBackend.open("/xxx/SqliteDatabaseBackendTest.db", OpenMode::ReadWrite), ASSERT_THROW(databaseBackend.open("/xxx/SqliteDatabaseBackendTest.db",
OpenMode::ReadWrite,
Sqlite::JournalMode::Wal),
Sqlite::WrongFilePath); Sqlite::WrongFilePath);
} }
@@ -101,15 +103,24 @@ TEST_F(SqliteDatabaseBackend, PersistJournalMode)
TEST_F(SqliteDatabaseBackend, OpenModeReadOnly) TEST_F(SqliteDatabaseBackend, OpenModeReadOnly)
{ {
auto mode = Backend::openMode(OpenMode::ReadOnly); auto mode = Backend::createOpenFlags(OpenMode::ReadOnly, Sqlite::JournalMode::Wal);
ASSERT_THAT(mode, SQLITE_OPEN_CREATE | SQLITE_OPEN_READONLY); ASSERT_THAT(mode, SQLITE_OPEN_CREATE | SQLITE_OPEN_READONLY | SQLITE_OPEN_EXRESCODE);
} }
TEST_F(SqliteDatabaseBackend, OpenModeReadWrite) TEST_F(SqliteDatabaseBackend, OpenModeReadWrite)
{ {
auto mode = Backend::openMode(OpenMode::ReadWrite); auto mode = Backend::createOpenFlags(OpenMode::ReadWrite, Sqlite::JournalMode::Wal);
ASSERT_THAT(mode, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE); ASSERT_THAT(mode, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_EXRESCODE);
}
TEST_F(SqliteDatabaseBackend, OpenModeReadWriteAndMemoryJournal)
{
auto mode = Backend::createOpenFlags(OpenMode::ReadWrite, Sqlite::JournalMode::Memory);
ASSERT_THAT(mode,
SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_EXRESCODE
| SQLITE_OPEN_MEMORY);
} }
} // namespace } // namespace