Skip to content

Commit f53f587

Browse files
committed
Merge pull request #33 from wearp/master
Added to Query.search method & tests
2 parents 8f84e94 + 77dc423 commit f53f587

File tree

2 files changed

+51
-7
lines changed

2 files changed

+51
-7
lines changed

tests/test_queries.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ def test_regex():
9292
assert not query({'val': 'ab.'})
9393
assert not query({'': None})
9494

95+
query = where('val').search(r'\d+')
96+
97+
assert query({'val': 'ab3'})
98+
assert not query({'val': 'abc'})
99+
assert not query({'val': ''})
100+
assert not query({'': None})
95101

96102
def test_custom():
97103
def test(value):
@@ -158,17 +164,28 @@ def test_has():
158164
assert query({'key1': {'key2': {'key3': 1}}})
159165
assert not query({'key1': {'key2': {'key3': 0}}})
160166

161-
# Test special methods: regex
167+
# Test special methods: regex matches
162168
query = where('key1').has('value').matches(r'\d+')
163169
assert query({'key1': {'value': '123'}})
164170
assert not query({'key2': {'value': '123'}})
165171
assert not query({'key2': {'value': 'abc'}})
166172

167-
# Test special methods: nested has and regex
173+
# Test special methods: regex search
174+
query = where('key1').has('value').search(r'\d+')
175+
assert query({'key1': {'value': 'a2c'}})
176+
assert not query({'key2': {'value': 'a2c'}})
177+
assert not query({'key2': {'value': 'abc'}})
178+
179+
# Test special methods: nested has and regex matches
168180
query = where('key1').has('x').has('y').matches(r'\d+')
169181
assert query({'key1': {'x': {'y': '123'}}})
170182
assert not query({'key1': {'x': {'y': 'abc'}}})
171183

184+
# Test special method: nested has and regex search
185+
query = where('key1').has('x').has('y').search(r'\d+')
186+
assert query({'key1': {'x': {'y': 'a2c'}}})
187+
assert not query({'key1': {'x': {'y': 'abc'}}})
188+
172189
# Test special methods: custom test
173190
query = where('key1').has('int').test(lambda x: x == 3)
174191
assert query({'key1': {'int': 3}})

tinydb/queries.py

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,20 @@ def matches(self, regex):
9292
:rtype: QueryRegex
9393
"""
9494

95-
return QueryRegex(self._key, regex)
95+
return QueryRegex(self._key, regex, re_method='match')
96+
97+
def search(self, regex):
98+
"""
99+
Run a regex test against a dict value.
100+
101+
>>> where('f1').search(r'\d+')
102+
'f1' ~= \d+
103+
104+
:param regex: The regular expression to pass to ``re.search``
105+
:rtype: QueryRegex
106+
"""
107+
108+
return QueryRegex(self._key, regex, re_method='search')
96109

97110
def test(self, func):
98111
"""
@@ -411,16 +424,18 @@ def __repr__(self):
411424
return '({0}) and ({1})'.format(self._cond_1, self._cond_2)
412425

413426

427+
414428
class QueryRegex(AndOrMixin):
415429
"""
416430
Run a regex test against a dict value.
417431
418432
See :meth:`.Query.matches`.
419433
"""
420434

421-
def __init__(self, key, regex):
435+
def __init__(self, key, regex, re_method):
422436
self.regex = regex
423437
self._key = key
438+
self.re_method = re_method
424439

425440
def __call__(self, element):
426441
"""
@@ -429,8 +444,12 @@ def __call__(self, element):
429444

430445
if self._key not in element:
431446
return False
432-
433-
return re.match(self.regex, element[self._key])
447+
448+
if self.re_method == 'match':
449+
return re.match(self.regex, element[self._key])
450+
451+
if self.re_method == 'search':
452+
return re.search(self.regex, element[self._key])
434453

435454
def __repr__(self):
436455
return '\'{0}\' ~= {1} '.format(self._key, self.regex)
@@ -478,7 +497,15 @@ def matches(self, regex):
478497
See :meth:`.Query.matches`.
479498
"""
480499

481-
self._special = QueryRegex(self._key, regex)
500+
self._special = QueryRegex(self._key, regex, re_method='match')
501+
return self
502+
503+
def search(self, regex):
504+
"""
505+
See :meth:`.Query.search`.
506+
"""
507+
508+
self._special = QueryRegex(self._key, regex, re_method='search')
482509
return self
483510

484511
def test(self, func):

0 commit comments

Comments
 (0)