Skip to content

Commit

Permalink
fix: builds filter
Browse files Browse the repository at this point in the history
Before the changes, the treeCommitsHistory and treeDetailsView views were unable to handle more than one filter using the same field (and even if it worked it wouldn't be able to deal with where to put AND or OR). So I created get_grouped_filters to group all values ​​in an array into the same filter object. However, I received some errors in the query when dealing with a filter that only had one value in the array. Therefore, to avoid changing every query to always check whether it has one value or more, I decided to change the code in just one place, defining a string at first and changing it to an array when adding more values

Closes #438
  • Loading branch information
anajalvarenga authored and Francisco2002 committed Oct 31, 2024
1 parent b9cdc83 commit cdf4333
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 19 deletions.
15 changes: 15 additions & 0 deletions backend/kernelCI_app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,18 @@ def validate_comparison_op(self, op):
def get_comparison_op(self, filter, op_type="orm"):
idx = self.comparison_op_type_idx[op_type]
return self.comparison_ops[filter["comparison_op"]][idx]

def get_grouped_filters(self):
grouped_filters = {}

for f in self.filters:
field = f["field"]
value = f['value']
if field not in grouped_filters:
grouped_filters[field] = f
elif type(grouped_filters[field]['value']) is str:
grouped_filters[field]['value'] = [grouped_filters[field]['value'], value]
else:
grouped_filters[field]['value'].append(value)

return grouped_filters
19 changes: 10 additions & 9 deletions backend/kernelCI_app/views/treeCommitsHistory.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ def __init__(self):
self.field_values = dict()

# TODO: unite the filters logic
def _get_filters(self, filter_params):
for f in filter_params.filters:
split_filter = f['field'].split('.')
def __get_filters(self, filter_params):
grouped_filters = filter_params.get_grouped_filters()

for field, filter in grouped_filters.items():
split_filter = field.split('.')

if len(split_filter) == 1:
split_filter.insert(0, 'build')
Expand All @@ -44,14 +46,13 @@ def _get_filters(self, filter_params):
if (field == "hardware"):
continue

value_name = f"{table}{field.capitalize()}{filter_params.get_comparison_op(f)}"

op = filter_params.get_comparison_op(f, "raw")
value_name = f"{table}{field.capitalize()}{filter_params.get_comparison_op(filter)}"

self.field_values[value_name] = f['value']
op = filter_params.get_comparison_op(filter, "raw")
self.field_values[value_name] = filter['value']
clause = f"{self.filters_options[table]['table_alias']}.{field}"

if f['value'] == 'NULL':
if filter['value'] == 'NULL':
clause += " IS NULL"
elif op == "IN":
clause += f" = ANY(%({value_name})s)"
Expand Down Expand Up @@ -145,7 +146,7 @@ def get(self, request, commit_hash):
"git_branch_param": git_branch_param,
}

build_counts_where, boot_counts_where, test_counts_where = self._get_filters(filter_params)
build_counts_where, boot_counts_where, test_counts_where = self.__get_filters(filter_params)

query = f"""
WITH
Expand Down
26 changes: 16 additions & 10 deletions backend/kernelCI_app/views/treeDetailsView.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ def create_summary(self, builds_dict):
"architectures": arch_summ,
}

def __get_filtered_tree_details_query(self, query, filter_params, build_fields, checkout_fields):
grouped_filters = filter_params.get_grouped_filters()

for field, filter in grouped_filters.items():
table = None
if field in build_fields:
table = "builds"
elif field in checkout_fields:
table = "checkouts"
if table:
op = filter_params.get_comparison_op(filter, "orm")
query.where(**{f"{table}.{field}__{op}": filter["value"]})

return query

# TODO, Remove this query builder, use Django ORM or raw SQL
def get(self, request, commit_hash):
git_url_param = request.GET.get("git_url")
Expand Down Expand Up @@ -160,16 +175,7 @@ def get(self, request, commit_hash):
except InvalidComparisonOP as e:
return HttpResponseBadRequest(getErrorResponseBody(str(e)))

for f in filter_params.filters:
field = f["field"]
table = None
if field in build_fields:
table = "builds"
elif field in checkout_fields:
table = "checkouts"
if table:
op = filter_params.get_comparison_op(f, "orm")
query.where(**{f"{table}.{field}__{op}": f["value"]})
query = self.__get_filtered_tree_details_query(query, filter_params, build_fields, checkout_fields)

records = query.select()
builds, summary, issues = self.sanitize_records(records)
Expand Down

0 comments on commit cdf4333

Please sign in to comment.