17 explicit SqliteRegistry(
const std::string& dbPath)
18 : db_(openDatabase(dbPath)) {}
20 ~SqliteRegistry()
override {
26 std::optional<std::string> getLatest()
const override {
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) {
38 std::optional<std::string> latest;
39 if (sqlite3_step(stmt) == SQLITE_ROW) {
40 const auto* value = sqlite3_column_text(stmt, 0);
42 latest = std::string(
reinterpret_cast<const char*
>(value));
46 sqlite3_finalize(stmt);
50 void setLatest(
const std::string& path)
override {
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) {
62 sqlite3_bind_text(stmt, 1, path.c_str(), -1, SQLITE_TRANSIENT);
64 sqlite3_finalize(stmt);
68 sqlite3* db_ =
nullptr;
70 static sqlite3* openDatabase(
const std::string& dbPath) {
71 sqlite3* db =
nullptr;
72 if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) {
74 throw std::runtime_error(
"failed to open registry db");
77 ensureRegistryTable(db);
81 static void ensureRegistryTable(sqlite3* db) {
84 "CREATE TABLE IF NOT EXISTS configs (name TEXT PRIMARY "
86 nullptr,
nullptr, &err) != SQLITE_OK) {
87 const std::string message = err ? err :
"failed to create registry table";
91 throw std::runtime_error(message);
98std::shared_ptr<core::ports::storage::IRegistry>
100 return std::make_shared<SqliteRegistry>(dbPath);
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.