Skip to content

Commit

Permalink
Merge pull request #273 from ral-facilities/feature/ilike-operator-#243
Browse files Browse the repository at this point in the history
Add Insensitive Like Operator to WHERE Filter
  • Loading branch information
MRichards99 authored Nov 2, 2021
2 parents 06e28dd + 550de36 commit 822408b
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 22 deletions.
15 changes: 14 additions & 1 deletion datagateway_api/common/icat/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,20 @@ def create_filter(self):
where_filter = self.create_condition(self.field, "!=", self.value)
elif self.operation == "like":
where_filter = self.create_condition(self.field, "like", f"%{self.value}%")
elif self.operation == "ilike":
self.field = f"UPPER({self.field})"
where_filter = self.create_condition(
self.field, "like", f"UPPER('%{self.value}%')",
)
elif self.operation == "nlike":
where_filter = self.create_condition(
self.field, "not like", f"%{self.value}%",
)
elif self.operation == "nilike":
self.field = f"UPPER({self.field})"
where_filter = self.create_condition(
self.field, "not like", f"UPPER('%{self.value}%')",
)
elif self.operation == "lt":
where_filter = self.create_condition(self.field, "<", self.value)
elif self.operation == "lte":
Expand Down Expand Up @@ -101,7 +111,10 @@ def create_condition(attribute_name, operator, value):
# distinct filter is used in a request
jpql_value = (
f"{value}"
if operator == "in" or operator == "!=" or "o." in str(value)
if operator == "in"
or operator == "!="
or str(value).startswith("UPPER")
or "o." in str(value)
else f"'{value}'"
)

Expand Down
6 changes: 3 additions & 3 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Flask-Cors = "3.0.9"
apispec = "3.3.0"
flask-swagger-ui = "3.25.0"
PyYAML = "5.4"
python-icat = "0.19.0"
python-icat = "0.20.0"
suds-community = "^0.8.4"
py-object-pool = "^1.1"
cachetools = "^4.2.1"
Expand Down
4 changes: 2 additions & 2 deletions test/icat/filters/test_order_filter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest

from typing_extensions import OrderedDict

from datagateway_api.common.exceptions import FilterError
from datagateway_api.common.filter_order_handler import FilterOrderHandler
Expand Down Expand Up @@ -81,7 +81,7 @@ def test_filter_applied_to_query(self, icat_query):
filter_handler.add_filter(test_filter)
filter_handler.apply_filters(icat_query)

assert icat_query.order == [("id", "DESC")]
assert icat_query.order == OrderedDict([("id", "%s DESC")])

filter_handler.clear_python_icat_order_filters()

Expand Down
30 changes: 17 additions & 13 deletions test/icat/filters/test_where_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@ class TestICATWhereFilter:
@pytest.mark.parametrize(
"operation, value, expected_condition_value",
[
pytest.param("eq", 5, "= '5'", id="equal"),
pytest.param("ne", 5, "!= 5", id="not equal"),
pytest.param("like", 5, "like '%5%'", id="like"),
pytest.param("nlike", 5, "not like '%5%'", id="not like"),
pytest.param("lt", 5, "< '5'", id="less than"),
pytest.param("lte", 5, "<= '5'", id="less than or equal"),
pytest.param("gt", 5, "> '5'", id="greater than"),
pytest.param("gte", 5, ">= '5'", id="greater than or equal"),
pytest.param("in", [1, 2, 3, 4], "in (1, 2, 3, 4)", id="in a list"),
pytest.param("in", [], "in (NULL)", id="empty list"),
pytest.param("eq", 5, ["%s = '5'"], id="equal"),
pytest.param("ne", 5, ["%s != 5"], id="not equal"),
pytest.param("like", 5, ["%s like '%%5%%'"], id="like"),
pytest.param("ilike", 5, ["UPPER(%s) like UPPER('%%5%%')"], id="ilike"),
pytest.param("nlike", 5, ["%s not like '%%5%%'"], id="not like"),
pytest.param(
"nilike", 5, ["UPPER(%s) not like UPPER('%%5%%')"], id="not ilike",
),
pytest.param("lt", 5, ["%s < '5'"], id="less than"),
pytest.param("lte", 5, ["%s <= '5'"], id="less than or equal"),
pytest.param("gt", 5, ["%s > '5'"], id="greater than"),
pytest.param("gte", 5, ["%s >= '5'"], id="greater than or equal"),
pytest.param("in", [1, 2, 3, 4], ["%s in (1, 2, 3, 4)"], id="in a list"),
pytest.param("in", [], ["%s in (NULL)"], id="empty list"),
],
)
def test_valid_operations(
Expand All @@ -44,13 +48,13 @@ def test_valid_internal_icat_value(self, icat_query):
test_filter = PythonICATWhereFilter("startDate", "o.endDate", "lt")
test_filter.apply_filter(icat_query)

assert icat_query.conditions == {"startDate": "< o.endDate"}
assert icat_query.conditions == {"startDate": ["%s < o.endDate"]}

def test_valid_field(self, icat_query):
test_filter = PythonICATWhereFilter("title", "Investigation Title", "eq")
test_filter.apply_filter(icat_query)

assert icat_query.conditions == {"title": "= 'Investigation Title'"}
assert icat_query.conditions == {"title": ["%s = 'Investigation Title'"]}

def test_invalid_field(self, icat_query):
test_filter = PythonICATWhereFilter("random_field", "my_value", "eq")
Expand All @@ -66,4 +70,4 @@ def test_multiple_conditions_per_field(self, icat_query):
filter_handler.add_filters([lt_filter, gt_filter])
filter_handler.apply_filters(icat_query)

assert icat_query.conditions == {"id": ["< '10'", "> '5'"]}
assert icat_query.conditions == {"id": ["%s < '10'", "%s > '5'"]}
5 changes: 4 additions & 1 deletion test/icat/test_filter_order_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,7 @@ def test_apply_filters(self, icat_query):
test_handler.add_filters([where_filter, limit_filter])
test_handler.apply_filters(icat_query)

assert icat_query.conditions == {"id": "= '2'"} and icat_query.limit == (0, 10)
assert icat_query.conditions == {"id": ["%s = '2'"]} and icat_query.limit == (
0,
10,
)
2 changes: 1 addition & 1 deletion test/icat/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class TestICATQuery:
{"fullName": "like Bob"},
None,
None,
{"fullName": "like Bob"},
{"fullName": ["%s like Bob"]},
None,
set(),
id="Query with condition",
Expand Down

0 comments on commit 822408b

Please sign in to comment.