From c0049fc7b6fdcf7bed3e2e95b99f429b841f8ce5 Mon Sep 17 00:00:00 2001 From: Albert S Date: Sat, 29 Jul 2023 10:00:22 +0200 Subject: [PATCH] sqlite: Use per-thread connections --- database/database.h | 2 +- database/sessiondaosqlite.cpp | 2 +- database/sqlite.cpp | 53 ++++++++++++++++++++++------------- database/sqlite.h | 8 ++++-- database/sqlitedao.h | 10 +++---- 5 files changed, 45 insertions(+), 30 deletions(-) diff --git a/database/database.h b/database/database.h index 3e7ee5e..380ba17 100644 --- a/database/database.h +++ b/database/database.h @@ -13,7 +13,7 @@ #include "permissionsdao.h" class Database { - private: + protected: std::string connnectionstring; public: diff --git a/database/sessiondaosqlite.cpp b/database/sessiondaosqlite.cpp index fde0e65..b7f5bfc 100755 --- a/database/sessiondaosqlite.cpp +++ b/database/sessiondaosqlite.cpp @@ -54,7 +54,7 @@ void SessionDaoSqlite::fillSession(int userid, Session &sess) { if(userid > -1) { - UserDaoSqlite userDao{this->db}; + UserDaoSqlite userDao{*this->db}; auto u = userDao.find(userid); if(u) { diff --git a/database/sqlite.cpp b/database/sqlite.cpp index 1b01321..cabcd08 100644 --- a/database/sqlite.cpp +++ b/database/sqlite.cpp @@ -18,23 +18,43 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include #include "sqlite.h" -#include "../logger.h" #include "pagedaosqlite.h" #include "revisiondaosqlite.h" #include "sessiondaosqlite.h" +#include "sqlite_modern_cpp.h" #include "userdaosqlite.h" #include "categorydaosqlite.h" -#include "exceptions.h" #include "permissionsdaosqlite.h" +thread_local sqlite::database *Sqlite::db = nullptr; + +std::atomic instances = 0; Sqlite::Sqlite(std::string path) : Database(path) { - this->db = std::make_shared(path); - - *db << "PRAGMA journal_mode=WAL;"; + instances++; + if(instances.load() > 1) + { + std::cerr << "temporal (yeah, right) HACK... only one instance allowed" << std::endl; + abort(); + } } +std::mutex dbmutex; +sqlite::database &Sqlite::database() const +{ + if(Sqlite::db == nullptr) + { + sqlite::sqlite_config config; + config.flags = config.flags | sqlite::OpenFlags::FULLMUTEX; + std::lock_guard dbguard(dbmutex); + Sqlite::db = new sqlite::database(this->connnectionstring, config); + *Sqlite::db << "PRAGMA journal_mode=WAL;"; + *Sqlite::db << "PRAGMA busy_timeout=10000;"; + } + return *Sqlite::db; +} std::unique_ptr Sqlite::createRevisionDao() const { return create(); @@ -67,27 +87,20 @@ std::unique_ptr Sqlite::createPermissionsDao() const void Sqlite::beginTransaction() { - if(!inTransaction) - { - *db << "begin;"; - inTransaction = true; - } + *db << "begin;"; } void Sqlite::rollbackTransaction() { - if(inTransaction) - { - *db << "rollback;"; - inTransaction = false; - } + *db << "rollback;"; } void Sqlite::commitTransaction() { - if(inTransaction) - { - *db << "commit;"; - inTransaction = false; - } + *db << "commit;"; +} + +Sqlite::~Sqlite() +{ + delete this->db; } diff --git a/database/sqlite.h b/database/sqlite.h index 6411daf..dda7fae 100644 --- a/database/sqlite.h +++ b/database/sqlite.h @@ -8,14 +8,15 @@ class Sqlite : public Database { private: - bool inTransaction = false; - std::shared_ptr db; + static thread_local sqlite::database *db; template std::unique_ptr create() const { - return std::make_unique(db); + return std::make_unique(database()); } + sqlite::database &database() const; + public: Sqlite(std::string path); std::unique_ptr createPageDao() const; @@ -27,6 +28,7 @@ class Sqlite : public Database void beginTransaction(); void commitTransaction(); void rollbackTransaction(); + virtual ~Sqlite(); }; #endif // SQLITE_H diff --git a/database/sqlitedao.h b/database/sqlitedao.h index 535e2f0..347ce93 100644 --- a/database/sqlitedao.h +++ b/database/sqlitedao.h @@ -12,20 +12,20 @@ class SqliteDao { protected: - std::shared_ptr db; + sqlite::database *db = nullptr; public: SqliteDao() { } - SqliteDao(std::shared_ptr db) + SqliteDao(sqlite::database &db) { - this->db = db; + this->db = &db; } - void setDb(std::shared_ptr db) + void setDb(sqlite::database &db) { - this->db = db; + this->db = &db; } inline void throwFrom(const sqlite::sqlite_exception &e) const