Commit 14a37433 authored by Vincent Pelletier's avatar Vincent Pelletier

Instead of using a static set, use a callback mechanism. This fixes virtual column detection.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@25944 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 6d50f2b4
...@@ -109,7 +109,7 @@ class ISearchKey(Interface): ...@@ -109,7 +109,7 @@ class ISearchKey(Interface):
If given, expresses the comparison between column and value. If given, expresses the comparison between column and value.
""" """
def parseSearchText(value, column_id_set): def parseSearchText(value, is_column):
""" """
Parse given value to generate an Abstract Syntax Tree representing its Parse given value to generate an Abstract Syntax Tree representing its
logical structure, or None if there is no obvious structure in given logical structure, or None if there is no obvious structure in given
...@@ -118,9 +118,12 @@ class ISearchKey(Interface): ...@@ -118,9 +118,12 @@ class ISearchKey(Interface):
value (string) value (string)
The string to parse. The string to parse.
column_id_set (set) is_column (function taking one parameter)
A list of valid column names. This is used when deciding wether value This function will be called with a single parameter, being a column
should really be parsed or remain a bare string. name candidate.
It must return a boolean:
True: value is a valid column name
False: value is not a valid column name
Returns: (None, AbstratSyntaxNode) Returns: (None, AbstratSyntaxNode)
AbstratSyntaxNode complies with the IAbstractSyntaxNode interface. AbstratSyntaxNode complies with the IAbstractSyntaxNode interface.
......
...@@ -1793,6 +1793,18 @@ class Catalog(Folder, ...@@ -1793,6 +1793,18 @@ class Catalog(Folder,
return CachingMethod(_getTableIndex, id='SQLCatalog.getTableIndex', \ return CachingMethod(_getTableIndex, id='SQLCatalog.getTableIndex', \
cache_factory='erp5_content_long')(table=table).copy() cache_factory='erp5_content_long')(table=table).copy()
@profiler_decorator
def isValidColumn(self, column_id):
"""
Tells wether given name is or not an existing column.
Warning: This includes "virtual" columns, such as related keys.
"""
result = column_id in self.getColumnMap()
if not result:
result = self.getRelatedKeyDefinition(column_id) is not None
return result
@profiler_decorator @profiler_decorator
def getRelatedKeyDefinition(self, key): def getRelatedKeyDefinition(self, key):
""" """
...@@ -1981,9 +1993,6 @@ class Catalog(Folder, ...@@ -1981,9 +1993,6 @@ class Catalog(Folder,
# column names with empty values. This is for backward compatibility. See # column names with empty values. This is for backward compatibility. See
# comment about empty values. # comment about empty values.
implicit_table_list = [] implicit_table_list = []
# It's not a problem to use a dict instead of a set here, and saves a
# cast.
column_id_set = self.getColumnMap()
for key, value in kw.iteritems(): for key, value in kw.iteritems():
result = None result = None
if isinstance(value, dict_type_list): if isinstance(value, dict_type_list):
...@@ -2017,7 +2026,7 @@ class Catalog(Folder, ...@@ -2017,7 +2026,7 @@ class Catalog(Folder,
# String: parse using key's default search key. # String: parse using key's default search key.
search_key = self.getColumnDefaultSearchKey(key) search_key = self.getColumnDefaultSearchKey(key)
if search_key is not None: if search_key is not None:
abstract_syntax_tree = search_key.parseSearchText(value, column_id_set) abstract_syntax_tree = search_key.parseSearchText(value, self.isValidColumn)
if abstract_syntax_tree is None: if abstract_syntax_tree is None:
# Parsing failed, create a query from the bare string. # Parsing failed, create a query from the bare string.
result = self.buildSingleQuery(key, value) result = self.buildSingleQuery(key, value)
......
...@@ -42,8 +42,8 @@ class DefaultKey(SearchKey): ...@@ -42,8 +42,8 @@ class DefaultKey(SearchKey):
default_comparison_operator = '=' default_comparison_operator = '='
get_operator_from_value = True get_operator_from_value = True
def parseSearchText(self, value, column_id_set): def parseSearchText(self, value, is_column):
return parse(value, column_id_set) return parse(value, is_column)
def _guessComparisonOperator(self, value): def _guessComparisonOperator(self, value):
if isinstance(value, basestring) and '%' in value: if isinstance(value, basestring) and '%' in value:
......
...@@ -40,8 +40,8 @@ class FullTextKey(SearchKey): ...@@ -40,8 +40,8 @@ class FullTextKey(SearchKey):
default_comparison_operator = 'match' default_comparison_operator = 'match'
get_operator_from_value = False get_operator_from_value = False
def parseSearchText(self, value, column_id_set): def parseSearchText(self, value, is_column):
return parse(value, column_id_set) return parse(value, is_column)
verifyClass(ISearchKey, FullTextKey) verifyClass(ISearchKey, FullTextKey)
...@@ -42,8 +42,8 @@ class KeywordKey(SearchKey): ...@@ -42,8 +42,8 @@ class KeywordKey(SearchKey):
default_comparison_operator = 'like' default_comparison_operator = 'like'
get_operator_from_value = True get_operator_from_value = True
def parseSearchText(self, value, column_id_set): def parseSearchText(self, value, is_column):
return parse(value, column_id_set) return parse(value, is_column)
def _buildQuery(self, operator_value_dict, logical_operator, parsed, group): def _buildQuery(self, operator_value_dict, logical_operator, parsed, group):
""" """
......
...@@ -341,7 +341,7 @@ class SearchKey(object): ...@@ -341,7 +341,7 @@ class SearchKey(object):
query = ComplexQuery(query_list, operator=logical_operator) query = ComplexQuery(query_list, operator=logical_operator)
return query return query
def parseSearchText(self, value, column_id_set): def parseSearchText(self, value, is_column):
return None return None
verifyClass(ISearchKey, SearchKey) verifyClass(ISearchKey, SearchKey)
......
...@@ -47,7 +47,7 @@ class AdvancedSearchTextDetector(lexer): ...@@ -47,7 +47,7 @@ class AdvancedSearchTextDetector(lexer):
return t return t
def t_COLUMN(self, t): def t_COLUMN(self, t):
self.found = t.value[:-1] in self.column_id_set self.found = self.isColumn(t.value[:-1])
t.type = 'WORD' t.type = 'WORD'
return t return t
...@@ -89,8 +89,8 @@ class AdvancedSearchTextDetector(lexer): ...@@ -89,8 +89,8 @@ class AdvancedSearchTextDetector(lexer):
def token(self): def token(self):
return self.token_list.pop(0) return self.token_list.pop(0)
def __call__(self, input, column_id_set): def __call__(self, input, is_column):
self.column_id_set = column_id_set self.isColumn = is_column
self.found = False self.found = False
check_grammar = False check_grammar = False
self.token_list = token_list = [] self.token_list = token_list = []
......
...@@ -66,8 +66,8 @@ def getAdvancedSearchTextParser(): ...@@ -66,8 +66,8 @@ def getAdvancedSearchTextParser():
return parser return parser
@profiler_decorator @profiler_decorator
def _parse(input, column_id_set, *args, **kw): def _parse(input, is_column, *args, **kw):
if getAdvancedSearchTextDetector()(input, column_id_set): if getAdvancedSearchTextDetector()(input, is_column):
result = getAdvancedSearchTextParser()(input, *args, **kw) result = getAdvancedSearchTextParser()(input, *args, **kw)
else: else:
result = None result = None
......
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