15std::vector<std::string> loadTransactionIds(sqlite3* db,
16 const std::string& statementId) {
17 std::vector<std::string> ids;
18 if (!db || statementId.empty())
22 db,
"SELECT transaction_id FROM statement_transactions WHERE "
23 "statement_id = ? ORDER BY position, transaction_id;");
27 stmt.bindText(1, statementId);
28 while (stmt.step() == SQLITE_ROW) {
29 ids.push_back(stmt.columnText(0));
34void saveTransactionIds(sqlite3* db,
const std::string& statementId,
35 const std::vector<std::string>& transactionIds) {
36 if (!db || statementId.empty())
40 db,
"DELETE FROM statement_transactions WHERE statement_id = ?;");
43 deleteStmt.bindText(1, statementId);
47 db,
"INSERT OR IGNORE INTO statement_transactions (statement_id, "
48 "transaction_id, position) VALUES (?, ?, ?);");
52 for (std::size_t i = 0; i < transactionIds.size(); ++i) {
53 if (transactionIds[i].empty())
56 insertStmt.bindText(1, statementId);
57 insertStmt.bindText(2, transactionIds[i]);
58 insertStmt.bindInt(3,
static_cast<int>(i));
66 std::shared_ptr<SqliteDb>
db;
67 std::shared_ptr<core::ports::diagnostics::IErrorReporter>
errorReporter;
74 const std::string& dbPath,
75 std::shared_ptr<core::ports::diagnostics::IErrorReporter> er)
80 std::shared_ptr<SqliteDb> db)
84 std::shared_ptr<SqliteDb> db,
85 std::shared_ptr<core::ports::diagnostics::IErrorReporter> er)
86 : pimpl_(std::make_unique<
Impl>()) {
88 throw std::runtime_error(
"db is null");
89 pimpl_->db = std::move(db);
90 pimpl_->errorReporter = std::move(er);
96 const std::shared_ptr<Statement>& statement) {
97 if (!statement || statement->id().empty())
100 "INSERT OR IGNORE INTO statements (id, name, "
101 "created_at, updated_at) VALUES (?, ?, ?, ?);");
105 stmt.
bindText(2, statement->name());
106 stmt.
bindText(3, statement->createdAt());
107 stmt.
bindText(4, statement->updatedAt());
109 saveTransactionIds(pimpl_->db->handle(), statement->id(),
110 statement->transactionIds());
113std::vector<std::shared_ptr<Statement>>
115 std::vector<std::shared_ptr<Statement>> out;
117 pimpl_->db->handle(),
118 "SELECT id, name, created_at, updated_at FROM statements ORDER BY id;");
121 while (stmt.
step() == SQLITE_ROW) {
122 auto s = std::make_shared<Statement>();
127 s->setTransactionIds(loadTransactionIds(pimpl_->db->handle(), s->id()));
128 out.push_back(std::move(s));
133std::optional<std::shared_ptr<Statement>>
138 "SELECT id, name, created_at, updated_at FROM "
139 "statements WHERE id = ? LIMIT 1;");
143 if (stmt.
step() != SQLITE_ROW)
145 auto s = std::make_shared<Statement>();
150 s->setTransactionIds(loadTransactionIds(pimpl_->db->handle(), s->id()));
158 "DELETE FROM statements WHERE id = ?;");
166 const std::shared_ptr<Statement>& statement) {
167 if (!statement || statement->id().empty())
170 "UPDATE statements SET name = ?, created_at = ?, "
171 "updated_at = ? WHERE id = ?;");
174 stmt.
bindText(1, statement->name());
175 stmt.
bindText(2, statement->createdAt());
176 stmt.
bindText(3, statement->updatedAt());
179 saveTransactionIds(pimpl_->db->handle(), statement->id(),
180 statement->transactionIds());
184 const std::shared_ptr<Statement>& statement) {
185 if (!statement || statement->id().empty())
188 if (sqlite3_changes(pimpl_->db->handle()) == 0)
194 sqlite3_exec(pimpl_->db->handle(),
"DELETE FROM statements;",
nullptr,
Declares the lightweight SQLite connection wrapper.
Declares the SQLite-backed statement repository.
Domain model for statements.
RAII wrapper for sqlite3_stmt* that auto-finalizes on destruction.
void updateStatement(const std::shared_ptr< core::domain::Statement > &statement) override
Update an existing statement.
std::vector< std::shared_ptr< core::domain::Statement > > getStatements() const override
Retrieve all statements.
~SqliteStatementRepository() override
Destroy the repository.
void addStatement(const std::shared_ptr< core::domain::Statement > &statement) override
Add a new statement.
void removeStatement(const std::string &id) override
Remove a statement by identifier.
SqliteStatementRepository(const std::string &dbPath)
Create a statement repository for the database at the given path.
void upsertStatement(const std::shared_ptr< core::domain::Statement > &statement) override
Insert or update a statement.
void clearStatements() override
Remove all statements.
std::optional< std::shared_ptr< core::domain::Statement > > getStatementById(const std::string &id) const override
Retrieve a statement by identifier.
std::string columnText(int col) const noexcept
void bindText(int col, const std::string &v) noexcept
std::shared_ptr< core::ports::diagnostics::IErrorReporter > errorReporter
std::shared_ptr< SqliteDb > db