Skip to content

Commit

Permalink
#145: Move filter-specific functions to FilterOrderHandler
Browse files Browse the repository at this point in the history
- This will help clean up common.icat.helpers and move filter-specific functions to the relevant file
- This commit also adds a function that calls other functions in its class to reduce code duplication
- This is a 'leave the code in a better state than you found it' kind of commit
  • Loading branch information
MRichards99 committed Oct 9, 2020
1 parent 2d2f4f1 commit 8c8a241
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 62 deletions.
69 changes: 69 additions & 0 deletions common/filter_order_handler.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
from common.icat.filters import (
PythonICATLimitFilter,
PythonICATSkipFilter,
PythonICATOrderFilter,
)


class FilterOrderHandler(object):
"""
The FilterOrderHandler takes in filters, sorts them according to the order of
Expand Down Expand Up @@ -32,3 +39,65 @@ def apply_filters(self, query):

for filter in self.filters:
filter.apply_filter(query)

def merge_python_icat_limit_skip_filters(self):
"""
When there are both limit and skip filters in a request, merge them into the
limit filter and remove the skip filter from the instance
"""

if any(
isinstance(icat_filter, PythonICATSkipFilter)
for icat_filter in self.filters
) and any(
isinstance(icat_filter, PythonICATLimitFilter)
for icat_filter in self.filters
):
# Merge skip and limit filter into a single limit filter
for icat_filter in self.filters:
if isinstance(icat_filter, PythonICATSkipFilter):
skip_filter = icat_filter
request_skip_value = icat_filter.skip_value

if isinstance(icat_filter, PythonICATLimitFilter):
limit_filter = icat_filter

if skip_filter and limit_filter:
log.info("Merging skip filter with limit filter")
limit_filter.skip_value = skip_filter.skip_value
log.info("Removing skip filter from list of filters")
self.remove_filter(skip_filter)
log.debug("Filters: %s", self.filters)

def clear_python_icat_order_filters(self):
"""
Checks if any order filters have been added to the request and resets the
variable used to manage which attribute(s) to use for sorting results.
A reset is required because Python ICAT overwrites (as opposed to appending to
it) the query's order list every time one is added to the query.
"""

if any(
isinstance(icat_filter, PythonICATOrderFilter)
for icat_filter in self.filters
):
PythonICATOrderFilter.result_order = []

def manage_icat_filters(self, filters, query):
"""
Utility function to call other functions in this class, used to manage filters
when using the Python ICAT backend. These steps are the same with the different
types of requests that utilise filters, therefore this function helps to reduce
code duplication
:param filters: The list of filters that will be applied to the query
:type filters: List of specific implementations :class:`QueryFilter`
:param query: ICAT query which will fetch the data at a later stage
:type query: :class:`icat.query.Query`
"""

self.add_filters(filters)
self.merge_python_icat_limit_skip_filters()
self.clear_python_icat_order_filters()
self.apply_filters(query)
65 changes: 3 additions & 62 deletions common/icat/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,7 @@
from common.filter_order_handler import FilterOrderHandler
from common.date_handler import DateHandler
from common.constants import Constants
from common.icat.filters import (
PythonICATLimitFilter,
PythonICATWhereFilter,
PythonICATSkipFilter,
PythonICATOrderFilter,
)

from common.icat.filters import PythonICATLimitFilter, PythonICATWhereFilter

log = logging.getLogger()

Expand Down Expand Up @@ -621,10 +615,7 @@ def get_entity_with_filters(client, table_name, filters):
query = icat_query(client, selected_entity_name)

filter_handler = FilterOrderHandler()
filter_handler.add_filters(filters)
merge_limit_skip_filters(filter_handler)
clear_order_filters(filter_handler.filters)
filter_handler.apply_filters(query.query)
filter_handler.manage_icat_filters(filters, query.query)

data = query.execute_query(client, True)

Expand All @@ -634,53 +625,6 @@ def get_entity_with_filters(client, table_name, filters):
return data


def merge_limit_skip_filters(filter_handler):
"""
When there are both limit and skip filters in a request, merge them into the limit
filter and remove the skip filter from `filter_handler`
:param filter_handler: The filter handler to apply the filters
:param filters: The filters to be applied
"""

if any(
isinstance(filter, PythonICATSkipFilter) for filter in filter_handler.filters
) and any(
isinstance(filter, PythonICATLimitFilter) for filter in filter_handler.filters
):
# Merge skip and limit filter into a single limit filter
for filter in filter_handler.filters:
if isinstance(filter, PythonICATSkipFilter):
skip_filter = filter
request_skip_value = filter.skip_value

if isinstance(filter, PythonICATLimitFilter):
limit_filter = filter

if skip_filter and limit_filter:
log.info("Merging skip filter with limit filter")
limit_filter.skip_value = skip_filter.skip_value
log.info("Removing skip filter from list of filters")
filter_handler.remove_filter(skip_filter)
log.debug("Filters: %s", filter_handler.filters)


def clear_order_filters(filters):
"""
Checks if any order filters have been added to the request and resets the variable
used to manage which attribute(s) to use for sorting results.
A reset is required because Python ICAT overwrites (as opposed to appending to it)
the query's order list every time one is added to the query.
:param filters: The list of filters to be applied to the request
:type filters: List of specific implementations :class:`QueryFilter`
"""

if any(isinstance(filter, PythonICATOrderFilter) for filter in filters):
PythonICATOrderFilter.result_order = []


def get_count_with_filters(client, table_name, filters):
"""
Get the number of results of a given entity, based on the filters provided in the
Expand All @@ -705,10 +649,7 @@ def get_count_with_filters(client, table_name, filters):
query = icat_query(client, selected_entity_name, aggregate="COUNT")

filter_handler = FilterOrderHandler()
filter_handler.add_filters(filters)
merge_limit_skip_filters(filter_handler)
clear_order_filters(filter_handler.filters)
filter_handler.apply_filters(query.query)
filter_handler.manage_icat_filters(filters, query.query)

data = query.execute_query(client, True)

Expand Down

0 comments on commit 8c8a241

Please sign in to comment.