139 lines
4.1 KiB
D
139 lines
4.1 KiB
D
|
module account.data_impl_sqlite;
|
||
|
|
||
|
import std.datetime;
|
||
|
|
||
|
import d2sqlite3;
|
||
|
import handy_httpd.components.optional;
|
||
|
|
||
|
import account.data;
|
||
|
import account.model;
|
||
|
import money.currency;
|
||
|
import history.model;
|
||
|
import util.sqlite;
|
||
|
|
||
|
class SqliteAccountRepository : AccountRepository {
|
||
|
private Database db;
|
||
|
this(Database db) {
|
||
|
this.db = db;
|
||
|
}
|
||
|
|
||
|
Optional!Account findById(ulong id) {
|
||
|
return findOne(
|
||
|
db,
|
||
|
"SELECT * FROM account WHERE id = ?",
|
||
|
&parseAccount,
|
||
|
id
|
||
|
);
|
||
|
}
|
||
|
|
||
|
Account insert(AccountType type, string numberSuffix, string name, Currency currency, string description) {
|
||
|
Statement stmt = db.prepare(q"SQL
|
||
|
INSERT INTO account
|
||
|
(created_at, type, number_suffix, name, currency, description)
|
||
|
VALUES (?, ?, ?, ?, ?, ?)
|
||
|
SQL");
|
||
|
stmt.bind(1, Clock.currTime(UTC()).toISOExtString());
|
||
|
stmt.bind(2, type.id);
|
||
|
stmt.bind(3, numberSuffix);
|
||
|
stmt.bind(4, name);
|
||
|
stmt.bind(5, currency.code);
|
||
|
stmt.bind(6, description);
|
||
|
stmt.execute();
|
||
|
ulong accountId = db.lastInsertRowid();
|
||
|
return findById(accountId).orElseThrow("Couldn't find account!");
|
||
|
}
|
||
|
|
||
|
void setArchived(ulong id, bool archived) {
|
||
|
util.sqlite.update(
|
||
|
db,
|
||
|
"UPDATE account SET archived = ? WHERE id = ?",
|
||
|
archived ? 1 : 0,
|
||
|
id
|
||
|
);
|
||
|
}
|
||
|
|
||
|
Account update(ulong id, in Account newData) {
|
||
|
return newData; // TODO:
|
||
|
}
|
||
|
|
||
|
void deleteById(ulong id) {
|
||
|
doTransaction(db, () {
|
||
|
util.sqlite.update(
|
||
|
db,
|
||
|
"DELETE FROM history
|
||
|
WHERE id IN (
|
||
|
SELECT history_id FROM account_history
|
||
|
WHERE account_id = ?
|
||
|
)",
|
||
|
id
|
||
|
);
|
||
|
util.sqlite.update(db, "DELETE FROM account WHERE id = ?", id);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
Account[] findAll() {
|
||
|
return util.sqlite.findAll(db, "SELECT * FROM account", &parseAccount);
|
||
|
}
|
||
|
|
||
|
AccountCreditCardProperties getCreditCardProperties(ulong id) {
|
||
|
Statement stmt = db.prepare("SELECT * FROM account_credit_card_properties WHERE account_id = ?");
|
||
|
stmt.bind(1, id);
|
||
|
ResultRange result = stmt.execute();
|
||
|
return parseCreditCardProperties(result.front);
|
||
|
}
|
||
|
|
||
|
void setCreditCardProperties(ulong id, in AccountCreditCardProperties props) {
|
||
|
// TODO:
|
||
|
}
|
||
|
|
||
|
History getHistory(ulong id) {
|
||
|
if (!exists(db, "SELECT id FROM account WHERE id = ?", id)) {
|
||
|
throw new Exception("Account doesn't exist.");
|
||
|
}
|
||
|
Optional!History history = findOne(
|
||
|
db,
|
||
|
q"SQL
|
||
|
SELECT * FROM history
|
||
|
LEFT JOIN account_history ah ON ah.history_id = history.id
|
||
|
WHERE ah.account_id = ?
|
||
|
SQL",
|
||
|
r => History(r.peek!ulong(0)),
|
||
|
id
|
||
|
);
|
||
|
if (!history.empty) {
|
||
|
return history.value;
|
||
|
}
|
||
|
// No history exists yet, so add it.
|
||
|
ulong historyId = doTransaction(db, () {
|
||
|
util.sqlite.update(db, "INSERT INTO history DEFAULT VALUES");
|
||
|
ulong historyId = db.lastInsertRowid();
|
||
|
util.sqlite.update(db, "INSERT INTO account_history (account_id, history_id) VALUES (?, ?)", id, historyId);
|
||
|
return historyId;
|
||
|
});
|
||
|
return History(historyId);
|
||
|
}
|
||
|
|
||
|
static Account parseAccount(Row row) {
|
||
|
return Account(
|
||
|
row.peek!ulong(0),
|
||
|
SysTime.fromISOExtString(row.peek!string(1)),
|
||
|
row.peek!bool(2),
|
||
|
AccountType.fromId(row.peek!string(3)),
|
||
|
row.peek!string(4),
|
||
|
row.peek!string(5),
|
||
|
Currency.ofCode(row.peek!string(6)),
|
||
|
row.peek!string(7)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
static AccountCreditCardProperties parseCreditCardProperties(Row row) {
|
||
|
import std.typecons : Nullable;
|
||
|
ulong accountId = row.peek!ulong(0);
|
||
|
Nullable!ulong creditLimit = row.peek!ulong(1);
|
||
|
return AccountCreditCardProperties(
|
||
|
accountId,
|
||
|
creditLimit.isNull ? -1 : creditLimit.get()
|
||
|
);
|
||
|
}
|
||
|
}
|