Skip to content

Commit

Permalink
#142: Implement like and in expressions for WHERE filter
Browse files Browse the repository at this point in the history
  • Loading branch information
MRichards99 committed Aug 11, 2020
1 parent 9d2b4b5 commit 95e8c37
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 23 deletions.
4 changes: 2 additions & 2 deletions common/database/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from sqlalchemy import asc, desc
from sqlalchemy.orm import aliased

from common.exceptions import AuthenticationError, MissingRecordError, BadFilterError, BadRequestError, MultipleIncludeError
from common.exceptions import ApiError, AuthenticationError, MissingRecordError, BadFilterError, \
BadRequestError, MultipleIncludeError
from common.models import db_models
from common.models.db_models import INVESTIGATIONUSER, INVESTIGATION, INSTRUMENT, FACILITYCYCLE, \
INVESTIGATIONINSTRUMENT, FACILITY, SESSION
Expand All @@ -24,7 +25,6 @@
PythonICATOrderFilter as OrderFilter, PythonICATSkipFilter as SkipFilter, PythonICATLimitFilter as LimitFilter, \
PythonICATIncludeFilter as IncludeFilter
else:
# TODO - Check this works
raise ApiError("Cannot select which implementation of filters to import, check the config file has a valid backend type")

log = logging.getLogger()
Expand Down
21 changes: 7 additions & 14 deletions common/icat/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,19 @@ def __init__(self, field, value, operation):
super().__init__(field, value, operation)

def apply_filter(self, query):
# Convert the properties into stuff that ICAT will accept
# Check self.field actually exists within the entity
#



if self.operation == "eq":
where_filter = create_condition(self.field, '=', [self.value])
where_filter = create_condition(self.field, '=', self.value)
elif self.operation == "like":
pass
where_filter = create_condition(self.field, 'like', self.value)
elif self.operation == "lte":
where_filter = create_condition(self.field, '<=', [self.value])
where_filter = create_condition(self.field, '<=', self.value)
elif self.operation == "gte":
where_filter = create_condition(self.field, '>=', [self.value])
where_filter = create_condition(self.field, '>=', self.value)
elif self.operation == "in":
log.debug(f"Field: {self.field}, Type: {type(self.field)}, Value: {self.value}, Type: {type(self.value)}")
where_filter = create_condition(self.field, '=', [self.value])
log.debug(f"IN Filter: {where_filter}")
where_filter = create_condition(self.field, 'in', tuple(self.value))
else:
raise BadFilterError(
f" Bad operation given to where filter. operation: {self.operation}")
raise BadFilterError(f"Bad operation given to where filter: {self.operation}")

try:
query.addConditions(where_filter)
Expand Down
12 changes: 6 additions & 6 deletions common/icat/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,23 +173,23 @@ def get_python_icat_entity_name(client, database_table_name):
return python_icat_entity_name


def create_condition(attribute_name, operator, values):
def create_condition(attribute_name, operator, value):
"""
Construct and return a Python dictionary containing conditions to be used in a Query object
:param attribute_name: Attribute name to search
:type attribute_name: :class:`str`
:param operator: Operator to use when filtering the data
:type operator: :class:`str`
:param values: What ICAT will use to filter the data
:type values: List of :class:`str`
:param value: What ICAT will use to filter the data
:type value: :class:`str` or :class:`tuple` (when using an IN expression)
:return: Condition (of type :class:`dict`) ready to be added to a Python ICAT Query object
"""

conditions = {}
for value in values:
log.debug(f"Value: {value}")
conditions[attribute_name] = f"{operator} '{value}'"
# Removing quote marks when doing conditions with IN expressions
jpql_value = f"{value}" if isinstance(value, tuple) else f"'{value}'"
conditions[attribute_name] = f"{operator} {jpql_value}"

return conditions

Expand Down
2 changes: 1 addition & 1 deletion test/test_database_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from common.database.helpers import QueryFilterFactory
from common.config import config
from common.exceptions import ApiError

backend_type = config.get_backend_type()
if backend_type == "db":
Expand All @@ -14,7 +15,6 @@
PythonICATOrderFilter as OrderFilter, PythonICATSkipFilter as SkipFilter, PythonICATLimitFilter as LimitFilter, \
PythonICATIncludeFilter as IncludeFilter
else:
# TODO - Check this works
raise ApiError("Cannot select which implementation of filters to import, check the config file has a valid backend type")


Expand Down

0 comments on commit 95e8c37

Please sign in to comment.