book: add caching for line

This commit is contained in:
Frederik Jaeckel 2023-02-27 20:37:38 +01:00
parent 624a5bff55
commit 39309783b6
5 changed files with 51 additions and 10 deletions

13
book.py
View file

@ -15,7 +15,7 @@ from datetime import date
from sql.aggregate import Sum from sql.aggregate import Sum
from sql.conditionals import Case from sql.conditionals import Case
from .model import order_name_hierarchical, sub_ids_hierarchical, \ from .model import order_name_hierarchical, sub_ids_hierarchical, \
AnyInArray, CACHEKEY_CURRENCY AnyInArray, CACHEKEY_CURRENCY, CACHEKEY_CASHBOOK
STATES = { STATES = {
@ -262,6 +262,16 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
} }
return recname return recname
def get_cachekeys_by_hierarchy(self):
""" generate keys for all cashbooks above us
"""
CBook = Pool().get('cashbook.book')
return [CACHEKEY_CASHBOOK % x.id
for x in CBook.search([
('parent', 'parent_of', [self.id]),
], order=[('id', 'ASC')])]
@classmethod @classmethod
def get_balance_of_cashbook_sql(cls): def get_balance_of_cashbook_sql(cls):
""" sql for balance of a single cashbook """ sql for balance of a single cashbook
@ -371,6 +381,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
query = [{ query = [{
'model': 'cashbook.line', 'model': 'cashbook.line',
'query': [('cashbook.parent', 'child_of', [x.id])], 'query': [('cashbook.parent', 'child_of', [x.id])],
'cachekey': CACHEKEY_CASHBOOK % x.id,
}, { }, {
'model': 'currency.currency.rate', 'model': 'currency.currency.rate',
'query': [('currency.id', '=', x.currency.id)], 'query': [('currency.id', '=', x.currency.id)],

23
line.py
View file

@ -16,6 +16,7 @@ from sql.functions import DatePart
from sql.conditionals import Case from sql.conditionals import Case
from .book import sel_state_book from .book import sel_state_book
from .mixin import SecondCurrencyMixin, MemCacheIndexMx from .mixin import SecondCurrencyMixin, MemCacheIndexMx
from .model import CACHEKEY_CASHBOOK
sel_payee = [ sel_payee = [
@ -983,6 +984,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
def create(cls, vlist): def create(cls, vlist):
""" add debit/credit """ add debit/credit
""" """
MemCache = Pool().get('cashbook.memcache')
vlist = [x.copy() for x in vlist] vlist = [x.copy() for x in vlist]
for values in vlist: for values in vlist:
values.update(cls.add_values_from_splitlines(values)) values.update(cls.add_values_from_splitlines(values))
@ -1003,13 +1006,20 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
'descr': values.get('description', '-'), 'descr': values.get('description', '-'),
}, },
)) ))
return super(Line, cls).create(vlist) records = super(Line, cls).create(vlist)
for record in records:
for x in record.cashbook.get_cachekeys_by_hierarchy():
MemCache.record_update(x, record)
return records
@classmethod @classmethod
def write(cls, *args): def write(cls, *args):
""" deny update if cashbook.line!='open', """ deny update if cashbook.line!='open',
add or update debit/credit add or update debit/credit
""" """
MemCache = Pool().get('cashbook.memcache')
actions = iter(args) actions = iter(args)
to_write = [] to_write = []
for lines, values in zip(actions, actions): for lines, values in zip(actions, actions):
@ -1056,11 +1066,22 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
super(Line, cls).write(*to_write) super(Line, cls).write(*to_write)
actions = iter(to_write)
for records, values in zip(actions, actions):
for record in records:
for x in record.cashbook.get_cachekeys_by_hierarchy():
MemCache.record_update(x, record)
@classmethod @classmethod
def delete(cls, lines): def delete(cls, lines):
""" deny delete if book is not 'open' or wf is not 'edit' """ deny delete if book is not 'open' or wf is not 'edit'
""" """
MemCache = Pool().get('cashbook.memcache')
cls.check_permission_delete(lines) cls.check_permission_delete(lines)
for line in lines:
for x in line.cashbook.get_cachekeys_by_hierarchy():
MemCache.record_update(x, None)
super(Line, cls).delete(lines) super(Line, cls).delete(lines)
# end Line # end Line

View file

