Update running balance only if required
This commit is contained in:
parent
4bbfad335e
commit
48211b2176
23
src/db.ts
23
src/db.ts
@ -74,6 +74,8 @@ export async function totalBalances(session: Database): Promise<{account: string
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function updateRunningBalances() {
|
export async function updateRunningBalances() {
|
||||||
|
// TODO: This is very slow - it would be faster to do this in Rust
|
||||||
|
|
||||||
// Recompute any required running balances
|
// Recompute any required running balances
|
||||||
const session = await db.load();
|
const session = await db.load();
|
||||||
const staleAccountsRaw: {account: string}[] = await session.select('SELECT DISTINCT account FROM postings WHERE running_balance IS NULL');
|
const staleAccountsRaw: {account: string}[] = await session.select('SELECT DISTINCT account FROM postings WHERE running_balance IS NULL');
|
||||||
@ -87,7 +89,7 @@ export async function updateRunningBalances() {
|
|||||||
// FIXME: Recompute balances only from the last non-stale balance to be more efficient
|
// FIXME: Recompute balances only from the last non-stale balance to be more efficient
|
||||||
const arraySQL = '(?' + ', ?'.repeat(staleAccounts.length - 1) + ')';
|
const arraySQL = '(?' + ', ?'.repeat(staleAccounts.length - 1) + ')';
|
||||||
const joinedTransactionPostings: JoinedTransactionPosting[] = await session.select(
|
const joinedTransactionPostings: JoinedTransactionPosting[] = await session.select(
|
||||||
`SELECT postings.id, account, quantity, commodity
|
`SELECT postings.id, account, quantity, commodity, running_balance
|
||||||
FROM transactions
|
FROM transactions
|
||||||
JOIN postings ON transactions.id = postings.transaction_id
|
JOIN postings ON transactions.id = postings.transaction_id
|
||||||
WHERE postings.account IN ${arraySQL}
|
WHERE postings.account IN ${arraySQL}
|
||||||
@ -99,15 +101,20 @@ export async function updateRunningBalances() {
|
|||||||
for (const posting of joinedTransactionPostings) {
|
for (const posting of joinedTransactionPostings) {
|
||||||
const openingBalance = runningBalances.get(posting.account) ?? 0;
|
const openingBalance = runningBalances.get(posting.account) ?? 0;
|
||||||
const quantityCost = asCost(posting.quantity, posting.commodity);
|
const quantityCost = asCost(posting.quantity, posting.commodity);
|
||||||
runningBalances.set(posting.account, openingBalance + quantityCost);
|
const runningBalance = openingBalance + quantityCost;
|
||||||
|
|
||||||
|
runningBalances.set(posting.account, runningBalance);
|
||||||
|
|
||||||
// Update running balance of posting
|
// Update running balance of posting
|
||||||
await session.execute(
|
// Only perform this update if required, to avoid expensive call to DB
|
||||||
`UPDATE postings
|
if (posting.running_balance !== runningBalance) {
|
||||||
SET running_balance = $1
|
await session.execute(
|
||||||
WHERE id = $2`,
|
`UPDATE postings
|
||||||
[openingBalance + quantityCost, posting.id]
|
SET running_balance = $1
|
||||||
);
|
WHERE id = $2`,
|
||||||
|
[runningBalance, posting.id]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user