Projet

Général

Profil

0002-api-backoffice-order-by-rank-65511.patch

Frédéric Péters, 30 mai 2022 09:53

Télécharger (4,4 ko)

Voir les différences:

Subject: [PATCH 2/4] api/backoffice: order by rank (#65511)

 tests/api/test_formdata.py | 51 ++++++++++++++++++++++++++++++++++++++
 wcs/forms/backoffice.py    |  7 +++++-
 wcs/sql.py                 | 10 +++++++-
 3 files changed, 66 insertions(+), 2 deletions(-)
tests/api/test_formdata.py
814 814
        assert len(resp.json) == 14
815 815

  
816 816

  
817
def test_api_list_formdata_order_by_rank(pub, local_user):
818
    if not pub.is_using_postgresql():
819
        pytest.skip('this requires SQL')
820
    pub.role_class.wipe()
821
    role = pub.role_class(name='test')
822
    role.store()
823

  
824
    FormDef.wipe()
825
    formdef = FormDef()
826
    formdef.name = 'test'
827
    formdef.workflow_roles = {'_receiver': role.id}
828
    formdef.fields = [
829
        fields.StringField(id='0', label='a', type='string', display_locations=['listings']),
830
        fields.StringField(id='1', label='b', type='string'),
831
    ]
832
    formdef.store()
833

  
834
    data_class = formdef.data_class()
835
    data_class.wipe()
836

  
837
    # 1st formdata with foo in "unimportant" field
838
    formdata1 = data_class()
839
    formdata1.data = {'1': 'FOO'}
840
    formdata1.just_created()
841
    formdata1.jump_status('new')
842
    formdata1.store()
843

  
844
    # 2nd formdata, with no foo
845
    formdata2 = data_class()
846
    formdata2.data = {}
847
    formdata2.just_created()
848
    formdata2.jump_status('new')
849
    formdata2.store()
850

  
851
    # 3rd formdata, with foo in "important" field
852
    formdata3 = data_class()
853
    formdata3.data = {'0': 'FOO'}
854
    formdata3.just_created()
855
    formdata3.jump_status('new')
856
    formdata3.store()
857

  
858
    # add proper role to user
859
    local_user.roles = [role.id]
860
    local_user.store()
861

  
862
    # check fts
863
    resp = get_app(pub).get(sign_uri('/api/forms/test/list?full=on&q=foo', user=local_user))
864
    assert len(resp.json) == 2
865
    assert [int(x['id']) for x in resp.json] == [formdata3.id, formdata1.id]
866

  
867

  
817 868
def test_api_list_formdata_unknown_filter(pub, local_user):
818 869
    pub.role_class.wipe()
819 870
    role = pub.role_class(name='test')
wcs/forms/backoffice.py
19 19
from quixote import get_publisher, get_request, get_session, redirect
20 20
from quixote.html import TemplateIO, htmltext
21 21

  
22
from wcs.qommon.storage import Contains, NotContains, Null, StrictNotEqual
22
from wcs.qommon.storage import Contains, FtsMatch, NotContains, Null, StrictNotEqual
23 23
from wcs.roles import logged_users_role
24 24

  
25 25
from ..qommon import _, misc
......
306 306
            ordered_ids = formdata_class.get_sorted_ids(order_by, clause=criterias)
307 307
            item_ids_dict = {x: True for x in item_ids}
308 308
            item_ids = [x for x in ordered_ids if x in item_ids_dict]
309
        elif not anonymise and get_publisher().is_using_postgresql() and query:
310
            criterias = [FtsMatch(query)] + (criterias or [])
311
            ordered_ids = formdata_class.get_sorted_ids('rank', clause=criterias)
312
            item_ids_dict = {x: True for x in item_ids}
313
            item_ids = [x for x in ordered_ids if x in item_ids_dict]
309 314
        else:
310 315
            item_ids.sort(key=int)
311 316
            item_ids.reverse()
wcs/sql.py
2361 2361
        assert not func_clause
2362 2362
        if where_clauses:
2363 2363
            sql_statement += ' WHERE ' + ' AND '.join(where_clauses)
2364
        sql_statement += cls.get_order_by_clause(order_by)
2364
        if order_by == 'rank':
2365
            try:
2366
                fts = [x for x in clause if not callable(x) and x.__class__.__name__ == 'FtsMatch'][0]
2367
            except IndexError:
2368
                pass
2369
            else:
2370
                sql_statement += ' ORDER BY ts_rank(fts, plainto_tsquery(%%(c%s)s)) DESC' % id(fts.value)
2371
        else:
2372
            sql_statement += cls.get_order_by_clause(order_by)
2365 2373
        cur.execute(sql_statement, parameters)
2366 2374
        ids = [x[0] for x in cur.fetchall()]
2367 2375
        conn.commit()
2368
-