Merge "and/or query combiner for filter options"

This commit is contained in:
Zuul 2018-04-11 07:18:02 +00:00 committed by Gerrit Code Review
commit bbb1243104
3 changed files with 31 additions and 8 deletions

View File

@ -258,14 +258,15 @@ def _apply_user_filters(query, basic_conds, tag_conds, prop_conds):
if basic_conds:
for basic_condition in basic_conds['and']:
query = query.filter(and_(*basic_condition))
or_queries = []
for basic_condition in basic_conds['or']:
or_queries.append(*basic_condition)
if tag_conds:
for tag_condition in tag_conds:
for tag_condition in tag_conds['and']:
query = query.join(models.ArtifactTag, aliased=True).filter(
and_(*tag_condition))
for tag_condition in tag_conds['or']:
or_queries.append(*tag_condition)
if prop_conds:
for prop_condition in prop_conds['and']:
@ -437,7 +438,10 @@ def _do_query_filters(filters):
"and": [],
"or": []
}
tag_conds = []
tag_conds = {
"and": [],
"or": []
}
prop_conds = {
"and": [],
"or": []
@ -446,10 +450,12 @@ def _do_query_filters(filters):
if field_name == 'tags':
tags = utils.split_filter_value_for_quotes(value)
for tag in tags:
tag_conds.append([models.ArtifactTag.value == tag])
tag_conds[query_combiner].append(
[models.ArtifactTag.value == tag])
elif field_name == 'tags-any':
tags = utils.split_filter_value_for_quotes(value)
tag_conds.append([models.ArtifactTag.value.in_(tags)])
tag_conds[query_combiner].append(
[models.ArtifactTag.value.in_(tags)])
elif field_name in BASE_ARTIFACT_PROPERTIES:
if op == 'in':
if field_name == 'version':

View File

@ -354,12 +354,17 @@ Possible values:
for filter_name, filter_value in filters:
if filter_name in ('tags-any', 'tags'):
if ':' in filter_value:
tag_values = filter_value
combiner = cls.DEFAULT_QUERY_COMBINER
if filter_value.startswith(("and:", "or:")):
combiner = filter_value[:filter_value.index(":")]
tag_values = filter_value[filter_value.index(":") + 1:]
if ':' in tag_values:
msg = _("Tags are filtered without operator")
raise exception.BadRequest(msg)
new_filters.append(
(filter_name, None, None, None, filter_value,
cls.DEFAULT_QUERY_COMBINER))
(filter_name, None, None, None, tag_values,
combiner))
continue
key_name = None

View File

@ -533,6 +533,18 @@ class TestArtifactList(base.BaseTestArtifactAPI):
for i in (0, 3, 5):
self.assertIn(arts[i], res['artifacts'])
filters = [('name', 'in:name4,name1'), ('tags-any', 'and:tag2,tag4')]
res = self.controller.list(self.req, 'sample_artifact', filters)
self.assertEqual(2, len(res['artifacts']))
for i in (3, 0):
self.assertIn(arts[i], res['artifacts'])
filters = [('name', 'or:in:name4,name1'), ('tags-any', 'or:tag4')]
res = self.controller.list(self.req, 'sample_artifact', filters)
self.assertEqual(6, len(res['artifacts']))
for i in (5, 4, 3, 0):
self.assertIn(arts[i], res['artifacts'])
# Filtering by tags with operators leads to BadRequest
for f in ('tags', 'tags-any'):
filters = [(f, 'eq:tag1')]