Commit 322dbb54 authored by Vincent Pelletier's avatar Vincent Pelletier

Add support for ScriptableKeys in SearchText expressions.

This requires them to be both accepted as columns (see change in
isValidColumn) and usable in an abstract syntax tree (see changes in
buildQueryFromAbstractSyntaxTreeNode), requiring a ScriptableKey-to-
SearchKey wrapper (see SearchKeyWrapperForScriptableKey).

Add a test.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@36990 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent dfcae221
...@@ -1841,11 +1841,14 @@ class Catalog(Folder, ...@@ -1841,11 +1841,14 @@ class Catalog(Folder,
""" """
Tells wether given name is or not an existing column. Tells wether given name is or not an existing column.
Warning: This includes "virtual" columns, such as related keys. Warning: This includes "virtual" columns, such as related keys and
scriptable keys.
""" """
result = column_id in self.getColumnMap() result = self.getScriptableKeyScript(column_id) is not None
if not result: if not result:
result = self.getRelatedKeyDefinition(column_id) is not None result = column_id in self.getColumnMap()
if not result:
result = self.getRelatedKeyDefinition(column_id) is not None
return result return result
@profiler_decorator @profiler_decorator
...@@ -2010,7 +2013,12 @@ class Catalog(Folder, ...@@ -2010,7 +2013,12 @@ class Catalog(Folder,
Expected node API is described in interfaces/abstract_syntax_node.py . Expected node API is described in interfaces/abstract_syntax_node.py .
""" """
search_key, related_key_definition = self.getColumnSearchKey(key) script = self.getScriptableKeyScript(key)
if script is None:
search_key, related_key_definition = self.getColumnSearchKey(key)
else:
search_key = SearchKeyWrapperForScriptableKey(key, script)
related_key_definition = None
if search_key is None: if search_key is None:
# Unknown, skip loudly # Unknown, skip loudly
LOG('SQLCatalog', WARNING, 'Unknown column %r, skipped.' % (key, )) LOG('SQLCatalog', WARNING, 'Unknown column %r, skipped.' % (key, ))
...@@ -2605,6 +2613,33 @@ def getSearchKeyInstance(search_key_class_name, column): ...@@ -2605,6 +2613,33 @@ def getSearchKeyInstance(search_key_class_name, column):
result = instance_dict[column] = search_key_class(column) result = instance_dict[column] = search_key_class(column)
return result return result
class SearchKeyWrapperForScriptableKey(SearchKey.SearchKey.SearchKey):
"""
This SearchKey is a simple wrapper around a ScriptableKey, so such script
can be used in place of a regular SearchKey.
"""
default_comparison_operator = None
get_operator_from_value = False
def __init__(self, column, script):
self.script = script
super(SearchKeyWrapperForScriptableKey, self).__init__(column)
def buildQuery(self, search_value, group=None, logical_operator=None,
comparison_operator=None):
# XXX: It would be better to extend ScriptableKey API to support other
# parameters.
if group is not None:
raise ValueError, 'ScriptableKey cannot be used inside a group ' \
'(%r given).' % (group, )
if logical_operator is not None:
raise ValueError, 'ScriptableKey ignores logical operators ' \
'(%r given).' % (logical_operator, )
if comparison_operator != '':
raise ValueError, 'ScriptableKey ignores comparison operators ' \
'(%r given).' % (comparison_operator, )
return self.script(search_value)
from Operator import operator_dict from Operator import operator_dict
def getComparisonOperatorInstance(operator): def getComparisonOperatorInstance(operator):
return operator_dict[operator] return operator_dict[operator]
......
...@@ -454,6 +454,8 @@ class TestSQLCatalog(unittest.TestCase): ...@@ -454,6 +454,8 @@ class TestSQLCatalog(unittest.TestCase):
def test_007_testScriptableKey(self): def test_007_testScriptableKey(self):
self.catalog(ReferenceQuery(ReferenceQuery(operator='=', keyword='%a%'), operator='and'), self.catalog(ReferenceQuery(ReferenceQuery(operator='=', keyword='%a%'), operator='and'),
{'scriptable_keyword': '%a%'}) {'scriptable_keyword': '%a%'})
self.catalog(ReferenceQuery(ReferenceQuery(operator='=', keyword='%a%'), operator='and'),
{'default': 'scriptable_keyword:%a%'})
def test_008_testRawKey(self): def test_008_testRawKey(self):
self.catalog(ReferenceQuery(ReferenceQuery(operator='=', default='%a%'), operator='and'), self.catalog(ReferenceQuery(ReferenceQuery(operator='=', default='%a%'), operator='and'),
......
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