From 51924f8bf0efac50a2b93f3f2978f54608512db8 Mon Sep 17 00:00:00 2001 From: Matthew Richards Date: Tue, 18 Aug 2020 16:34:21 +0000 Subject: [PATCH] #140: Move create_condition() to PythonICATWhereFilter - This is to remove a circular dependency that I found while implementing an order filter - Also added a couple of __init__.py files which didn't previously exist --- common/database/__init__.py | 0 common/icat/__init__.py | 0 common/icat/filters.py | 41 +++++++++++++++++++++++++++++-------- common/icat/helpers.py | 26 ++--------------------- 4 files changed, 35 insertions(+), 32 deletions(-) create mode 100644 common/database/__init__.py create mode 100644 common/icat/__init__.py diff --git a/common/database/__init__.py b/common/database/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/common/icat/__init__.py b/common/icat/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/common/icat/filters.py b/common/icat/filters.py index f92bcd72..cb2e7689 100644 --- a/common/icat/filters.py +++ b/common/icat/filters.py @@ -9,7 +9,6 @@ IncludeFilter, ) from common.exceptions import FilterError -from common.icat.helpers import create_condition log = logging.getLogger() @@ -19,30 +18,56 @@ def __init__(self, field, value, operation): super().__init__(field, value, operation) def apply_filter(self, query): + log.info("Creating condition for ICAT where filter") if self.operation == "eq": - where_filter = create_condition(self.field, "=", self.value) + where_filter = self.create_condition(self.field, "=", self.value) elif self.operation == "like": - where_filter = create_condition(self.field, "like", self.value) + where_filter = self.create_condition(self.field, "like", self.value) elif self.operation == "lt": - where_filter = create_condition(self.field, "<", self.value) + where_filter = self.create_condition(self.field, "<", self.value) elif self.operation == "lte": - where_filter = create_condition(self.field, "<=", self.value) + where_filter = self.create_condition(self.field, "<=", self.value) elif self.operation == "gt": - where_filter = create_condition(self.field, ">", self.value) + where_filter = self.create_condition(self.field, ">", self.value) elif self.operation == "gte": - where_filter = create_condition(self.field, ">=", self.value) + where_filter = self.create_condition(self.field, ">=", self.value) elif self.operation == "in": - where_filter = create_condition(self.field, "in", tuple(self.value)) + where_filter = self.create_condition(self.field, "in", tuple(self.value)) else: raise FilterError(f"Bad operation given to where filter: {self.operation}") + log.debug("ICAT Where Filter: %s", where_filter) try: + log.info("Adding ICAT where filter to query") query.addConditions(where_filter) except ValueError: raise FilterError( "Something went wrong when adding WHERE filter to ICAT query" ) + @staticmethod + 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 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 = {} + # 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 + class PythonICATDistinctFieldFilter(DistinctFieldFilter): def __init__(self, fields): diff --git a/common/icat/helpers.py b/common/icat/helpers.py index 89c6a7f8..a3859a23 100644 --- a/common/icat/helpers.py +++ b/common/icat/helpers.py @@ -12,6 +12,7 @@ ) from common.filter_order_handler import FilterOrderHandler from common.constants import Constants +from common.icat.filters import PythonICATLimitFilter, PythonICATWhereFilter log = logging.getLogger() @@ -206,29 +207,6 @@ def get_python_icat_entity_name(client, database_table_name): return python_icat_entity_name -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 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 = {} - # 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 - - def str_to_datetime_object(icat_attribute, data): """ Where data is stored as dates in ICAT (which this function determines), convert @@ -321,7 +299,7 @@ def get_entity_by_id(client, table_name, id_, return_json_formattable_data): """ # Set query condition for the selected ID - id_condition = create_condition("id", "=", id_) + id_condition = PythonICATWhereFilter.create_condition("id", "=", id_) selected_entity_name = get_python_icat_entity_name(client, table_name)