sql: get new fts search value when ordering (#74972)
gitea/wcs/pipeline/head This commit looks good
Details
gitea/wcs/pipeline/head This commit looks good
Details
This commit is contained in:
parent
23000e2340
commit
63d4c99c9d
|
@ -339,3 +339,52 @@ def test_card_get_file(pub):
|
|||
assert os.path.exists(thumb_filepath) is True
|
||||
# again, thumbs_dir already exists
|
||||
get_app(pub).get(sign_uri(file_url + '&thumbnail=1'), status=200)
|
||||
|
||||
|
||||
def test_api_list_formdata_phone_order_by_rank(pub):
|
||||
pub.role_class.wipe()
|
||||
role = pub.role_class(name='test')
|
||||
role.store()
|
||||
|
||||
ApiAccess.wipe()
|
||||
access = ApiAccess()
|
||||
access.name = 'test'
|
||||
access.access_identifier = 'test'
|
||||
access.access_key = '12345'
|
||||
access.store()
|
||||
|
||||
CardDef.wipe()
|
||||
carddef = CardDef()
|
||||
carddef.name = 'test'
|
||||
carddef.workflow_roles = {'_receiver': role.id}
|
||||
carddef.fields = [
|
||||
fields.StringField(id='0', label='a', type='string', display_locations=['listings']),
|
||||
fields.StringField(id='1', label='b', type='string'),
|
||||
]
|
||||
carddef.store()
|
||||
|
||||
data_class = carddef.data_class()
|
||||
data_class.wipe()
|
||||
|
||||
# 1st carddata, with phone number
|
||||
carddata1 = data_class()
|
||||
carddata1.data = {'1': '+33623456789'}
|
||||
carddata1.just_created()
|
||||
carddata1.jump_status('new')
|
||||
carddata1.store()
|
||||
|
||||
# 2nd carddata, with no value
|
||||
carddata2 = data_class()
|
||||
carddata2.data = {}
|
||||
carddata2.just_created()
|
||||
carddata2.jump_status('new')
|
||||
carddata2.store()
|
||||
|
||||
# check fts
|
||||
resp = get_app(pub).get(
|
||||
sign_uri(
|
||||
'/api/cards/test/list?full=on&q=0623456789', orig=access.access_identifier, key=access.access_key
|
||||
)
|
||||
)
|
||||
assert len(resp.json['data']) == 1
|
||||
assert [int(x['id']) for x in resp.json['data']] == [carddata1.id]
|
||||
|
|
|
@ -326,7 +326,7 @@ class ILike(Criteria):
|
|||
|
||||
|
||||
class FtsMatch(Criteria):
|
||||
def __init__(self, value, extra_normalize=True):
|
||||
def __init__(self, value, extra_normalize=True, **kwargs):
|
||||
self.value = self.get_fts_value(value)
|
||||
self.extra_normalize = extra_normalize # will be handled in sql.FtsMatch
|
||||
|
||||
|
@ -339,7 +339,7 @@ class FtsMatch(Criteria):
|
|||
|
||||
|
||||
class NotNull(Criteria):
|
||||
def __init__(self, attribute):
|
||||
def __init__(self, attribute, **kwargs):
|
||||
self.attribute = attribute
|
||||
|
||||
def build_lambda(self):
|
||||
|
@ -347,7 +347,7 @@ class NotNull(Criteria):
|
|||
|
||||
|
||||
class Null(Criteria):
|
||||
def __init__(self, attribute):
|
||||
def __init__(self, attribute, **kwargs):
|
||||
self.attribute = attribute
|
||||
|
||||
def build_lambda(self):
|
||||
|
@ -355,7 +355,7 @@ class Null(Criteria):
|
|||
|
||||
|
||||
class ElementEqual(Criteria):
|
||||
def __init__(self, attribute, key, value):
|
||||
def __init__(self, attribute, key, value, **kwargs):
|
||||
self.attribute = attribute
|
||||
self.key = key
|
||||
self.value = value
|
||||
|
@ -365,7 +365,7 @@ class ElementEqual(Criteria):
|
|||
|
||||
|
||||
class ElementILike(Criteria):
|
||||
def __init__(self, attribute, key, value):
|
||||
def __init__(self, attribute, key, value, **kwargs):
|
||||
self.attribute = attribute
|
||||
self.key = key
|
||||
self.value = value
|
||||
|
@ -378,7 +378,7 @@ class ElementILike(Criteria):
|
|||
|
||||
|
||||
class ElementIntersects(Criteria):
|
||||
def __init__(self, attribute, key, value):
|
||||
def __init__(self, attribute, key, value, **kwargs):
|
||||
self.attribute = attribute
|
||||
self.key = key
|
||||
self.value = value
|
||||
|
@ -405,7 +405,7 @@ class Nothing(Criteria):
|
|||
|
||||
|
||||
class Distance(Criteria):
|
||||
def __init__(self, point, distance):
|
||||
def __init__(self, point, distance, **kwargs):
|
||||
self.point = point # {'lat': ..., 'lon': ...}
|
||||
self.distance = distance # in meters
|
||||
|
||||
|
|
18
wcs/sql.py
18
wcs/sql.py
|
@ -330,7 +330,7 @@ class ArrayContains(Contains):
|
|||
class NotNull(Criteria):
|
||||
sql_op = 'IS NOT NULL'
|
||||
|
||||
def __init__(self, attribute):
|
||||
def __init__(self, attribute, **kwargs):
|
||||
self.attribute = attribute
|
||||
|
||||
def as_sql(self):
|
||||
|
@ -425,7 +425,7 @@ class ILike(Criteria):
|
|||
|
||||
|
||||
class FtsMatch(Criteria):
|
||||
def __init__(self, value, extra_normalize=True):
|
||||
def __init__(self, value, extra_normalize=True, **kwargs):
|
||||
# make Criteria.__repr__ works
|
||||
self.attribute = 'fts'
|
||||
self.value = self.get_fts_value(value)
|
||||
|
@ -454,7 +454,7 @@ class FtsMatch(Criteria):
|
|||
|
||||
|
||||
class ElementEqual(Criteria):
|
||||
def __init__(self, attribute, key, value):
|
||||
def __init__(self, attribute, key, value, **kwargs):
|
||||
super().__init__(attribute, value)
|
||||
self.key = key
|
||||
|
||||
|
@ -534,13 +534,21 @@ def parse_clause(clause):
|
|||
func_clauses = []
|
||||
where_clauses = []
|
||||
parameters = {}
|
||||
for element in clause:
|
||||
for i, element in enumerate(clause):
|
||||
if callable(element):
|
||||
func_clauses.append(element)
|
||||
else:
|
||||
sql_class = globals().get(element.__class__.__name__)
|
||||
if sql_class:
|
||||
sql_element = sql_class(**element.__dict__)
|
||||
if isinstance(element, Criteria):
|
||||
# already SQL
|
||||
sql_element = element
|
||||
else:
|
||||
# criteria from wcs.qommon.storage, replace it with its SQL variant
|
||||
# (keep extra _label for display in backoffice)
|
||||
sql_element = sql_class(**element.__dict__)
|
||||
sql_element._label = getattr(element, '_label', None)
|
||||
clause[i] = sql_element
|
||||
where_clauses.append(sql_element.as_sql())
|
||||
parameters.update(sql_element.as_sql_param())
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue