diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h @@ -5,6 +5,7 @@ #include "entities/Draft.h" #include "entities/KeyserverInfo.h" #include "entities/UserInfo.h" +#include "sqlite_orm.h" #include #include @@ -14,10 +15,13 @@ class SQLiteQueryExecutor : public DatabaseQueryExecutor { static void migrate(); static auto &getStorage(); + static sqlite3 *getConnection(); + static void closeConnection(); static std::once_flag initialized; static int sqlcipherEncryptionKeySize; static std::string secureStoreEncryptionKeyID; + static sqlite3 *dbConnection; #ifndef EMSCRIPTEN static void assign_encryption_key(); @@ -28,6 +32,7 @@ static std::string encryptionKey; SQLiteQueryExecutor(); + ~SQLiteQueryExecutor(); SQLiteQueryExecutor(std::string sqliteFilePath); std::unique_ptr getThread(std::string threadID) const override; std::string getDraft(std::string key) const override; diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp @@ -1,6 +1,5 @@ #include "SQLiteQueryExecutor.h" #include "Logger.h" -#include "sqlite_orm.h" #include "entities/KeyserverInfo.h" #include "entities/Metadata.h" @@ -26,6 +25,7 @@ int SQLiteQueryExecutor::sqlcipherEncryptionKeySize = 64; std::string SQLiteQueryExecutor::secureStoreEncryptionKeyID = "comm.encryptionKey"; +sqlite3 *SQLiteQueryExecutor::dbConnection = nullptr; bool create_table(sqlite3 *db, std::string query, std::string tableName) { char *error; @@ -477,6 +477,21 @@ return create_table(db, query, "keyservers"); } +bool enable_rollback_journal_mode(sqlite3 *db) { + char *error; + sqlite3_exec(db, "PRAGMA journal_mode=DELETE;", nullptr, nullptr, &error); + + if (!error) { + return true; + } + + std::stringstream error_message; + error_message << "Error disabling write-ahead logging mode: " << error; + Logger::log(error_message.str()); + sqlite3_free(error); + return false; +} + bool create_schema(sqlite3 *db) { char *error; sqlite3_exec( @@ -826,7 +841,8 @@ {30, {create_persist_storage_table, true}}, {31, {recreate_message_store_threads_table, true}}, {32, {create_users_table, true}}, - {33, {create_keyservers_table, true}}}}; + {33, {create_keyservers_table, true}}, + {34, {enable_rollback_journal_mode, false}}}}; enum class MigrationResult { SUCCESS, FAILURE, NOT_APPLIED }; @@ -882,11 +898,6 @@ } bool set_up_database(sqlite3 *db) { - auto write_ahead_enabled = enable_write_ahead_logging_mode(db); - if (!write_ahead_enabled) { - return false; - } - sqlite3_exec(db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr); auto db_version = get_database_version(db); auto latest_version = migrations.back().first; @@ -1074,6 +1085,38 @@ SQLiteQueryExecutor::migrate(); } +sqlite3 *SQLiteQueryExecutor::getConnection() { + if (SQLiteQueryExecutor::dbConnection) { + return SQLiteQueryExecutor::dbConnection; + } + + int connectResult = sqlite3_open( + SQLiteQueryExecutor::sqliteFilePath.c_str(), + &SQLiteQueryExecutor::dbConnection); + + if (connectResult != SQLITE_OK) { + std::stringstream error_message; + error_message << "Failed to open database connection. Details: " + << sqlite3_errstr(connectResult) << std::endl; + throw std::runtime_error(error_message.str()); + } + + default_on_db_open_callback(SQLiteQueryExecutor::dbConnection); + return SQLiteQueryExecutor::dbConnection; +} + +void SQLiteQueryExecutor::closeConnection() { + if (!SQLiteQueryExecutor::dbConnection) { + return; + } + sqlite3_close(SQLiteQueryExecutor::dbConnection); + SQLiteQueryExecutor::dbConnection = nullptr; +} + +SQLiteQueryExecutor::~SQLiteQueryExecutor() { + SQLiteQueryExecutor::closeConnection(); +} + std::string SQLiteQueryExecutor::getDraft(std::string key) const { std::unique_ptr draft = SQLiteQueryExecutor::getStorage().get_pointer(key); @@ -1451,6 +1494,7 @@ }; #else void SQLiteQueryExecutor::clearSensitiveData() { + SQLiteQueryExecutor::closeConnection(); if (file_exists(SQLiteQueryExecutor::sqliteFilePath) && std::remove(SQLiteQueryExecutor::sqliteFilePath.c_str())) { std::ostringstream errorStream; diff --git a/web/database/_generated/comm_query_executor.wasm b/web/database/_generated/comm_query_executor.wasm index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@