finnow/finnow-api/source/analytics/data_impl_sqlite.d

104 lines
3.6 KiB
D

module analytics.data_impl_sqlite;
import d2sqlite3;
import std.array;
import std.datetime;
import util.money;
import util.data;
import util.sqlite;
import account.model : AccountJournalEntryType, AccountType;
import analytics.balances;
import analytics.data;
class SqliteAnalyticsRepository : AnalyticsRepository {
private Database db;
this(Database db) {
this.db = db;
}
JournalEntryStub[] getJournalEntries(
in Currency currency,
in TimeRange timeRange
) {
QueryBuilder qb = QueryBuilder("account_journal_entry je")
.select("je.timestamp,je.account_id,je.amount,je.type,account.type")
.join("LEFT JOIN account ON account.id = je.account_id")
.where("UPPER(je.currency) = ?")
.withArgBinding((ref stmt, ref idx) {
stmt.bind(idx++, currency.codeString);
});
if (timeRange.fromTime) {
qb.where("je.timestamp >= ?")
.withArgBinding((ref stmt, ref idx) {
stmt.bind(idx++, timeRange.fromTime.value);
});
}
if (timeRange.toTime) {
qb.where("je.timestamp <= ?")
.withArgBinding((ref stmt, ref idx) {
stmt.bind(idx++, timeRange.fromTime.value);
});
}
string query = qb.build() ~ " ORDER BY je.timestamp";
Statement stmt = db.prepare(query);
qb.applyArgBindings(stmt);
ResultRange result = stmt.execute();
Appender!(JournalEntryStub[]) app;
foreach (row; result) {
auto journalEntryTypeStr = row.peek!(string, PeekMode.slice)(3);
AccountJournalEntryType type;
if (journalEntryTypeStr == AccountJournalEntryType.CREDIT) {
type = AccountJournalEntryType.CREDIT;
} else {
type = AccountJournalEntryType.DEBIT;
}
app ~= JournalEntryStub(
SysTime.fromISOExtString(row.peek!(string, PeekMode.slice)(0)),
row.peek!ulong(1),
AccountType.fromId(row.peek!(string, PeekMode.slice)(4)),
row.peek!ulong(2),
type
);
}
return app[];
}
BalanceRecordStub[] getBalanceRecords(
in Currency currency,
in TimeRange timeRange
) {
QueryBuilder qb = QueryBuilder("account_value_record")
.select("timestamp,account_id,value,type")
.where("UPPER(currency) = ?")
.withArgBinding((ref stmt, ref idx) {
stmt.bind(idx++, currency.codeString);
})
.where("UPPER(type) = 'BALANCE'");
if (timeRange.fromTime) {
qb.where("timestamp >= ?")
.withArgBinding((ref stmt, ref idx) {
stmt.bind(idx++, timeRange.fromTime.value);
});
}
if (timeRange.toTime) {
qb.where("timestamp <= ?")
.withArgBinding((ref stmt, ref idx) {
stmt.bind(idx++, timeRange.fromTime.value);
});
}
string query = qb.build() ~ " ORDER BY timestamp";
Statement stmt = db.prepare(query);
qb.applyArgBindings(stmt);
ResultRange result = stmt.execute();
Appender!(BalanceRecordStub[]) app;
foreach (row; result) {
app ~= BalanceRecordStub(
SysTime.fromISOExtString(row.peek!(string, PeekMode.slice)(0)),
row.peek!ulong(1),
row.peek!long(2)
);
}
return app[];
}
}