FOSSredder 0.5.0
Loading...
Searching...
No Matches
SqliteRegistry.cpp
Go to the documentation of this file.
1
5
7
8#include <optional>
9#include <sqlite3.h>
10#include <stdexcept>
11#include <string>
12
13namespace {
14
15class SqliteRegistry final : public core::ports::storage::IRegistry {
16public:
17 explicit SqliteRegistry(const std::string& dbPath)
18 : db_(openDatabase(dbPath)) {}
19
20 ~SqliteRegistry() override {
21 if (db_) {
22 sqlite3_close(db_);
23 }
24 }
25
26 std::optional<std::string> getLatest() const override {
27 if (!db_) {
28 return std::nullopt;
29 }
30
31 constexpr const char* sql =
32 "SELECT value FROM configs WHERE name = '__latest__' LIMIT 1;";
33 sqlite3_stmt* stmt = nullptr;
34 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr) != SQLITE_OK) {
35 return std::nullopt;
36 }
37
38 std::optional<std::string> latest;
39 if (sqlite3_step(stmt) == SQLITE_ROW) {
40 const auto* value = sqlite3_column_text(stmt, 0);
41 if (value) {
42 latest = std::string(reinterpret_cast<const char*>(value));
43 }
44 }
45
46 sqlite3_finalize(stmt);
47 return latest;
48 }
49
50 void setLatest(const std::string& path) override {
51 if (!db_) {
52 return;
53 }
54
55 constexpr const char* sql = "INSERT OR REPLACE INTO configs (name, value) "
56 "VALUES ('__latest__', ?);";
57 sqlite3_stmt* stmt = nullptr;
58 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr) != SQLITE_OK) {
59 return;
60 }
61
62 sqlite3_bind_text(stmt, 1, path.c_str(), -1, SQLITE_TRANSIENT);
63 sqlite3_step(stmt);
64 sqlite3_finalize(stmt);
65 }
66
67private:
68 sqlite3* db_ = nullptr;
69
70 static sqlite3* openDatabase(const std::string& dbPath) {
71 sqlite3* db = nullptr;
72 if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) {
73 sqlite3_close(db);
74 throw std::runtime_error("failed to open registry db");
75 }
76
77 ensureRegistryTable(db);
78 return db;
79 }
80
81 static void ensureRegistryTable(sqlite3* db) {
82 char* err = nullptr;
83 if (sqlite3_exec(db,
84 "CREATE TABLE IF NOT EXISTS configs (name TEXT PRIMARY "
85 "KEY, value TEXT);",
86 nullptr, nullptr, &err) != SQLITE_OK) {
87 const std::string message = err ? err : "failed to create registry table";
88 if (err) {
89 sqlite3_free(err);
90 }
91 throw std::runtime_error(message);
92 }
93 }
94};
95
96} // namespace
97
98std::shared_ptr<core::ports::storage::IRegistry>
99createSqliteRegistry(const std::string& dbPath) {
100 return std::make_shared<SqliteRegistry>(dbPath);
101}
Registry port used by storage adapters.
std::shared_ptr< core::ports::storage::IRegistry > createSqliteRegistry(const std::string &dbPath)
Create the SQLite-backed registry for the given path.