lorsqu'on normalise une recherche FTS, chercher aussi avec les valeurs d'origine (#75302) #162
|
@ -4429,6 +4429,11 @@ def test_fts_phone(pub):
|
|||
formdata.just_created()
|
||||
formdata.store()
|
||||
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {'1': None, '2': '123456789'}
|
||||
formdata.just_created()
|
||||
formdata.store()
|
||||
|
||||
assert formdef.data_class().count([FtsMatch('01 23 45 67 89')]) == 1
|
||||
assert formdef.data_class().count([FtsMatch('0123456789')]) == 1
|
||||
assert formdef.data_class().count([FtsMatch('+33123456789')]) == 1
|
||||
|
@ -4437,6 +4442,7 @@ def test_fts_phone(pub):
|
|||
assert formdef.data_class().count([FtsMatch('+33(0)123456789 bar')]) == 0
|
||||
assert formdef.data_class().count([FtsMatch('foo +33(0)123456789')]) == 1
|
||||
assert formdef.data_class().count([FtsMatch('bar +33(0)123456789')]) == 0
|
||||
assert formdef.data_class().count([FtsMatch('123456789')]) == 2
|
||||
|
||||
formdata.data = {'1': '+32 2 345 67 89', '2': 'foo'}
|
||||
formdata.store()
|
||||
|
|
26
wcs/sql.py
26
wcs/sql.py
|
@ -437,22 +437,42 @@ class ILike(Criteria):
|
|||
|
||||
class FtsMatch(Criteria):
|
||||
def __init__(self, value, extra_normalize=True):
|
||||
# make Criteria.__repr__ works
|
||||
self.attribute = 'fts'
|
||||
self.value = self.get_fts_value(value)
|
||||
if extra_normalize:
|
||||
phone_match = re.match(r'.*?(?P<phone>\b\+?[-\(\)\d\.\s/]{6,20}\b)', self.value)
|
||||
if phone_match and not re.match(r'^\d+-\d+$', phone_match.group('phone').strip()):
|
||||
if phone_match:
|
||||
# if it looks like a phone number, normalize it to its
|
||||
# "international/E164" format to match what's stored in the
|
||||
# database.
|
||||
phone_value = misc.normalize_phone_number_for_fts(phone_match.group('phone').strip())
|
||||
self.value = self.value.replace(phone_match.group('phone').strip(), phone_value)
|
||||
self.value = [self.value, self.value.replace(phone_match.group('phone').strip(), phone_value)]
|
||||
|
||||
@classmethod
|
||||
def get_fts_value(cls, value):
|
||||
return unidecode.unidecode(value)
|
||||
|
||||
def as_sql(self):
|
||||
return 'fts @@ plainto_tsquery(%%(c%s)s)' % id(self.value)
|
||||
if isinstance(self.value, list):
|
||||
parts = []
|
||||
for value in self.value:
|
||||
parts.append('(%s)' % self.as_sql_part(value))
|
||||
return '(%s)' % ' or '.join(parts)
|
||||
else:
|
||||
return self.as_sql_part(self.value)
|
||||
|
||||
def as_sql_part(self, value):
|
||||
return 'fts @@ plainto_tsquery(%%(%s)s)' % self.value_to_identifier(value)
|
||||
|
||||
def value_to_identifier(self, value):
|
||||
return 'c%s' % id(value)
|
||||
|
||||
def as_sql_param(self):
|
||||
if isinstance(self.value, list):
|
||||
return {self.value_to_identifier(value): value for value in self.value}
|
||||
else:
|
||||
return {self.value_to_identifier(self.value): self.value}
|
||||
|
||||
|
||||
class ElementEqual(Criteria):
|
||||
|
|
Loading…
Reference in New Issue