Merge "Add dict and list filters"
This commit is contained in:
commit
32ffa684bc
|
@ -435,13 +435,14 @@ def _do_query_filters(filters):
|
||||||
conds = [models.ArtifactProperty.name == field_name]
|
conds = [models.ArtifactProperty.name == field_name]
|
||||||
if key_name is not None:
|
if key_name is not None:
|
||||||
conds.extend([models.ArtifactProperty.key_name == key_name])
|
conds.extend([models.ArtifactProperty.key_name == key_name])
|
||||||
if op != 'in':
|
if value is not None:
|
||||||
fn = op_mappings[op]
|
if op != 'in':
|
||||||
conds.extend([fn(getattr(models.ArtifactProperty,
|
fn = op_mappings[op]
|
||||||
field_type + '_value'), value)])
|
conds.extend([fn(getattr(models.ArtifactProperty,
|
||||||
else:
|
field_type + '_value'), value)])
|
||||||
conds.extend([getattr(models.ArtifactProperty,
|
else:
|
||||||
field_type + '_value').in_(value)])
|
conds.extend([getattr(models.ArtifactProperty,
|
||||||
|
field_type + '_value').in_(value)])
|
||||||
|
|
||||||
prop_conds.append(conds)
|
prop_conds.append(conds)
|
||||||
|
|
||||||
|
|
|
@ -531,7 +531,6 @@ class BaseArtifact(base.VersionedObject):
|
||||||
# (field_name, key_name, op, field_type, value)
|
# (field_name, key_name, op, field_type, value)
|
||||||
new_filters = []
|
new_filters = []
|
||||||
for filter_name, filter_value in filters:
|
for filter_name, filter_value in filters:
|
||||||
key_name = None
|
|
||||||
if filter_name in ('tags-any', 'tags'):
|
if filter_name in ('tags-any', 'tags'):
|
||||||
if ':' in filter_value:
|
if ':' in filter_value:
|
||||||
msg = _("Tags are filtered without operator")
|
msg = _("Tags are filtered without operator")
|
||||||
|
@ -539,28 +538,37 @@ class BaseArtifact(base.VersionedObject):
|
||||||
new_filters.append(
|
new_filters.append(
|
||||||
(filter_name, None, None, None, filter_value))
|
(filter_name, None, None, None, filter_value))
|
||||||
continue
|
continue
|
||||||
elif '.' in filter_name:
|
|
||||||
filter_name, key_name = filter_name.split('.', 1)
|
|
||||||
cls._validate_filter_name(filter_name)
|
|
||||||
op, val = utils.split_filter_op(filter_value)
|
|
||||||
cls._validate_filter_ops(filter_name, op)
|
|
||||||
field_type = cls.fields.get(filter_name).element_type
|
|
||||||
else:
|
|
||||||
cls._validate_filter_name(filter_name)
|
|
||||||
op, val = utils.split_filter_op(filter_value)
|
|
||||||
cls._validate_filter_ops(filter_name, op)
|
|
||||||
field_type = cls.fields.get(filter_name)
|
|
||||||
|
|
||||||
|
key_name = None
|
||||||
|
if '.' in filter_name:
|
||||||
|
filter_name, key_name = filter_name.split('.', 1)
|
||||||
|
if not isinstance(cls.fields.get(filter_name),
|
||||||
|
glare_fields.Dict):
|
||||||
|
msg = _("Field %s is not Dict") % filter_name
|
||||||
|
raise exception.BadRequest(msg)
|
||||||
|
|
||||||
|
cls._validate_filter_name(filter_name)
|
||||||
|
field_type = cls.fields.get(filter_name)
|
||||||
|
|
||||||
|
if isinstance(field_type, glare_fields.List) or isinstance(
|
||||||
|
field_type, glare_fields.Dict) and key_name is not None:
|
||||||
|
field_type = field_type.element_type
|
||||||
try:
|
try:
|
||||||
if op == 'in':
|
if isinstance(field_type, glare_fields.Dict):
|
||||||
value = [field_type.coerce(cls(), filter_name, value)
|
new_filters.append((
|
||||||
for value in
|
filter_name, filter_value, None, None, None))
|
||||||
utils.split_filter_value_for_quotes(val)]
|
|
||||||
else:
|
else:
|
||||||
value = field_type.coerce(cls(), filter_name, val)
|
op, val = utils.split_filter_op(filter_value)
|
||||||
new_filters.append(
|
cls._validate_filter_ops(filter_name, op)
|
||||||
(filter_name, key_name, op,
|
if op == 'in':
|
||||||
cls._get_field_type(field_type), value))
|
value = [field_type.coerce(cls(), filter_name, value)
|
||||||
|
for value in
|
||||||
|
utils.split_filter_value_for_quotes(val)]
|
||||||
|
else:
|
||||||
|
value = field_type.coerce(cls(), filter_name, val)
|
||||||
|
new_filters.append(
|
||||||
|
(filter_name, key_name, op,
|
||||||
|
cls._get_field_type(field_type), value))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
msg = _("Invalid filter value: %s") % str(val)
|
msg = _("Invalid filter value: %s") % str(val)
|
||||||
raise exception.BadRequest(msg)
|
raise exception.BadRequest(msg)
|
||||||
|
|
|
@ -425,6 +425,58 @@ class TestList(TestArtifact):
|
||||||
result = sort_results(self.get(url=url)['sample_artifact'])
|
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||||
self.assertEqual(art_list[5:], result)
|
self.assertEqual(art_list[5:], result)
|
||||||
|
|
||||||
|
def test_artifact_list_dict_filters(self):
|
||||||
|
lists_of_str = [
|
||||||
|
['aaa', 'bbb', 'ccc'],
|
||||||
|
['aaa', 'bbb'],
|
||||||
|
['aaa', 'ddd'],
|
||||||
|
['bbb'],
|
||||||
|
['ccc']
|
||||||
|
]
|
||||||
|
dicts_of_str = [
|
||||||
|
{'aaa': 'z', 'bbb': 'z', 'ccc': 'z'},
|
||||||
|
{'aaa': 'z', 'bbb': 'z'},
|
||||||
|
{'aaa': 'z', 'ddd': 'z'},
|
||||||
|
{'bbb': 'z'},
|
||||||
|
{'ccc': 'z'}
|
||||||
|
]
|
||||||
|
art_list = [self.create_artifact({'name': 'name%s' % i,
|
||||||
|
'version': '1.0',
|
||||||
|
'tags': ['tag%s' % i],
|
||||||
|
'int1': 1024,
|
||||||
|
'float1': 123.456,
|
||||||
|
'str1': 'bugaga',
|
||||||
|
'bool1': True,
|
||||||
|
'list_of_str': lists_of_str[i],
|
||||||
|
'dict_of_str': dicts_of_str[i]})
|
||||||
|
for i in range(5)]
|
||||||
|
|
||||||
|
# test list filters
|
||||||
|
url = '/sample_artifact?list_of_str=aaa&sort=name'
|
||||||
|
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||||
|
self.assertEqual(art_list[:3], result)
|
||||||
|
|
||||||
|
url = '/sample_artifact?list_of_str=ccc&sort=name'
|
||||||
|
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||||
|
self.assertEqual([art_list[0], art_list[4]], result)
|
||||||
|
|
||||||
|
url = '/sample_artifact?list_of_str=eee&sort=name'
|
||||||
|
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||||
|
self.assertEqual([], result)
|
||||||
|
|
||||||
|
# test dict filters
|
||||||
|
url = '/sample_artifact?dict_of_str=aaa&sort=name'
|
||||||
|
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||||
|
self.assertEqual(art_list[:3], result)
|
||||||
|
|
||||||
|
url = '/sample_artifact?dict_of_str=ccc&sort=name'
|
||||||
|
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||||
|
self.assertEqual([art_list[0], art_list[4]], result)
|
||||||
|
|
||||||
|
url = '/sample_artifact?dict_of_str=eee&sort=name'
|
||||||
|
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||||
|
self.assertEqual([], result)
|
||||||
|
|
||||||
def test_list_dict_prop_filters(self):
|
def test_list_dict_prop_filters(self):
|
||||||
# Create artifact
|
# Create artifact
|
||||||
art_list = [self.create_artifact({'name': 'name0',
|
art_list = [self.create_artifact({'name': 'name0',
|
||||||
|
@ -485,11 +537,14 @@ class TestList(TestArtifact):
|
||||||
self.assertEqual([], result)
|
self.assertEqual([], result)
|
||||||
|
|
||||||
url = '/sample_artifact?dict_of_str'
|
url = '/sample_artifact?dict_of_str'
|
||||||
self.get(url=url, status=400)
|
self.assertEqual([], result)
|
||||||
|
|
||||||
url = '/sample_artifact?dict_of_str.pr3=blabla:val3'
|
url = '/sample_artifact?dict_of_str.pr3=blabla:val3'
|
||||||
self.get(url=url, status=400)
|
self.get(url=url, status=400)
|
||||||
|
|
||||||
|
url = '/sample_artifact?list_of_str.pr3=blabla:val3'
|
||||||
|
self.get(url=url, status=400)
|
||||||
|
|
||||||
url = '/sample_artifact?dict_of_str.bla=val1'
|
url = '/sample_artifact?dict_of_str.bla=val1'
|
||||||
result = sort_results(self.get(url=url)['sample_artifact'])
|
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||||
self.assertEqual([], result)
|
self.assertEqual([], result)
|
||||||
|
|
Loading…
Reference in New Issue