diff --git a/src/libs/sqlite/sqlitedatabase.cpp b/src/libs/sqlite/sqlitedatabase.cpp index d0c1b0bf1ed..ec2379c61c1 100644 --- a/src/libs/sqlite/sqlitedatabase.cpp +++ b/src/libs/sqlite/sqlitedatabase.cpp @@ -30,15 +30,14 @@ namespace Sqlite { SqliteDatabase::SqliteDatabase() - : m_databaseBackend(*this), - m_journalMode(JournalMode::Wal) + : m_databaseBackend(*this) { } void SqliteDatabase::open() { - m_databaseBackend.open(m_databaseFilePath); - m_databaseBackend.setJournalMode(journalMode()); + m_databaseBackend.open(m_databaseFilePath, m_openMode); + m_databaseBackend.setJournalMode(m_journalMode); initializeTables(); m_isOpen = true; } @@ -92,6 +91,16 @@ JournalMode SqliteDatabase::journalMode() const return m_journalMode; } +void SqliteDatabase::setOpenMode(OpenMode openMode) +{ + m_openMode = openMode; +} + +OpenMode SqliteDatabase::openMode() const +{ + return m_openMode; +} + int SqliteDatabase::changesCount() { return m_databaseBackend.changesCount(); diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h index d8f08b535d5..2e178a0190c 100644 --- a/src/libs/sqlite/sqlitedatabase.h +++ b/src/libs/sqlite/sqlitedatabase.h @@ -65,6 +65,9 @@ public: void setJournalMode(JournalMode journalMode); JournalMode journalMode() const; + void setOpenMode(OpenMode openMode); + OpenMode openMode() const; + int changesCount(); int totalChangesCount(); @@ -80,7 +83,8 @@ private: SqliteDatabaseBackend m_databaseBackend; std::vector m_sqliteTables; Utils::PathString m_databaseFilePath; - JournalMode m_journalMode; + JournalMode m_journalMode = JournalMode::Wal; + OpenMode m_openMode = OpenMode::ReadWrite; bool m_isOpen = false; }; diff --git a/src/libs/sqlite/sqlitedatabasebackend.cpp b/src/libs/sqlite/sqlitedatabasebackend.cpp index cb346a8654f..79eed32eab4 100644 --- a/src/libs/sqlite/sqlitedatabasebackend.cpp +++ b/src/libs/sqlite/sqlitedatabasebackend.cpp @@ -101,13 +101,13 @@ void SqliteDatabaseBackend::checkpointFullWalLog() checkIfLogCouldBeCheckpointed(resultCode); } -void SqliteDatabaseBackend::open(Utils::SmallStringView databaseFilePath) +void SqliteDatabaseBackend::open(Utils::SmallStringView databaseFilePath, OpenMode mode) { checkCanOpenDatabase(databaseFilePath); int resultCode = sqlite3_open_v2(databaseFilePath.data(), &m_databaseHandle, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, + openMode(mode), NULL); checkDatabaseCouldBeOpened(resultCode); @@ -375,6 +375,18 @@ TextEncoding SqliteDatabaseBackend::pragmaToTextEncoding(Utils::SmallStringView return static_cast(index); } +int SqliteDatabaseBackend::openMode(OpenMode mode) +{ + int sqliteMode = SQLITE_OPEN_CREATE; + + switch (mode) { + case OpenMode::ReadOnly: sqliteMode |= SQLITE_OPEN_READONLY; break; + case OpenMode::ReadWrite: sqliteMode |= SQLITE_OPEN_READWRITE; break; + } + + return sqliteMode; +} + void SqliteDatabaseBackend::throwExceptionStatic(const char *whatHasHappens) { throw SqliteException(whatHasHappens); diff --git a/src/libs/sqlite/sqlitedatabasebackend.h b/src/libs/sqlite/sqlitedatabasebackend.h index cad4f07726f..72c14634de9 100644 --- a/src/libs/sqlite/sqlitedatabasebackend.h +++ b/src/libs/sqlite/sqlitedatabasebackend.h @@ -54,7 +54,7 @@ public: void shutdownSqliteLibrary(); void checkpointFullWalLog(); - void open(Utils::SmallStringView databaseFilePath); + void open(Utils::SmallStringView databaseFilePath, OpenMode openMode); void close(); void closeWithoutException(); @@ -76,6 +76,8 @@ public: template Type toValue(Utils::SmallStringView sqlStatement); + static int openMode(OpenMode); + protected: bool databaseIsOpen() const; @@ -106,9 +108,11 @@ protected: Utils::SmallStringView textEncodingToPragma(TextEncoding textEncoding); static TextEncoding pragmaToTextEncoding(Utils::SmallStringView pragma); + Q_NORETURN static void throwExceptionStatic(const char *whatHasHappens); Q_NORETURN void throwException(const char *whatHasHappens) const; + private: SqliteDatabase &m_database; sqlite3 *m_databaseHandle; diff --git a/src/libs/sqlite/sqliteglobal.h b/src/libs/sqlite/sqliteglobal.h index 84dfe1fa56d..cb5208df5ff 100644 --- a/src/libs/sqlite/sqliteglobal.h +++ b/src/libs/sqlite/sqliteglobal.h @@ -66,6 +66,12 @@ enum class JournalMode : char Wal }; +enum class OpenMode : char +{ + ReadOnly, + ReadWrite +}; + enum TextEncoding : char { Utf8, diff --git a/tests/unit/unittest/sqlitedatabase-test.cpp b/tests/unit/unittest/sqlitedatabase-test.cpp index fa9dac26427..59d9467246b 100644 --- a/tests/unit/unittest/sqlitedatabase-test.cpp +++ b/tests/unit/unittest/sqlitedatabase-test.cpp @@ -63,6 +63,13 @@ TEST_F(SqliteDatabase, SetJournalMode) ASSERT_THAT(database.journalMode(), JournalMode::Memory); } +TEST_F(SqliteDatabase, SetOpenlMode) +{ + database.setOpenMode(OpenMode::ReadOnly); + + ASSERT_THAT(database.openMode(), OpenMode::ReadOnly); +} + TEST_F(SqliteDatabase, OpenDatabase) { database.close(); diff --git a/tests/unit/unittest/sqlitedatabasebackend-test.cpp b/tests/unit/unittest/sqlitedatabasebackend-test.cpp index be93866671d..90252eb39fa 100644 --- a/tests/unit/unittest/sqlitedatabasebackend-test.cpp +++ b/tests/unit/unittest/sqlitedatabasebackend-test.cpp @@ -30,10 +30,14 @@ #include #include +#include + #include namespace { +using Backend = Sqlite::SqliteDatabaseBackend; + using Sqlite::SqliteException; using Sqlite::SqliteWriteStatement; @@ -52,7 +56,7 @@ using SqliteDatabaseBackendSlowTest = SqliteDatabaseBackend; TEST_F(SqliteDatabaseBackend, OpenAlreadyOpenDatabase) { - ASSERT_THROW(databaseBackend.open(databaseFilePath), SqliteException); + ASSERT_THROW(databaseBackend.open(databaseFilePath, OpenMode::ReadWrite), SqliteException); } TEST_F(SqliteDatabaseBackend, CloseAlreadyClosedDatabase) @@ -64,7 +68,7 @@ TEST_F(SqliteDatabaseBackend, CloseAlreadyClosedDatabase) TEST_F(SqliteDatabaseBackend, OpenWithWrongPath) { - ASSERT_THROW(databaseBackend.open("/xxx/SqliteDatabaseBackendTest.db"), SqliteException); + ASSERT_THROW(databaseBackend.open("/xxx/SqliteDatabaseBackendTest.db", OpenMode::ReadWrite), SqliteException); } TEST_F(SqliteDatabaseBackend, DefaultJournalMode) @@ -142,10 +146,24 @@ TEST_F(SqliteDatabaseBackend, TextEncodingCannotBeChangedAfterTouchingDatabase) ASSERT_THROW(databaseBackend.setTextEncoding(Utf16), SqliteException); } +TEST_F(SqliteDatabaseBackend, OpenModeReadOnly) +{ + auto mode = Backend::openMode(OpenMode::ReadOnly); + + ASSERT_THAT(mode, SQLITE_OPEN_CREATE | SQLITE_OPEN_READONLY); +} + +TEST_F(SqliteDatabaseBackend, OpenModeReadWrite) +{ + auto mode = Backend::openMode(OpenMode::ReadWrite); + + ASSERT_THAT(mode, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE); +} + void SqliteDatabaseBackend::SetUp() { QDir::temp().remove(QStringLiteral("SqliteDatabaseBackendTest.db")); - databaseBackend.open(databaseFilePath); + databaseBackend.open(databaseFilePath, OpenMode::ReadWrite); } void SqliteDatabaseBackend::TearDown()