Commit 9841da3a authored by Jérome Perrin's avatar Jérome Perrin

Catalog: raise error when provided unknown query parameters

This behaviour can be disabled:
 - for a given query, by passing ignore_unknown_query_parameter=True. This can
   be helpful if you pass user parameters to the catalog, like listbox does.
 - globally, by setting sql_catalog_raise_error_on_unknown_query_parameter
   property on catalog. This can be helpful if you just want to hide errors
   from users without having to fix the code.
parent 90fda2d3
......@@ -235,6 +235,12 @@ class Selection(Acquisition.Implicit, Traversable, Persistent):
kw['selection_domain'] = self.domain
if self.report is not None:
kw['selection_report'] = self.report
# As we are passing user provided values to the catalog, pass this
# special argument to tell the catalog not to raise on unknown
# parameters.
kw['ignore_unknown_query_parameter'] = True
if callable(method):
result = method(**kw)
else:
......
......@@ -584,7 +584,13 @@ class Catalog(Folder,
'type': 'boolean',
'default' : True,
'mode': 'w' },
{ 'id': 'sql_catalog_raise_error_on_unknown_query_parameter',
'title': 'Raise error on unknown query parameter',
'description': 'Boolean used to tell if we raise error when search '
'is provided unknown values',
'type': 'boolean',
'default' : True,
'mode': 'w' },
)
sql_catalog_produce_reserved = ''
......@@ -626,6 +632,7 @@ class Catalog(Folder,
sql_catalog_security_uid_columns = (' | security_uid',)
sql_catalog_table_vote_scripts = ()
sql_catalog_raise_error_on_uid_check = True
sql_catalog_raise_error_on_unknown_query_parameter = True
# These are ZODB variables, so shared by multiple Zope instances.
# This is set to the last logical time when clearReserved is called.
......@@ -2205,7 +2212,8 @@ class Catalog(Folder,
return self._parseSearchText(self.getSearchKey(
column, search_key=search_key), search_text, is_valid=is_valid)
def buildQuery(self, kw, ignore_empty_string=True, operator='and'):
def buildQuery(self, kw, ignore_empty_string=True,
ignore_unknown_query_parameter=False, operator='and'):
query_list = []
append = query_list.append
# unknown_column_dict: contains all (key, value) pairs which could not be
......@@ -2288,7 +2296,11 @@ class Catalog(Folder,
if len(empty_value_dict):
LOG('SQLCatalog', WARNING, 'Discarding columns with empty values: %r' % (empty_value_dict, ))
if len(unknown_column_dict):
LOG('SQLCatalog', WARNING, 'Unknown columns %r, skipped.' % (unknown_column_dict.keys(), ))
if self.sql_catalog_raise_error_on_unknown_query_parameter:
if not ignore_unknown_query_parameter:
raise ValueError("Unknown catalog columns: %s" % unknown_column_dict.keys(),)
else:
LOG('SQLCatalog', WARNING, 'Unknown columns %r, skipped.' % (unknown_column_dict.keys(), ))
return ComplexQuery(query_list, logical_operator=operator,
unknown_column_dict=unknown_column_dict)
......@@ -2336,6 +2348,7 @@ class Catalog(Folder,
return order_by_list
def buildEntireQuery(self, kw, query_table='catalog', ignore_empty_string=1,
ignore_unknown_query_parameter=False,
limit=None, extra_column_list=()):
group_by_list = kw.pop('group_by_list', kw.pop('group_by', kw.pop('group_by_expression', ())))
if isinstance(group_by_list, basestring):
......@@ -2394,7 +2407,8 @@ class Catalog(Folder,
# new API.
order_by_override_list = kw.pop('select_expression_key', ())
return EntireQuery(
query=self.buildQuery(kw, ignore_empty_string=ignore_empty_string),
query=self.buildQuery(kw, ignore_empty_string=ignore_empty_string,
ignore_unknown_query_parameter=ignore_unknown_query_parameter),
order_by_list=order_by_list,
order_by_override_list=order_by_override_list,
group_by_list=group_by_list,
......@@ -2407,11 +2421,15 @@ class Catalog(Folder,
from_expression=from_expression)
def buildSQLQuery(self, query_table='catalog', REQUEST=None,
ignore_empty_string=1, only_group_columns=False,
ignore_empty_string=1,
ignore_unknown_query_parameter=False,
only_group_columns=False,
limit=None, extra_column_list=(),
**kw):
query = self.buildEntireQuery(kw, query_table=query_table,
ignore_empty_string=ignore_empty_string, limit=limit,
ignore_empty_string=ignore_empty_string,
ignore_unknown_query_parameter=ignore_unknown_query_parameter,
limit=limit,
extra_column_list=extra_column_list)
result = query.asSQLExpression(self, only_group_columns).asSQLExpressionDict()
return result
......
......@@ -791,6 +791,11 @@ class TestSQLCatalog(ERP5TypeTestCase):
self._searchTextInDictQuery('date')
self._searchTextInDictQuery('related_date')
def test_raiseOnUnknownParameter(self):
self.assertRaises(ValueError, self._catalog._queryResults, foobar=1)
self._catalog._queryResults(ignore_unknown_query_parameter=True, foobar=1)
##return catalog(title=Query(title='a', operator='not'))
#return catalog(title={'query': 'a', 'operator': 'not'})
#return catalog(title={'query': ['a', 'b'], 'operator': 'not'})
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment