summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-01-19 00:21:11 +0100
committerCarl Hetherington <cth@carlh.net>2025-01-22 14:34:25 +0100
commit16b3f6c6245acf9689349dbd2af7d4411f861767 (patch)
tree14bedff2389bf48c643e1a7d34c82d8265251801
parent9964a038c1a1ed86510439a33b7022807af31d8d (diff)
Move sqlite database open/close to a new SQLiteDatabase.
-rw-r--r--src/lib/cinema_list.cc52
-rw-r--r--src/lib/cinema_list.h9
-rw-r--r--src/lib/dkdm_recipient_list.cc48
-rw-r--r--src/lib/dkdm_recipient_list.h9
-rw-r--r--src/lib/exceptions.cc13
-rw-r--r--src/lib/exceptions.h24
-rw-r--r--src/lib/sqlite_database.cc67
-rw-r--r--src/lib/sqlite_database.h52
-rw-r--r--src/lib/sqlite_statement.cc9
-rw-r--r--src/lib/sqlite_statement.h7
-rw-r--r--src/lib/sqlite_transaction.cc2
-rw-r--r--src/lib/sqlite_transaction.h6
-rw-r--r--src/lib/wscript1
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