Projet

Général

Profil

0001-sql-use-custom-json-encoder-for-computed-data-storag.patch

Frédéric Péters, 05 mai 2021 15:10

Télécharger (3,22 ko)

Voir les différences:

Subject: [PATCH] sql: use custom json encoder for computed data storage
 (#53772)

 tests/form_pages/test_computed_field.py | 31 +++++++++++++++++++++++++
 wcs/sql.py                              |  5 ++--
 2 files changed, 34 insertions(+), 2 deletions(-)
tests/form_pages/test_computed_field.py
1 1
import datetime
2
import decimal
2 3

  
3 4
import pytest
4 5
from django.utils.timezone import make_aware
......
330 331
    assert formdata.data['1'] == {'foo': 'bar'}
331 332

  
332 333

  
334
def test_computed_field_decimal_data(pub, http_requests):
335
    FormDef.wipe()
336

  
337
    formdef = FormDef()
338
    formdef.name = 'test'
339
    formdef.fields = [
340
        fields.ComputedField(
341
            id='1',
342
            label='computed',
343
            varname='computed',
344
            value_template='{{ "123.45"|decimal }}',
345
            freeze_on_initial_value=True,
346
        ),
347
        fields.CommentField(id='2', label='X{{form_var_computed}}Y', type='comment'),
348
    ]
349
    formdef.store()
350
    formdef.data_class().wipe()
351

  
352
    resp = get_app(pub).get('/test/')
353
    assert 'X123.45Y' in resp.text
354
    resp = resp.forms[0].submit('submit')  # -> validation
355
    resp = resp.forms[0].submit('submit').follow()  # -> submit
356
    assert 'The form has been recorded' in resp.text
357
    assert formdef.data_class().count() == 1
358
    formdata = formdef.data_class().select()[0]
359
    # pickle storage keeps the typed data but postgresql storage has to convert
360
    # it to stringfor json storage, hence the casting here:
361
    assert decimal.Decimal(formdata.data['1']) == decimal.Decimal('123.45')
362

  
363

  
333 364
def test_computed_field_usage_in_live_data(pub, http_requests):
334 365
    FormDef.wipe()
335 366

  
wcs/sql.py
17 17
import copy
18 18
import datetime
19 19
import io
20
import json
20 21
import re
21 22
import time
22 23
import unicodedata
......
47 48
from . import qommon
48 49
from .publisher import UnpicklerClass
49 50
from .qommon import _, get_cfg
50
from .qommon.misc import strftime
51
from .qommon.misc import JSONEncoder, strftime
51 52
from .qommon.storage import _take, deep_bytes2str
52 53
from .qommon.storage import parse_clause as parse_storage_clause
53 54
from .qommon.substitution import invalidate_substitution_cache
......
1700 1701
                    if value is not None:
1701 1702
                        # embed value in a dict, so it's never necessary to cast the
1702 1703
                        # value for postgresql
1703
                        value = {'data': value, '@type': 'computed-data'}
1704
                        value = {'data': json.loads(JSONEncoder().encode(value)), '@type': 'computed-data'}
1704 1705
                elif sql_type == 'varchar':
1705 1706
                    assert isinstance(value, str)
1706 1707
                elif sql_type == 'date':
1707
-