@ -7,7 +7,7 @@ from trytond.model import MultiValueMixin, ValueMixin, fields, Unique, Model
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.pool import Pool from trytond.pool import Pool
from trytond.cache import MemoryCache from trytond.cache import MemoryCache
from datetime import timedelta, datetime from datetime import timedelta
from decimal import Decimal from decimal import Decimal
from sql import With, Literal from sql import With, Literal
from sql.functions import Function from sql.functions import Function
@ -15,6 +15,7 @@ from sql.conditionals import Coalesce
ENABLE_CACHE = True ENABLE_CACHE = True
CACHEKEY_CURRENCY = 'currency-%s' CACHEKEY_CURRENCY = 'currency-%s'
CACHEKEY_CASHBOOK = 'cashbook-%s'
class ArrayAgg(Function): class ArrayAgg(Function):
@ -140,8 +141,6 @@ class MemCache(Model):
if ENABLE_CACHE == False: if ENABLE_CACHE == False:
return '-' return '-'
dt1 = datetime.now()
print('-- get_key_by_record:', name, record.id)
fname = [name, str(record.id)] fname = [name, str(record.id)]
fname.extend(addkeys) fname.extend(addkeys)
@ -185,8 +184,6 @@ class MemCache(Model):
if 'cachekey' in line.keys(): if 'cachekey' in line.keys():
key = cls.store_value(line['cachekey'], fname[-1]) key = cls.store_value(line['cachekey'], fname[-1])
print('-- get_key_by_record-END:', datetime.now() - dt1, '-'.join(fname))
return '-'.join(fname) return '-'.join(fname)
@classmethod @classmethod

View file

@ -9,6 +9,7 @@ from trytond.transaction import Transaction
from trytond.exceptions import UserError from trytond.exceptions import UserError
from datetime import date from datetime import date
from decimal import Decimal from decimal import Decimal
from trytond.modules.cashbook.model import CACHEKEY_CASHBOOK
class BookTestCase(ModuleTestCase): class BookTestCase(ModuleTestCase):
@ -189,6 +190,11 @@ class BookTestCase(ModuleTestCase):
self.assertEqual(book.rec_name, 'Level 1') self.assertEqual(book.rec_name, 'Level 1')
self.assertEqual(len(book.childs), 1) self.assertEqual(len(book.childs), 1)
self.assertEqual(book.childs[0].rec_name, 'Level 1/Level 2 | 0.00 usd | Open') self.assertEqual(book.childs[0].rec_name, 'Level 1/Level 2 | 0.00 usd | Open')
self.assertEqual(book.get_cachekeys_by_hierarchy(), [CACHEKEY_CASHBOOK % book.id])
self.assertEqual(book.childs[0].get_cachekeys_by_hierarchy(), [
CACHEKEY_CASHBOOK % book.id,
CACHEKEY_CASHBOOK % book.childs[0].id
])
@with_transaction() @with_transaction()
def test_book_deny_delete_open(self): def test_book_deny_delete_open(self):

View file

@ -6,7 +6,7 @@
from trytond.tests.test_tryton import ModuleTestCase, with_transaction from trytond.tests.test_tryton import ModuleTestCase, with_transaction
from trytond.pool import Pool from trytond.pool import Pool
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.modules.cashbook.model import CACHEKEY_CURRENCY from trytond.modules.cashbook.model import CACHEKEY_CURRENCY, ENABLE_CACHE
from datetime import date from datetime import date
from decimal import Decimal from decimal import Decimal
import time import time
@ -53,7 +53,10 @@ class CurrencyTestCase(ModuleTestCase):
value = '%d-c%s' % ( value = '%d-c%s' % (
currency.rates[0].id, currency.rates[0].id,
str(currency.rates[0].create_date.timestamp())) str(currency.rates[0].create_date.timestamp()))
if ENABLE_CACHE == True:
self.assertEqual(MemCache.read_value(cache_key), value) self.assertEqual(MemCache.read_value(cache_key), value)
else :
self.assertEqual(MemCache.read_value(cache_key), None)
time.sleep(1.0) time.sleep(1.0)
Currency.write(*[ Currency.write(*[
@ -70,7 +73,10 @@ class CurrencyTestCase(ModuleTestCase):
value = '%d-w%s' % ( value = '%d-w%s' % (
currency.rates[0].id, currency.rates[0].id,
str(currency.rates[0].write_date.timestamp())) str(currency.rates[0].write_date.timestamp()))
if ENABLE_CACHE == True:
self.assertEqual(MemCache.read_value(cache_key), value) self.assertEqual(MemCache.read_value(cache_key), value)
else :
self.assertEqual(MemCache.read_value(cache_key), None)
Currency.write(*[ Currency.write(*[
[currency], [currency],