FOSSredder 0.5.0
Loading...
Searching...
No Matches
SqliteStatementRepository.cpp
Go to the documentation of this file.
1
5
10#include <sqlite3.h>
11#include <stdexcept>
12
13namespace {
14
15std::vector<std::string> loadTransactionIds(sqlite3* db,
16 const std::string& statementId) {
17 std::vector<std::string> ids;
18 if (!db || statementId.empty())
19 return ids;
20
22 db, "SELECT transaction_id FROM statement_transactions WHERE "
23 "statement_id = ? ORDER BY position, transaction_id;");
24 if (!stmt)
25 return ids;
26
27 stmt.bindText(1, statementId);
28 while (stmt.step() == SQLITE_ROW) {
29 ids.push_back(stmt.columnText(0));
30 }
31 return ids;
32}
33
34void saveTransactionIds(sqlite3* db, const std::string& statementId,
35 const std::vector<std::string>& transactionIds) {
36 if (!db || statementId.empty())
37 return;
38
39 persistence::StmtGuard deleteStmt(
40 db, "DELETE FROM statement_transactions WHERE statement_id = ?;");
41 if (!deleteStmt)
42 return;
43 deleteStmt.bindText(1, statementId);
44 deleteStmt.step();
45
46 persistence::StmtGuard insertStmt(
47 db, "INSERT OR IGNORE INTO statement_transactions (statement_id, "
48 "transaction_id, position) VALUES (?, ?, ?);");
49 if (!insertStmt)
50 return;
51
52 for (std::size_t i = 0; i < transactionIds.size(); ++i) {
53 if (transactionIds[i].empty())
54 continue;
55 insertStmt.reset();
56 insertStmt.bindText(1, statementId);
57 insertStmt.bindText(2, transactionIds[i]);
58 insertStmt.bindInt(3, static_cast<int>(i));
59 insertStmt.step();
60 }
61}
62
63} // namespace
64
66 std::shared_ptr<SqliteDb> db;
67 std::shared_ptr<core::ports::diagnostics::IErrorReporter> errorReporter;
68};
69
71 : SqliteStatementRepository(std::make_shared<SqliteDb>(dbPath), nullptr) {}
72
74 const std::string& dbPath,
75 std::shared_ptr<core::ports::diagnostics::IErrorReporter> er)
76 : SqliteStatementRepository(std::make_shared<SqliteDb>(dbPath),
77 std::move(er)) {}
78
80 std::shared_ptr<SqliteDb> db)
81 : SqliteStatementRepository(std::move(db), nullptr) {}
82
84 std::shared_ptr<SqliteDb> db,
85 std::shared_ptr<core::ports::diagnostics::IErrorReporter> er)
86 : pimpl_(std::make_unique<Impl>()) {
87 if (!db)
88 throw std::runtime_error("db is null");
89 pimpl_->db = std::move(db);
90 pimpl_->errorReporter = std::move(er);
91}
92
94
96 const std::shared_ptr<Statement>& statement) {
97 if (!statement || statement->id().empty())
98 return;
99 persistence::StmtGuard stmt(pimpl_->db->handle(),
100 "INSERT OR IGNORE INTO statements (id, name, "
101 "created_at, updated_at) VALUES (?, ?, ?, ?);");
102 if (!stmt)
103 return;
104 stmt.bindText(1, statement->id());
105 stmt.bindText(2, statement->name());
106 stmt.bindText(3, statement->createdAt());
107 stmt.bindText(4, statement->updatedAt());
108 stmt.step();
109 saveTransactionIds(pimpl_->db->handle(), statement->id(),
110 statement->transactionIds());
111}
112
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;");
119 if (!stmt)
120 return out;
121 while (stmt.step() == SQLITE_ROW) {
122 auto s = std::make_shared<Statement>();
123 s->setId(stmt.columnText(0));
124 s->rename(stmt.columnText(1));
125 s->setCreatedAt(stmt.columnText(2));
126 s->setUpdatedAt(stmt.columnText(3));
127 s->setTransactionIds(loadTransactionIds(pimpl_->db->handle(), s->id()));
128 out.push_back(std::move(s));
129 }
130 return out;
131}
132
133std::optional<std::shared_ptr<Statement>>
135 if (id.empty())
136 return std::nullopt;
137 persistence::StmtGuard stmt(pimpl_->db->handle(),
138 "SELECT id, name, created_at, updated_at FROM "
139 "statements WHERE id = ? LIMIT 1;");
140 if (!stmt)
141 return std::nullopt;
142 stmt.bindText(1, id);
143 if (stmt.step() != SQLITE_ROW)
144 return std::nullopt;
145 auto s = std::make_shared<Statement>();
146 s->setId(stmt.columnText(0));
147 s->rename(stmt.columnText(1));
148 s->setCreatedAt(stmt.columnText(2));
149 s->setUpdatedAt(stmt.columnText(3));
150 s->setTransactionIds(loadTransactionIds(pimpl_->db->handle(), s->id()));
151 return s;
152}
153
155 if (id.empty())
156 return;
157 persistence::StmtGuard stmt(pimpl_->db->handle(),
158 "DELETE FROM statements WHERE id = ?;");
159 if (!stmt)
160 return;
161 stmt.bindText(1, id);
162 stmt.step();
163}
164
166 const std::shared_ptr<Statement>& statement) {
167 if (!statement || statement->id().empty())
168 return;
169 persistence::StmtGuard stmt(pimpl_->db->handle(),
170 "UPDATE statements SET name = ?, created_at = ?, "
171 "updated_at = ? WHERE id = ?;");
172 if (!stmt)
173 return;
174 stmt.bindText(1, statement->name());
175 stmt.bindText(2, statement->createdAt());
176 stmt.bindText(3, statement->updatedAt());
177 stmt.bindText(4, statement->id());
178 stmt.step();
179 saveTransactionIds(pimpl_->db->handle(), statement->id(),
180 statement->transactionIds());
181}
182
184 const std::shared_ptr<Statement>& statement) {
185 if (!statement || statement->id().empty())
186 return;
187 updateStatement(statement);
188 if (sqlite3_changes(pimpl_->db->handle()) == 0)
189 addStatement(statement);
190}
191
193 char* err = nullptr;
194 sqlite3_exec(pimpl_->db->handle(), "DELETE FROM statements;", nullptr,
195 nullptr, &err);
196 if (err)
197 sqlite3_free(err);
198}
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
Definition StmtGuard.h:57
int step() noexcept
Definition StmtGuard.h:37
void bindText(int col, const std::string &v) noexcept
Definition StmtGuard.h:44
std::shared_ptr< core::ports::diagnostics::IErrorReporter > errorReporter