: _cinemas("cinemas")
, _screens("screens")
, _trusted_devices("trusted_devices")
+ , _db(Config::instance()->cinemas_file())
{
setup_tables();
- setup(Config::instance()->cinemas_file());
+ setup();
}
: _cinemas("cinemas")
, _screens("screens")
, _trusted_devices("trusted_devices")
+ , _db(db_file)
{
setup_tables();
- setup(db_file);
+ setup();
}
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();
}
-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)
{
statement.execute();
- return sqlite3_last_insert_rowid(_db);
+ return sqlite3_last_insert_rowid(_db.db());
}
}
-CinemaList::~CinemaList()
-{
- if (_db) {
- sqlite3_close(_db);
- }
-}
-
-
static
vector<pair<CinemaID, Cinema>>
cinemas_from_result(SQLiteStatement& statement)
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());
#include "id.h"
+#include "sqlite_database.h"
#include "sqlite_table.h"
#include <libcxml/cxml.h>
#include <dcp/utc_offset.h>
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);
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;
};
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)
{
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)
{
add_dkdm_recipient.execute();
- return sqlite3_last_insert_rowid(_db);
+ return sqlite3_last_insert_rowid(_db.db());
}
#include "id.h"
+#include "sqlite_database.h"
#include "sqlite_table.h"
#include <libcxml/cxml.h>
#include <boost/filesystem.hpp>
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);
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;
};
*/
-#include "exceptions.h"
#include "compose.hpp"
+#include "exceptions.h"
+#include "sqlite_database.h"
#include "i18n.h"
}
+
+boost::filesystem::path
+SQLError::get_filename(SQLiteDatabase& db)
+{
+ if (auto filename = sqlite3_db_filename(db.db(), "main")) {
+ return filename;
+ }
+
+ return {};
+}
#include <stdexcept>
+class SQLiteDatabase;
+
+
/** @class DecodeError
* @brief A low-level problem with the decoder (possibly due to the nature
* of a source file).
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);
}
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));
}
--- /dev/null
+/*
+ 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);
+ }
+}
+
+
--- /dev/null
+/*
+ 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
#include "exceptions.h"
+#include "sqlite_database.h"
#include "sqlite_statement.h"
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);
break;
case SQLITE_ERROR:
case SQLITE_MISUSE:
- throw SQLError(_db, sqlite3_errmsg(_db));
+ throw SQLError(_db, sqlite3_errmsg(_db.db()));
}
}
}
#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;
int data_count();
private:
- sqlite3* _db;
+ SQLiteDatabase& _db;
sqlite3_stmt* _stmt;
};
#include "sqlite_transaction.h"
-SQLiteTransaction::SQLiteTransaction(sqlite3* db)
+SQLiteTransaction::SQLiteTransaction(SQLiteDatabase& db)
: _db(db)
{
SQLiteStatement statement(_db, "BEGIN TRANSACTION");
*/
-#include <sqlite3.h>
+class SQLiteDatabase;
class SQLiteTransaction
{
public:
- SQLiteTransaction(sqlite3* db);
+ SQLiteTransaction(SQLiteDatabase& db);
~SQLiteTransaction();
SQLiteTransaction(SQLiteTransaction const&) = delete;
void commit();
private:
- sqlite3* _db;
+ SQLiteDatabase& _db;
bool _rollback = true;
};
state.cc
spl.cc
spl_entry.cc
+ sqlite_database.cc
sqlite_statement.cc
sqlite_table.cc
sqlite_transaction.cc