FOSSredder 0.5.0
Loading...
Searching...
No Matches
SqliteExportLogRepository.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> loadIds(sqlite3* db, const char* sql,
21 const std::string& exportLogId) {
22 std::vector<std::string> ids;
23 if (!db || exportLogId.empty()) {
24 return ids;
25 }
26
27 persistence::StmtGuard stmt(db, sql);
28 if (!stmt) {
29 return ids;
30 }
31
32 stmt.bindText(1, exportLogId);
33 while (stmt.step() == SQLITE_ROW) {
34 ids.push_back(stmt.columnText(0));
35 }
36 return ids;
37}
38
39void saveIds(sqlite3* db, const std::string& exportLogId,
40 const std::vector<std::string>& ids, const char* deleteSql,
41 const char* insertSql) {
42 if (!db || exportLogId.empty()) {
43 return;
44 }
45
46 persistence::StmtGuard deleteStmt(db, deleteSql);
47 if (!deleteStmt) {
48 return;
49 }
50 deleteStmt.bindText(1, exportLogId);
51 deleteStmt.step();
52
53 persistence::StmtGuard insertStmt(db, insertSql);
54 if (!insertStmt) {
55 return;
56 }
57
58 for (std::size_t i = 0; i < ids.size(); ++i) {
59 const auto& id = ids[i];
60 if (id.empty()) {
61 continue;
62 }
63 insertStmt.reset();
64 insertStmt.bindText(1, exportLogId);
65 insertStmt.bindText(2, id);
66 insertStmt.bindInt(3, static_cast<int>(i));
67 insertStmt.step();
68 }
69}
70
71void writeExportLog(
72 sqlite3* db,
73 const std::shared_ptr<core::application::exporting::ExportLog>& log,
74 const char* sql) {
75 if (!db || !log) {
76 return;
77 }
78
79 if (log->id.empty()) {
80 log->id = persistence::generateUuid();
81 }
82
83 persistence::StmtGuard stmt(db, sql);
84 if (!stmt) {
85 return;
86 }
87
88 stmt.bindText(1, log->id);
89 stmt.bindText(2, log->time);
90 stmt.bindText(3, log->targetPath);
91 stmt.bindText(4, log->status);
92 stmt.bindText(5, log->message);
93 stmt.step();
94}
95
96} // namespace
97
99 explicit Impl(std::shared_ptr<SqliteDb> db) : db(std::move(db)) {}
100
101 std::shared_ptr<SqliteDb> db;
102};
103
105 : SqliteExportLogRepository(std::make_shared<SqliteDb>(dbPath)) {}
106
108 std::shared_ptr<SqliteDb> db)
109 : pimpl_(std::make_unique<Impl>(std::move(db))) {
110 if (!pimpl_->db) {
111 throw std::runtime_error("db is null");
112 }
113}
114
116
118 const std::shared_ptr<core::application::exporting::ExportLog>& log) {
119 const auto db = pimpl_->db->handle();
120 writeExportLog(db, log,
121 "INSERT INTO export_logs (id, time, target_path, status, "
122 "message) VALUES (?, ?, ?, ?, ?);");
123 if (log) {
124 saveIds(db, log->id, log->annualIds,
125 "DELETE FROM export_log_annuals WHERE export_log_id = ?;",
126 "INSERT OR IGNORE INTO export_log_annuals (export_log_id, "
127 "annual_id, position) VALUES (?, ?, ?);");
128 saveIds(db, log->id, log->analysisIds,
129 "DELETE FROM export_log_analyses WHERE export_log_id = ?;",
130 "INSERT OR IGNORE INTO export_log_analyses (export_log_id, "
131 "analysis_id, position) VALUES (?, ?, ?);");
132 }
133}
134
135std::vector<std::shared_ptr<core::application::exporting::ExportLog>>
137 std::vector<std::shared_ptr<core::application::exporting::ExportLog>> logs;
138 const auto db = pimpl_->db->handle();
140 "SELECT id, time, target_path, status, message "
141 "FROM export_logs ORDER BY time DESC, id DESC;");
142 if (!stmt) {
143 return logs;
144 }
145
146 while (stmt.step() == SQLITE_ROW) {
147 auto log = std::make_shared<core::application::exporting::ExportLog>();
148 log->id = stmt.columnText(0);
149 log->time = stmt.columnText(1);
150 log->targetPath = stmt.columnText(2);
151 log->status = stmt.columnText(3);
152 log->message = stmt.columnText(4);
153 log->annualIds = loadIds(db,
154 "SELECT annual_id FROM export_log_annuals WHERE "
155 "export_log_id = ? ORDER BY position, annual_id;",
156 log->id);
157 log->analysisIds =
158 loadIds(db,
159 "SELECT analysis_id FROM export_log_analyses WHERE "
160 "export_log_id = ? ORDER BY position, analysis_id;",
161 log->id);
162 logs.push_back(std::move(log));
163 }
164
165 return logs;
166}
167
168std::optional<std::shared_ptr<core::application::exporting::ExportLog>>
170 const auto db = pimpl_->db->handle();
172 "SELECT id, time, target_path, status, message "
173 "FROM export_logs WHERE id = ? LIMIT 1;");
174 if (!stmt) {
175 return std::nullopt;
176 }
177
178 stmt.bindText(1, id);
179 if (stmt.step() != SQLITE_ROW) {
180 return std::nullopt;
181 }
182
183 auto log = std::make_shared<core::application::exporting::ExportLog>();
184 log->id = stmt.columnText(0);
185 log->time = stmt.columnText(1);
186 log->targetPath = stmt.columnText(2);
187 log->status = stmt.columnText(3);
188 log->message = stmt.columnText(4);
189 log->annualIds = loadIds(db,
190 "SELECT annual_id FROM export_log_annuals WHERE "
191 "export_log_id = ? ORDER BY position, annual_id;",
192 log->id);
193 log->analysisIds =
194 loadIds(db,
195 "SELECT analysis_id FROM export_log_analyses WHERE export_log_id "
196 "= ? ORDER BY position, analysis_id;",
197 log->id);
198 return log;
199}
200
202 persistence::StmtGuard stmt(pimpl_->db->handle(),
203 "DELETE FROM export_logs WHERE id = ?;");
204 if (!stmt) {
205 return;
206 }
207 stmt.bindText(1, id);
208 stmt.step();
209}
210
212 const std::shared_ptr<core::application::exporting::ExportLog>& log) {
213 const auto db = pimpl_->db->handle();
214 writeExportLog(db, log,
215 "UPDATE export_logs SET time = ?2, target_path = ?3, status = "
216 "?4, message = ?5 WHERE id = ?1;");
217 if (log) {
218 saveIds(db, log->id, log->annualIds,
219 "DELETE FROM export_log_annuals WHERE export_log_id = ?;",
220 "INSERT OR IGNORE INTO export_log_annuals (export_log_id, "
221 "annual_id, position) VALUES (?, ?, ?);");
222 saveIds(db, log->id, log->analysisIds,
223 "DELETE FROM export_log_analyses WHERE export_log_id = ?;",
224 "INSERT OR IGNORE INTO export_log_analyses (export_log_id, "
225 "analysis_id, position) VALUES (?, ?, ?);");
226 }
227}
228
230 const std::shared_ptr<core::application::exporting::ExportLog>& log) {
231 const auto db = pimpl_->db->handle();
232 writeExportLog(db, log,
233 "INSERT OR REPLACE INTO export_logs (id, time, target_path, "
234 "status, message) VALUES (?, ?, ?, ?, ?);");
235 if (log) {
236 saveIds(db, log->id, log->annualIds,
237 "DELETE FROM export_log_annuals WHERE export_log_id = ?;",
238 "INSERT OR IGNORE INTO export_log_annuals (export_log_id, "
239 "annual_id, position) VALUES (?, ?, ?);");
240 saveIds(db, log->id, log->analysisIds,
241 "DELETE FROM export_log_analyses WHERE export_log_id = ?;",
242 "INSERT OR IGNORE INTO export_log_analyses (export_log_id, "
243 "analysis_id, position) VALUES (?, ?, ?);");
244 }
245}
246
248 persistence::StmtGuard stmt(pimpl_->db->handle(), "DELETE FROM export_logs;");
249 if (!stmt) {
250 return;
251 }
252 stmt.step();
253}
Declares the persisted metadata record for an export run.
Declares the lightweight SQLite connection wrapper.
Declares the SQLite-backed export log repository.
RAII wrapper for sqlite3_stmt* that auto-finalizes on destruction.
void clearExportLogs() override
Remove all export log entries.
SqliteExportLogRepository(const std::string &dbPath)
Create an export log repository for the database at the given path.
std::vector< std::shared_ptr< core::application::exporting::ExportLog > > getExportLogs() const override
Retrieve all export log entries.
std::optional< std::shared_ptr< core::application::exporting::ExportLog > > getExportLogById(const std::string &id) const override
Retrieve an export log entry by identifier.
void addExportLog(const std::shared_ptr< core::application::exporting::ExportLog > &log) override
Insert a new export log entry.
void upsertExportLog(const std::shared_ptr< core::application::exporting::ExportLog > &log) override
Insert or update an export log entry.
~SqliteExportLogRepository() override
Destroy the repository.
void updateExportLog(const std::shared_ptr< core::application::exporting::ExportLog > &log) override
Update an existing export log entry.
void removeExportLog(const std::string &id) override
Remove an export log entry 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::string generateUuid()
Definition Uuid.h:9
Impl(std::shared_ptr< SqliteDb > db)