module history.data_impl_sqlite; import std.datetime; import handy_httpd.components.optional; import d2sqlite3; import history.data; import history.model; import util.sqlite; class SqliteHistoryRepository : HistoryRepository { private Database db; this(Database db) { this.db = db; } Optional!History findById(ulong id) { Statement stmt = db.prepare("SELECT * FROM history WHERE id = ?"); stmt.bind(1, id); ResultRange result = stmt.execute(); if (result.empty) return Optional!History.empty; return Optional!History.of(parseHistory(result.front)); } HistoryItem[] findItemsBefore(ulong historyId, SysTime timestamp, uint limit) { import std.conv; import std.algorithm; import std.array; const query = q"SQL SELECT * FROM history_item WHERE history_id = ? AND timestamp <= ? ORDER BY timestamp DESC LIMIT SQL"; Statement stmt = db.prepare(query ~ " " ~ to!string(limit)); stmt.bind(1, historyId); stmt.bind(2, timestamp.toISOExtString()); ResultRange result = stmt.execute(); return result.map!(r => parseItem(r)).array; } HistoryItemText getTextItem(ulong itemId) { Statement stmt = db.prepare("SELECT * FROM history_item_text WHERE item_id = ?"); stmt.bind(1, itemId); ResultRange result = stmt.execute(); if (result.empty) throw new Exception("No history item exists."); return parseTextItem(result.front); } void addTextItem(ulong historyId, SysTime timestamp, string text) { ulong itemId = addItem(historyId, timestamp, HistoryItemType.TEXT); update( db, "INSERT INTO history_item_text (item_id, content) VALUES (?, ?)", itemId, text ); } void deleteById(ulong id) { Statement stmt = db.prepare("DELETE FROM history WHERE id = ?"); stmt.bind(1, id); stmt.execute(); } static History parseHistory(Row row) { return History(row.peek!ulong(0)); } static HistoryItem parseItem(Row row) { HistoryItem item; item.id = row.peek!ulong(0); item.historyId = row.peek!ulong(1); item.timestamp = SysTime.fromISOExtString(row.peek!string(2)); item.type = getHistoryItemType(row.peek!string(3)); return item; } static HistoryItemText parseTextItem(Row row) { HistoryItemText item; item.itemId = row.peek!ulong(0); item.content = row.peek!string(1); return item; } private ulong addItem(ulong historyId, SysTime timestamp, HistoryItemType type) { update( db, "INSERT INTO history_item (history_id, timestamp, type) VALUES (?, ?, ?)", historyId, timestamp, type ); return db.lastInsertRowid(); } }