Skip to content

Commit b476f05

Browse files
committed
Add auto_batch.USE_WRAPPED toggle
1 parent 89d99d4 commit b476f05

File tree

5 files changed

+87
-68
lines changed

5 files changed

+87
-68
lines changed

.anvil_editor.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ unique_ids:
44
_demo_startup: '1719087683748644303970981.0312'
55
auto_batch: '1720557189347558051799744.9072'
66
tables: '1720711436314890422194670.1993'
7+
tables._tables: '1721062590178633669568195.047'
78
tables.query: '1720557765872560470139563.91'
89
users: '1720885720127965548016217.2301'
910
server_modules:

client_code/auto_batch.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from functools import wraps
55

66

7+
USE_WRAPPED = True
78
_add_queue = defaultdict(list)
89
_update_queue = defaultdict(dict)
910
_delete_queue = []

client_code/tables/__init__.py

Lines changed: 16 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,21 @@
1-
from . import query
2-
from ..auto_batch import batch_tables as app_tables
3-
from ..auto_batch import get_table_by_id, AutoBatch, BatchRow, BatchSearchIterator, BatchTable
4-
import anvil.tables
5-
from functools import wraps
6-
#from contextlib import nullcontext
1+
from ..auto_batch import USE_WRAPPED, AutoBatch, BatchRow, BatchSearchIterator, BatchTable
72

83

9-
class _NullContext: # b/c Skulpt lacks contextlib
10-
def __enter__(self):
11-
return None
12-
13-
def __exit__(self, exc_type, exc_value, traceback):
14-
return False
4+
WRAPPED_ATTRS = [
5+
'query',
6+
'batch_update',
7+
'batch_delete',
8+
'Transaction',
9+
'in_transaction',
10+
'app_tables',
11+
'get_table_by_id',
12+
]
1513

1614

1715
def __getattr__(attr):
18-
return getattr(anvil.tables, attr)
19-
20-
21-
batch_update = _NullContext()
22-
batch_delete = _NullContext()
23-
24-
25-
class Transaction:
26-
def __init__(self, *args, **kwargs):
27-
self.transaction = anvil.tables.Transaction(*args, **kwargs)
28-
self.auto_batch = AutoBatch()
29-
30-
def __enter__(self):
31-
txn = self.transaction.__enter__()
32-
self.auto_batch.__enter__()
33-
return txn
34-
35-
def __exit__(self, exc_type, exc_value, traceback):
36-
self.auto_batch.__exit__(exc_type, exc_value, traceback)
37-
return self.transaction.__exit__(exc_type, exc_value, traceback)
38-
39-
def abort(self):
40-
self.transaction.abort()
41-
42-
43-
def in_transaction(*d_args, **d_kwargs):
44-
# added complications due to @in_transaction's optional 'relaxed' argument:
45-
only_arg_is_func_to_decorate = (len(d_args) == 1 and callable(d_args[0]) and not d_kwargs)
46-
if only_arg_is_func_to_decorate:
47-
func_to_decorate = d_args[0]
48-
tables_in_transaction = anvil.tables.in_transaction
49-
else: #decorator was specified with arg(s) (i.e. 'relaxed')
50-
# func-to-decorate not known yet
51-
tables_in_transaction = anvil.tables.in_transaction(*d_args, **d_kwargs)
52-
53-
def in_transaction_with_auto_batch(func):
54-
@tables_in_transaction
55-
@wraps(func)
56-
def out_function(*args, **kwargs):
57-
with AutoBatch():
58-
result = func(*args, **kwargs) # Call the original function
59-
return result
60-
return out_function
61-
62-
if only_arg_is_func_to_decorate:
63-
return in_transaction_with_auto_batch(func_to_decorate)
64-
else: # composite decorator now configured for 'relaxed' transaction
65-
# Return composite decorator as a function, to then be applied to func-to-decorate
66-
return in_transaction_with_auto_batch
16+
if USE_WRAPPED and attr in WRAPPED_ATTRS:
17+
from . import _tables
18+
return getattr(_tables, attr)
19+
else:
20+
import anvil.tables
21+
return getattr(anvil.tables, attr)

client_code/tables/_tables.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import anvil.tables
2+
from . import query
3+
from ..auto_batch import batch_tables as app_tables
4+
from ..auto_batch import get_table_by_id, AutoBatch, BatchRow, BatchSearchIterator, BatchTable
5+
from functools import wraps
6+
#from contextlib import nullcontext
7+
8+
class _NullContext: # b/c Skulpt lacks contextlib
9+
def __enter__(self):
10+
return None
11+
12+
def __exit__(self, exc_type, exc_value, traceback):
13+
return False
14+
15+
16+
batch_update = _NullContext()
17+
batch_delete = _NullContext()
18+
19+
20+
class Transaction:
21+
def __init__(self, *args, **kwargs):
22+
self.transaction = anvil.tables.Transaction(*args, **kwargs)
23+
self.auto_batch = AutoBatch()
24+
25+
def __enter__(self):
26+
txn = self.transaction.__enter__()
27+
self.auto_batch.__enter__()
28+
return txn
29+
30+
def __exit__(self, exc_type, exc_value, traceback):
31+
self.auto_batch.__exit__(exc_type, exc_value, traceback)
32+
return self.transaction.__exit__(exc_type, exc_value, traceback)
33+
34+
def abort(self):
35+
self.transaction.abort()
36+
37+
38+
def in_transaction(*d_args, **d_kwargs):
39+
# added complications due to @in_transaction's optional 'relaxed' argument:
40+
only_arg_is_func_to_decorate = (len(d_args) == 1 and callable(d_args[0]) and not d_kwargs)
41+
if only_arg_is_func_to_decorate:
42+
func_to_decorate = d_args[0]
43+
tables_in_transaction = anvil.tables.in_transaction
44+
else: #decorator was specified with arg(s) (i.e. 'relaxed')
45+
# func-to-decorate not known yet
46+
tables_in_transaction = anvil.tables.in_transaction(*d_args, **d_kwargs)
47+
48+
def in_transaction_with_auto_batch(func):
49+
@tables_in_transaction
50+
@wraps(func)
51+
def out_function(*args, **kwargs):
52+
with AutoBatch():
53+
result = func(*args, **kwargs) # Call the original function
54+
return result
55+
return out_function
56+
57+
if only_arg_is_func_to_decorate:
58+
return in_transaction_with_auto_batch(func_to_decorate)
59+
else: # composite decorator now configured for 'relaxed' transaction
60+
# Return composite decorator as a function, to then be applied to func-to-decorate
61+
return in_transaction_with_auto_batch

client_code/tables/query.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import anvil.tables.query
2-
from ..auto_batch import debatchify_inputs
2+
from ..auto_batch import USE_WRAPPED
3+
4+
5+
def batch_row_handling(cls):
6+
from ..auto_batch import debatchify_inputs
7+
cls.__init__ = debatchify_inputs(cls.__init__)
8+
return cls
39

410

511
def __getattr__(attr):
6-
if attr in ('all_of', 'any_of', 'none_of', 'not_'):
12+
if USE_WRAPPED and attr in ('all_of', 'any_of', 'none_of', 'not_'):
713
return batch_row_handling(getattr(anvil.tables.query, attr))
814
else:
915
return getattr(anvil.tables.query, attr)
10-
11-
12-
def batch_row_handling(cls):
13-
cls.__init__ = debatchify_inputs(cls.__init__)
14-
return cls

0 commit comments

Comments
 (0)