Skip to content
Snippets Groups Projects
Commit 0e9abad3 authored by Daniele Nicolodi's avatar Daniele Nicolodi
Browse files

orders: Optimization

Matching the accounts with a regular expression allows to extract all
the records with only one BQL query thus not requiring multiple
iterations through the transactions in the ledger.

The regular expression could be further optimized, see Emacs
regexp-opt function, but it is probably not worth the effort.
parent 6417c379
Branches
No related tags found
No related merge requests found
......@@ -32,6 +32,21 @@ EMPTY = frozenset()
ZERO = decimal.Decimal('0.00')
def commonprefix(words):
words = sorted(words)
w1, w2 = words[0], words[-1]
for i in range(len(w1)):
if w1[i] != w2[i]:
return w1[:i]
return w1
def reopts(words):
prefix = commonprefix(words)
n = len(prefix)
return '{}(?:{})$'.format(re.escape(prefix), '|'.join(re.escape(w[n:]) for w in words))
@contextlib.contextmanager
def atomic(filepath):
tmp = filepath + '~tmp'
......@@ -938,25 +953,23 @@ def balance(conf, year):
assert not errors
accounts = list_designated_accounts(entries)
expr = reopts(accounts)
entries = [apply_effective_date(entry, 'payment-date') for entry in entries]
r = []
for account in accounts:
types, rows = query.run_query(entries, options, f"""
SELECT
account,
flag = '*' AS key,
SUM(position) AS total
WHERE
year = {year} AND
account = '{account}' AND
flag != 'P'
GROUP BY
account, key""")
r.extend(rows)
t1 = petl.pushheader(r, [name for name, rtype in types]) \
types, rows = query.run_query(entries, options, f"""
SELECT
account,
flag = '*' AS key,
sum(position) AS total
WHERE
year = {year} AND
account ~ '{expr}' AND
flag != 'P'
GROUP BY
account, key""")
t1 = petl.pushheader(rows, [name for name, rtype in types]) \
.convert('key', lambda v: 'POSTED' if v else 'BOOKED') \
.convert('total', lambda v: v.get_only_position().units)
......@@ -1146,7 +1159,7 @@ def acks(conf):
assert not errors
accounts = list_designated_accounts(entries)
expr = r'(?:{})$'.format('|'.join(re.escape(a) for a in accounts))
expr = reopts(accounts)
types, rows = query.run_query(entries, options, f"""
SELECT
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment