FOSSredder 0.5.0
Loading...
Searching...
No Matches
SqliteStatementDraftRepository.cpp
Go to the documentation of this file.
1
5
7
11#include "persistence/Uuid.h"
12
13#include <sqlite3.h>
14
15#include <stdexcept>
16#include <utility>
17
18namespace {
19
20std::vector<std::string>
21loadStatementDraftTransactionIds(sqlite3* db,
22 const std::string& statementDraftId) {
23 std::vector<std::string> ids;
24 if (!db || statementDraftId.empty()) {
25 return ids;
26 }
27
29 db, "SELECT transaction_draft_id FROM statement_draft_transactions WHERE "
30 "statement_draft_id = ? ORDER BY position, transaction_draft_id;");
31 if (!stmt) {
32 return ids;
33 }
34
35 stmt.bindText(1, statementDraftId);
36 while (stmt.step() == SQLITE_ROW) {
37 ids.push_back(stmt.columnText(0));
38 }
39 return ids;
40}
41
42void saveStatementDraftTransactionIds(
43 sqlite3* db, const std::string& statementDraftId,
44 const std::vector<std::string>& transactionIds) {
45 if (!db || statementDraftId.empty()) {
46 return;
47 }
48
49 persistence::StmtGuard deleteStmt(
50 db,
51 "DELETE FROM statement_draft_transactions WHERE statement_draft_id = ?;");
52 if (!deleteStmt) {
53 return;
54 }
55 deleteStmt.bindText(1, statementDraftId);
56 deleteStmt.step();
57
58 persistence::StmtGuard insertStmt(
59 db,
60 "INSERT OR IGNORE INTO statement_draft_transactions (statement_draft_id, "
61 "transaction_draft_id, position) VALUES (?, ?, ?);");
62 if (!insertStmt) {
63 return;
64 }
65
66 for (std::size_t i = 0; i < transactionIds.size(); ++i) {
67 if (transactionIds[i].empty()) {
68 continue;
69 }
70 insertStmt.reset();
71 insertStmt.bindText(1, statementDraftId);
72 insertStmt.bindText(2, transactionIds[i]);
73 insertStmt.bindInt(3, static_cast<int>(i));
74 insertStmt.step();
75 }
76}
77
78void writeStatementDraft(
79 sqlite3* db,
80 const std::shared_ptr<core::application::importing::draft::StatementDraft>&
81 draft,
82 const char* sql) {
83 if (!db || !draft) {
84 return;
85 }
86
87 if (draft->id.empty()) {
88 draft->id = persistence::generateUuid();
89 }
90
91 persistence::StmtGuard stmt(db, sql);
92 if (!stmt) {
93 return;
94 }
95
96 stmt.bindText(1, draft->id);
97 stmt.bindText(2, draft->name);
98 stmt.bindText(3, draft->createdAt);
99 stmt.bindText(4, draft->updatedAt);
100 stmt.step();
101}
102
103} // namespace
104
106 explicit Impl(std::shared_ptr<SqliteDb> db) : db(std::move(db)) {}
107
108 std::shared_ptr<SqliteDb> db;
109};
110
112 const std::string& dbPath)
113 : SqliteStatementDraftRepository(std::make_shared<SqliteDb>(dbPath)) {}
114
116 std::shared_ptr<SqliteDb> db)
117 : pimpl_(std::make_unique<Impl>(std::move(db))) {
118 if (!pimpl_->db) {
119 throw std::runtime_error("db is null");
120 }
121}
122
124
126 const std::shared_ptr<core::application::importing::draft::StatementDraft>&
127 draft) {
128 const auto db = pimpl_->db->handle();
129 writeStatementDraft(db, draft,
130 "INSERT INTO statement_drafts (id, name, created_at, "
131 "updated_at) VALUES (?, ?, ?, ?);");
132 if (draft) {
133 saveStatementDraftTransactionIds(db, draft->id, draft->transactionIds);
134 }
135}
136
137std::vector<
138 std::shared_ptr<core::application::importing::draft::StatementDraft>>
140 std::vector<
141 std::shared_ptr<core::application::importing::draft::StatementDraft>>
142 drafts;
143 persistence::StmtGuard stmt(pimpl_->db->handle(),
144 "SELECT id, name, created_at, updated_at FROM "
145 "statement_drafts ORDER BY id;");
146 if (!stmt) {
147 return drafts;
148 }
149
150 while (stmt.step() == SQLITE_ROW) {
151 auto draft =
152 std::make_shared<core::application::importing::draft::StatementDraft>();
153 draft->id = stmt.columnText(0);
154 draft->name = stmt.columnText(1);
155 draft->createdAt = stmt.columnText(2);
156 draft->updatedAt = stmt.columnText(3);
157 draft->transactionIds =
158 loadStatementDraftTransactionIds(pimpl_->db->handle(), draft->id);
159 drafts.push_back(std::move(draft));
160 }
161
162 return drafts;
163}
164
165std::optional<
166 std::shared_ptr<core::application::importing::draft::StatementDraft>>
168 const std::string& id) const {
169 persistence::StmtGuard stmt(pimpl_->db->handle(),
170 "SELECT id, name, created_at, updated_at FROM "
171 "statement_drafts WHERE id = ? LIMIT 1;");
172 if (!stmt) {
173 return std::nullopt;
174 }
175
176 stmt.bindText(1, id);
177 if (stmt.step() != SQLITE_ROW) {
178 return std::nullopt;
179 }
180
181 auto draft =
182 std::make_shared<core::application::importing::draft::StatementDraft>();
183 draft->id = stmt.columnText(0);
184 draft->name = stmt.columnText(1);
185 draft->createdAt = stmt.columnText(2);
186 draft->updatedAt = stmt.columnText(3);
187 draft->transactionIds =
188 loadStatementDraftTransactionIds(pimpl_->db->handle(), draft->id);
189 return draft;
190}
191
193 const std::string& id) {
194 persistence::StmtGuard stmt(pimpl_->db->handle(),
195 "DELETE FROM statement_drafts WHERE id = ?;");
196 if (!stmt) {
197 return;
198 }
199 stmt.bindText(1, id);
200 stmt.step();
201}
202
204 const std::shared_ptr<core::application::importing::draft::StatementDraft>&
205 draft) {
206 const auto db = pimpl_->db->handle();
207 writeStatementDraft(db, draft,
208 "UPDATE statement_drafts SET name = ?2, created_at = ?3, "
209 "updated_at = ?4 WHERE id = ?1;");
210 if (draft) {
211 saveStatementDraftTransactionIds(db, draft->id, draft->transactionIds);
212 }
213}
214
216 const std::shared_ptr<core::application::importing::draft::StatementDraft>&
217 draft) {
218 const auto db = pimpl_->db->handle();
219 writeStatementDraft(db, draft,
220 "INSERT OR REPLACE INTO statement_drafts (id, name, "
221 "created_at, updated_at) VALUES (?, ?, ?, ?);");
222 if (draft) {
223 saveStatementDraftTransactionIds(db, draft->id, draft->transactionIds);
224 }
225}
226
228 persistence::StmtGuard stmt(pimpl_->db->handle(),
229 "DELETE FROM statement_drafts;");
230 if (!stmt) {
231 return;
232 }
233 stmt.step();
234}
Declares the lightweight SQLite connection wrapper.
Declares the SQLite-backed statement draft repository.
Draft statement model used by import finalization and core application flow.
RAII wrapper for sqlite3_stmt* that auto-finalizes on destruction.
void removeStatementDraft(const std::string &id) override
Remove a statement draft by identifier.
void addStatementDraft(const std::shared_ptr< core::application::importing::draft::StatementDraft > &draft) override
Insert a new statement draft.
void upsertStatementDraft(const std::shared_ptr< core::application::importing::draft::StatementDraft > &draft) override
Insert or update a statement draft.
SqliteStatementDraftRepository(const std::string &dbPath)
Create a statement draft repository for the database at the given path.
std::optional< std::shared_ptr< core::application::importing::draft::StatementDraft > > getStatementDraftById(const std::string &id) const override
Retrieve a statement draft by identifier.
void updateStatementDraft(const std::shared_ptr< core::application::importing::draft::StatementDraft > &draft) override
Update an existing statement draft.
std::vector< std::shared_ptr< core::application::importing::draft::StatementDraft > > getStatementDrafts() const override
Retrieve all statement drafts.
~SqliteStatementDraftRepository() override
Destroy the repository.
void clearStatementDrafts() override
Remove all statement drafts.
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::string generateUuid()
Definition Uuid.h:9