diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-01-19 00:21:11 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-01-22 14:34:25 +0100 |
| commit | 16b3f6c6245acf9689349dbd2af7d4411f861767 (patch) | |
| tree | 14bedff2389bf48c643e1a7d34c82d8265251801 | |
| parent | 9964a038c1a1ed86510439a33b7022807af31d8d (diff) | |
Move sqlite database open/close to a new SQLiteDatabase.
| -rw-r--r-- | src/lib/cinema_list.cc | 52 | ||||
| -rw-r--r-- | src/lib/cinema_list.h | 9 | ||||
| -rw-r--r-- | src/lib/dkdm_recipient_list.cc | 48 | ||||
| -rw-r--r-- | src/lib/dkdm_recipient_list.h | 9 | ||||
| -rw-r--r-- | src/lib/exceptions.cc | 13 | ||||
| -rw-r--r-- | src/lib/exceptions.h | 24 | ||||
| -rw-r--r-- | src/lib/sqlite_database.cc | 67 | ||||
| -rw-r--r-- | src/lib/sqlite_database.h | 52 | ||||
| -rw-r--r-- | src/lib/sqlite_statement.cc | 9 | ||||
| -rw-r--r-- | src/lib/sqlite_statement.h | 7 | ||||
| -rw-r--r-- | src/lib/sqlite_transaction.cc | 2 | ||||
| -rw-r--r-- | src/lib/sqlite_transaction.h | 6 | ||||
| -rw-r--r-- | src/lib/wscript | 1 |
13 files changed, 175 insertions, 124 deletions
diff --git a/src/lib/cinema_list.cc b/src/lib/cinema_list.cc index e4095f1c4..4ee538efe 100644 --- a/src/lib/cinema_list.cc +++ b/src/lib/cinema_list.cc @@ -47,9 +47,10 @@ CinemaList::CinemaList() : _cinemas("cinemas") , _screens("screens") , _trusted_devices("trusted_devices") + , _db(Config::instance()->cinemas_file()) { setup_tables(); - setup(Config::instance()->cinemas_file()); + setup(); } @@ -57,9 +58,10 @@ CinemaList::CinemaList(boost::filesystem::path db_file) : _cinemas("cinemas") , _screens("screens") , _trusted_devices("trusted_devices") + , _db(db_file) { setup_tables(); - setup(db_file); + setup(); } @@ -161,19 +163,8 @@ CinemaList::clear() void -CinemaList::setup(boost::filesystem::path db_file) +CinemaList::setup() { -#ifdef DCPOMATIC_WINDOWS - auto rc = sqlite3_open16(db_file.c_str(), &_db); -#else - auto rc = sqlite3_open(db_file.c_str(), &_db); -#endif - if (rc != SQLITE_OK) { - throw FileError("Could not open SQLite database", db_file); - } - - sqlite3_busy_timeout(_db, 500); - SQLiteStatement cinemas(_db, _cinemas.create()); cinemas.execute(); @@ -185,27 +176,6 @@ CinemaList::setup(boost::filesystem::path db_file) } -CinemaList::CinemaList(CinemaList&& other) - : _db(other._db) - , _cinemas(std::move(other._cinemas)) - , _screens(std::move(other._screens)) - , _trusted_devices(std::move(other._trusted_devices)) -{ - other._db = nullptr; -} - - -CinemaList& -CinemaList::operator=(CinemaList&& other) -{ - if (this != &other) { - _db = other._db; - other._db = nullptr; - } - return *this; -} - - CinemaID CinemaList::add_cinema(Cinema const& cinema) { @@ -219,7 +189,7 @@ CinemaList::add_cinema(Cinema const& cinema) statement.execute(); - return sqlite3_last_insert_rowid(_db); + return sqlite3_last_insert_rowid(_db.db()); } @@ -248,14 +218,6 @@ CinemaList::remove_cinema(CinemaID id) } -CinemaList::~CinemaList() -{ - if (_db) { - sqlite3_close(_db); - } -} - - static vector<pair<CinemaID, Cinema>> cinemas_from_result(SQLiteStatement& statement) @@ -314,7 +276,7 @@ CinemaList::add_screen(CinemaID cinema_id, dcpomatic::Screen const& screen) add_screen.execute(); - auto const screen_id = sqlite3_last_insert_rowid(_db); + auto const screen_id = sqlite3_last_insert_rowid(_db.db()); for (auto device: screen.trusted_devices) { SQLiteStatement add_device(_db, _trusted_devices.insert()); diff --git a/src/lib/cinema_list.h b/src/lib/cinema_list.h index 1e0144f73..40e32410f 100644 --- a/src/lib/cinema_list.h +++ b/src/lib/cinema_list.h @@ -24,6 +24,7 @@ #include "id.h" +#include "sqlite_database.h" #include "sqlite_table.h" #include <libcxml/cxml.h> #include <dcp/utc_offset.h> @@ -77,14 +78,10 @@ class CinemaList public: CinemaList(); CinemaList(boost::filesystem::path db_file); - ~CinemaList(); CinemaList(CinemaList const&) = delete; CinemaList& operator=(CinemaList const&) = delete; - CinemaList(CinemaList&& other); - CinemaList& operator=(CinemaList&& other); - void read_legacy_file(boost::filesystem::path xml_file); void read_legacy_string(std::string const& xml); @@ -117,13 +114,13 @@ private: dcpomatic::Screen screen_from_result(SQLiteStatement& statement, ScreenID screen_id, bool with_trusted_devices) const; std::vector<std::pair<ScreenID, dcpomatic::Screen>> screens_from_result(SQLiteStatement& statement) const; void setup_tables(); - void setup(boost::filesystem::path db_file); + void setup(); void read_legacy_document(cxml::Document const& doc); - sqlite3* _db = nullptr; SQLiteTable _cinemas; SQLiteTable _screens; SQLiteTable _trusted_devices; + mutable SQLiteDatabase _db; }; diff --git a/src/lib/dkdm_recipient_list.cc b/src/lib/dkdm_recipient_list.cc index f67379122..c57ade437 100644 --- a/src/lib/dkdm_recipient_list.cc +++ b/src/lib/dkdm_recipient_list.cc @@ -37,27 +37,21 @@ using boost::optional; DKDMRecipientList::DKDMRecipientList() : _dkdm_recipients("dkdm_recipients") + , _db(Config::instance()->dkdm_recipients_file()) { - setup(Config::instance()->dkdm_recipients_file()); + setup(); } DKDMRecipientList::DKDMRecipientList(boost::filesystem::path db_file) : _dkdm_recipients("dkdm_recipients") + , _db(db_file) { - setup(db_file); + setup(); } -DKDMRecipientList::~DKDMRecipientList() -{ - if (_db) { - sqlite3_close(_db); - } -} - - void DKDMRecipientList::read_legacy_file(boost::filesystem::path xml_file) { @@ -105,48 +99,18 @@ DKDMRecipientList::read_legacy_document(cxml::Document const& doc) void -DKDMRecipientList::setup(boost::filesystem::path db_file) +DKDMRecipientList::setup() { _dkdm_recipients.add_column("name", "TEXT"); _dkdm_recipients.add_column("notes", "TEXT"); _dkdm_recipients.add_column("recipient", "TEXT"); _dkdm_recipients.add_column("emails", "TEXT"); -#ifdef DCPOMATIC_WINDOWS - auto rc = sqlite3_open16(db_file.c_str(), &_db); -#else - auto rc = sqlite3_open(db_file.c_str(), &_db); -#endif - if (rc != SQLITE_OK) { - throw FileError("Could not open SQLite database", db_file); - } - - sqlite3_busy_timeout(_db, 500); - SQLiteStatement screens(_db, _dkdm_recipients.create()); screens.execute(); } -DKDMRecipientList::DKDMRecipientList(DKDMRecipientList&& other) - : _dkdm_recipients(std::move(other._dkdm_recipients)) -{ - _db = other._db; - other._db = nullptr; -} - - -DKDMRecipientList& -DKDMRecipientList::operator=(DKDMRecipientList&& other) -{ - if (this != &other) { - _db = other._db; - other._db = nullptr; - } - return *this; -} - - DKDMRecipientID DKDMRecipientList::add_dkdm_recipient(DKDMRecipient const& dkdm_recipient) { @@ -159,7 +123,7 @@ DKDMRecipientList::add_dkdm_recipient(DKDMRecipient const& dkdm_recipient) add_dkdm_recipient.execute(); - return sqlite3_last_insert_rowid(_db); + return sqlite3_last_insert_rowid(_db.db()); } diff --git a/src/lib/dkdm_recipient_list.h b/src/lib/dkdm_recipient_list.h index fc4d84b60..3847239b5 100644 --- a/src/lib/dkdm_recipient_list.h +++ b/src/lib/dkdm_recipient_list.h @@ -24,6 +24,7 @@ #include "id.h" +#include "sqlite_database.h" #include "sqlite_table.h" #include <libcxml/cxml.h> #include <boost/filesystem.hpp> @@ -58,14 +59,10 @@ class DKDMRecipientList public: DKDMRecipientList(); DKDMRecipientList(boost::filesystem::path db_file); - ~DKDMRecipientList(); DKDMRecipientList(DKDMRecipientList const&) = delete; DKDMRecipientList& operator=(DKDMRecipientList const&) = delete; - DKDMRecipientList(DKDMRecipientList&& other); - DKDMRecipientList& operator=(DKDMRecipientList&& other); - void read_legacy_file(boost::filesystem::path xml_file); void read_legacy_string(std::string const& xml); @@ -78,11 +75,11 @@ public: boost::optional<DKDMRecipient> dkdm_recipient(DKDMRecipientID id) const; private: - void setup(boost::filesystem::path db_file); + void setup(); void read_legacy_document(cxml::Document const& doc); - sqlite3* _db = nullptr; SQLiteTable _dkdm_recipients; + mutable SQLiteDatabase _db; }; diff --git a/src/lib/exceptions.cc b/src/lib/exceptions.cc index 27496dcdc..5f0fe935a 100644 --- a/src/lib/exceptions.cc +++ b/src/lib/exceptions.cc @@ -19,8 +19,9 @@ */ -#include "exceptions.h" #include "compose.hpp" +#include "exceptions.h" +#include "sqlite_database.h" #include "i18n.h" @@ -180,3 +181,13 @@ DiskFullError::DiskFullError(boost::filesystem::path writing) } + +boost::filesystem::path +SQLError::get_filename(SQLiteDatabase& db) +{ + if (auto filename = sqlite3_db_filename(db.db(), "main")) { + return filename; + } + + return {}; +} diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h index c1bb8f6b6..dae64fb5d 100644 --- a/src/lib/exceptions.h +++ b/src/lib/exceptions.h @@ -39,6 +39,9 @@ extern "C" { #include <stdexcept> +class SQLiteDatabase; + + /** @class DecodeError * @brief A low-level problem with the decoder (possibly due to the nature * of a source file). @@ -484,19 +487,19 @@ public: class SQLError : public std::runtime_error { public: - SQLError(sqlite3* db, char const* s) + SQLError(SQLiteDatabase& db, char const* s) : std::runtime_error(get_message(db, s)) { _filename = get_filename(db); } - SQLError(sqlite3* db, int rc) + SQLError(SQLiteDatabase& db, int rc) : std::runtime_error(get_message(db, rc)) { _filename = get_filename(db); } - SQLError(sqlite3* db, int rc, std::string doing) + SQLError(SQLiteDatabase& db, int rc, std::string doing) : std::runtime_error(get_message(db, rc, doing)) { _filename = get_filename(db); @@ -507,26 +510,19 @@ public: } private: - boost::filesystem::path get_filename(sqlite3* db) - { - if (auto filename = sqlite3_db_filename(db, "main")) { - return filename; - } - - return {}; - } + boost::filesystem::path get_filename(SQLiteDatabase& db); - std::string get_message(sqlite3* db, char const* s) + std::string get_message(SQLiteDatabase& db, char const* s) { return String::compose("%1 (in %2)", s, get_filename(db)); } - std::string get_message(sqlite3* db, int rc) + std::string get_message(SQLiteDatabase& db, int rc) { return String::compose("%1 (in %2)", sqlite3_errstr(rc), get_filename(db)); } - std::string get_message(sqlite3* db, int rc, std::string doing) + std::string get_message(SQLiteDatabase& db, int rc, std::string doing) { return String::compose("%1 (while doing %2) (in %3)", sqlite3_errstr(rc), doing, get_filename(db)); } diff --git a/src/lib/sqlite_database.cc b/src/lib/sqlite_database.cc new file mode 100644 index 000000000..f0270129b --- /dev/null +++ b/src/lib/sqlite_database.cc @@ -0,0 +1,67 @@ +/* + Copyright (C) 2025 Carl Hetherington <cth@carlh.net> + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>. + +*/ + + +#include "exceptions.h" +#include "sqlite_database.h" +#include <sqlite3.h> + + +SQLiteDatabase::SQLiteDatabase(boost::filesystem::path path) +{ +#ifdef DCPOMATIC_WINDOWS + auto rc = sqlite3_open16(path.c_str(), &_db); +#else + auto rc = sqlite3_open(path.c_str(), &_db); +#endif + if (rc != SQLITE_OK) { + throw FileError("Could not open SQLite database", path); + } + + sqlite3_busy_timeout(_db, 500); +} + + +SQLiteDatabase::SQLiteDatabase(SQLiteDatabase&& other) +{ + _db = other._db; + other._db = nullptr; +} + + +SQLiteDatabase& +SQLiteDatabase::operator=(SQLiteDatabase&& other) +{ + if (this != &other) { + _db = other._db; + other._db = nullptr; + } + return *this; +} + + +SQLiteDatabase::~SQLiteDatabase() +{ + if (_db) { + sqlite3_close(_db); + } +} + + diff --git a/src/lib/sqlite_database.h b/src/lib/sqlite_database.h new file mode 100644 index 000000000..7858cbf5c --- /dev/null +++ b/src/lib/sqlite_database.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2025 Carl Hetherington <cth@carlh.net> + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>. + +*/ + + +#ifndef DCPOMATIC_SQLITE_DATABASE_H +#define DCPOMATIC_SQLITE_DATABASE_H + + +#include <boost/filesystem.hpp> + +struct sqlite3; + + +class SQLiteDatabase +{ +public: + SQLiteDatabase(boost::filesystem::path path); + ~SQLiteDatabase(); + + SQLiteDatabase(SQLiteDatabase const&) = delete; + SQLiteDatabase& operator=(SQLiteDatabase const&) = delete; + + SQLiteDatabase(SQLiteDatabase&&); + SQLiteDatabase& operator=(SQLiteDatabase&& other); + + sqlite3* db() const { + return _db; + } + +private: + sqlite3* _db = nullptr; +}; + + +#endif diff --git a/src/lib/sqlite_statement.cc b/src/lib/sqlite_statement.cc index b3ec1fb81..d130da507 100644 --- a/src/lib/sqlite_statement.cc +++ b/src/lib/sqlite_statement.cc @@ -20,6 +20,7 @@ #include "exceptions.h" +#include "sqlite_database.h" #include "sqlite_statement.h" @@ -27,13 +28,13 @@ using std::function; using std::string; -SQLiteStatement::SQLiteStatement(sqlite3* db, string const& statement) +SQLiteStatement::SQLiteStatement(SQLiteDatabase& db, string const& statement) : _db(db) { #ifdef DCPOMATIC_HAVE_SQLITE3_PREPARE_V3 - auto rc = sqlite3_prepare_v3(_db, statement.c_str(), -1, 0, &_stmt, nullptr); + auto rc = sqlite3_prepare_v3(_db.db(), statement.c_str(), -1, 0, &_stmt, nullptr); #else - auto rc = sqlite3_prepare_v2(_db, statement.c_str(), -1, &_stmt, nullptr); + auto rc = sqlite3_prepare_v2(_db.db(), statement.c_str(), -1, &_stmt, nullptr); #endif if (rc != SQLITE_OK) { throw SQLError(_db, rc, statement); @@ -83,7 +84,7 @@ SQLiteStatement::execute(function<void(SQLiteStatement&)> row, function<void()> break; case SQLITE_ERROR: case SQLITE_MISUSE: - throw SQLError(_db, sqlite3_errmsg(_db)); + throw SQLError(_db, sqlite3_errmsg(_db.db())); } } } diff --git a/src/lib/sqlite_statement.h b/src/lib/sqlite_statement.h index 3c2246efb..f1131e899 100644 --- a/src/lib/sqlite_statement.h +++ b/src/lib/sqlite_statement.h @@ -24,10 +24,13 @@ #include <string> +class SQLiteDatabase; + + class SQLiteStatement { public: - SQLiteStatement(sqlite3* db, std::string const& statement); + SQLiteStatement(SQLiteDatabase& db, std::string const& statement); ~SQLiteStatement(); SQLiteStatement(SQLiteStatement const&) = delete; @@ -44,7 +47,7 @@ public: int data_count(); private: - sqlite3* _db; + SQLiteDatabase& _db; sqlite3_stmt* _stmt; }; diff --git a/src/lib/sqlite_transaction.cc b/src/lib/sqlite_transaction.cc index 239d85020..b03dc6499 100644 --- a/src/lib/sqlite_transaction.cc +++ b/src/lib/sqlite_transaction.cc @@ -23,7 +23,7 @@ #include "sqlite_transaction.h" -SQLiteTransaction::SQLiteTransaction(sqlite3* db) +SQLiteTransaction::SQLiteTransaction(SQLiteDatabase& db) : _db(db) { SQLiteStatement statement(_db, "BEGIN TRANSACTION"); diff --git a/src/lib/sqlite_transaction.h b/src/lib/sqlite_transaction.h index 0f6319243..b1ec4d6eb 100644 --- a/src/lib/sqlite_transaction.h +++ b/src/lib/sqlite_transaction.h @@ -19,13 +19,13 @@ */ -#include <sqlite3.h> +class SQLiteDatabase; class SQLiteTransaction { public: - SQLiteTransaction(sqlite3* db); + SQLiteTransaction(SQLiteDatabase& db); ~SQLiteTransaction(); SQLiteTransaction(SQLiteTransaction const&) = delete; @@ -34,7 +34,7 @@ public: void commit(); private: - sqlite3* _db; + SQLiteDatabase& _db; bool _rollback = true; }; diff --git a/src/lib/wscript b/src/lib/wscript index 8a4b17dbc..2855041b2 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -192,6 +192,7 @@ sources = """ state.cc spl.cc spl_entry.cc + sqlite_database.cc sqlite_statement.cc sqlite_table.cc sqlite_transaction.cc |
