Skip to content

Commit

Permalink
Merge branch 'feature/icat-limit-skip-filters-#139' into feature/icat…
Browse files Browse the repository at this point in the history
…-distinct-filter-#141
  • Loading branch information
MRichards99 committed Aug 27, 2020
2 parents 2aea37c + 61b63a2 commit 32e6927
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 7 deletions.
1 change: 1 addition & 0 deletions common/filter_order_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def sort_filters(self):
def apply_filters(self, query):
"""
Given a query apply the filters the handler has in the correct order.
:param query: The query to have filters applied to
"""
self.sort_filters()
Expand Down
16 changes: 9 additions & 7 deletions common/icat/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,22 +99,24 @@ def apply_filter(self, query):


class PythonICATOrderFilter(OrderFilter):
# Used to append the order tuples across all filters in a single request
result_order = []

def __init__(self, field, direction):
# Python ICAT doesn't automatically uppercase the direction, errors otherwise
super().__init__(field, direction.upper())

def apply_filter(self, query):
result_order = [(self.field, self.direction)]
log.debug("Result Order: %s", result_order)
PythonICATOrderFilter.result_order.append((self.field, self.direction))
log.debug("Result Order: %s", PythonICATOrderFilter.result_order)

try:
log.info("Adding order filter")
query.setOrder(PythonICATOrderFilter.result_order)
except ValueError:
raise FilterError(
"Order Filter Error: Either an invalid attribute(s) or attribute(s)"
" contains 1-many relationship"
)
except ValueError as e:
# Typically either invalid attribute(s) or attribute(s) contains 1-many
# relationship
raise FilterError(e)


class PythonICATSkipFilter(SkipFilter):
Expand Down
31 changes: 31 additions & 0 deletions common/icat/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
PythonICATLimitFilter,
PythonICATWhereFilter,
PythonICATSkipFilter,
PythonICATOrderFilter,
)


Expand Down Expand Up @@ -411,12 +412,26 @@ def update_entity_by_id(client, table_name, id_, new_data):


def get_entity_with_filters(client, table_name, filters):
"""
Gets all the records of a given entity, based on the filters provided in the request
:param client: ICAT client containing an authenticated user
:type client: :class:`icat.client.Client`
:param table_name: Table name to extract which entity to use
:type table_name: :class:`str`
:param filters: The list of filters to be applied to the request
:type filters: List of specific implementations :class:`QueryFilter`
:return: The list of records of the given entity, using the filters to restrict the
result of the query
"""

selected_entity_name = get_python_icat_entity_name(client, table_name)
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)

data = query.execute_query(client, True)
Expand Down Expand Up @@ -456,3 +471,19 @@ def merge_limit_skip_filters(filter_handler):
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 = []

0 comments on commit 32e6927

Please sign in to comment.