Skip to content

Commit

Permalink
Add contains and contains_all filters.
Browse files Browse the repository at this point in the history
Fixes #343

Co-authored-by: Julien Lebunetel <julien@lebunetel.com>
  • Loading branch information
Rémy HUBSCHER and jlebunetel committed Apr 16, 2018
1 parent 4c03306 commit 26d64ed
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
8 changes: 8 additions & 0 deletions kinto/core/storage/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,12 @@ def extract_record_set(records, filters, sorting,
def apply_filters(records, filters):
"""Filter the specified records, using basic iteration.
"""

def contains_all_filtering(record_value, search_term):
search_set = set(search_term[1])
record_value_set = set(record_value[1])
return record_value_set.intersection(search_set) == search_set

operators = {
COMPARISON.LT: operator.lt,
COMPARISON.MAX: operator.le,
Expand All @@ -336,6 +342,8 @@ def apply_filters(records, filters):
COMPARISON.IN: operator.contains,
COMPARISON.EXCLUDE: lambda x, y: not operator.contains(x, y),
COMPARISON.LIKE: lambda x, y: re.search(y, x, re.IGNORECASE),
COMPARISON.CONTAINS_ALL: contains_all_filtering,
COMPARISON.CONTAINS: lambda record_value, search_term: set(record_value[1]).intersection(set(search_term[1]))
}
for record in records:
matches = True
Expand Down
32 changes: 32 additions & 0 deletions kinto/core/storage/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,38 @@ def test_get_all_can_filter_with_list_of_values(self):
**self.storage_kw)
self.assertEqual(len(records), 2)

def test_get_all_can_filter_on_array_that_contains_all_values(self):
self.create_record({'colors': ["red", "green", "blue"]})
self.create_record({'colors': ["gray", "blue"]})
self.create_record({'colors': ["red", "gray", "blue"]})
self.create_record({'colors': ["purple", "green", "blue"]})

filters = [Filter('colors', ['red'], utils.COMPARISON.CONTAINS_ALL)]
records, _ = self.storage.get_all(filters=filters,
**self.storage_kw)
self.assertEqual(len(records), 2)

filters = [Filter('colors', ['red', 'gray'], utils.COMPARISON.CONTAINS_ALL)]
records, _ = self.storage.get_all(filters=filters,
**self.storage_kw)
self.assertEqual(len(records), 1)

def test_get_all_can_filter_on_array_that_contains_at_least_one_value(self):
self.create_record({'colors': ["red", "green", "blue"]})
self.create_record({'colors': ["gray", "blue"]})
self.create_record({'colors': ["red", "gray", "blue"]})
self.create_record({'colors': ["purple", "green", "blue"]})

filters = [Filter('colors', ['red'], utils.COMPARISON.CONTAINS)]
records, _ = self.storage.get_all(filters=filters,
**self.storage_kw)
self.assertEqual(len(records), 2)

filters = [Filter('colors', ['red', 'gray'], utils.COMPARISON.CONTAINS)]
records, _ = self.storage.get_all(filters=filters,
**self.storage_kw)
self.assertEqual(len(records), 3)

def test_get_all_can_filter_with_numeric_values(self):
self.create_record({'missing': 'code'})
for l in [1, 10, 6, 46]:
Expand Down
2 changes: 2 additions & 0 deletions kinto/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ class COMPARISON(Enum):
EXCLUDE = 'exclude'
LIKE = 'like'
HAS = 'has'
CONTAINS_ALL = 'contains_all'
CONTAINS = 'contains'


def reapply_cors(request, response):
Expand Down

0 comments on commit 26d64ed

Please sign in to comment.