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):
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
logical structure, or None if there is no obvious structure in given
......@@ -118,9 +118,12 @@ class ISearchKey(Interface):
value (string)
The string to parse.
column_id_set (set)
A list of valid column names. This is used when deciding wether value
should really be parsed or remain a bare string.
is_column (function taking one parameter)
This function will be called with a single parameter, being a column
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)
AbstratSyntaxNode complies with the IAbstractSyntaxNode interface.
......
......@@ -1793,6 +1793,18 @@ class Catalog(Folder,
return CachingMethod(_getTableIndex, id='SQLCatalog.getTableIndex', \
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
def getRelatedKeyDefinition(self, key):
"""
......@@ -1981,9 +1993,6 @@ class Catalog(Folder,
# column names with empty values. This is for backward compatibility. See
# comment about empty values.
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():
result = None
if isinstance(value, dict_type_list):
......@@ -2017,7 +2026,7 @@ class Catalog(Folder,
# String: parse using key's default search key.
search_key = self.getColumnDefaultSearchKey(key)
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:
# Parsing failed, create a query from the bare string.
result = self.buildSingleQuery(key, value)
......
......@@ -42,8 +42,8 @@ class DefaultKey(SearchKey):
default_comparison_operator = '='
get_operator_from_value = True
def parseSearchText(self, value, column_id_set):
return parse(value, column_id_set)
def parseSearchText(self, value, is_column):
return parse(value, is_column)
def _guessComparisonOperator(self, value):
if isinstance(value, basestring) and '%' in value:
......
......@@ -40,8 +40,8 @@ class FullTextKey(SearchKey):
default_comparison_operator = 'match'
get_operator_from_value = False
def parseSearchText(self, value, column_id_set):
return parse(value, column_id_set)
def parseSearchText(self, value, is_column):
return parse(value, is_column)
verifyClass(ISearchKey, FullTextKey)
......@@ -42,8 +42,8 @@ class KeywordKey(SearchKey):
default_comparison_operator = 'like'
get_operator_from_value = True
def parseSearchText(self, value, column_id_set):
return parse(value, column_id_set)
def parseSearchText(self, value, is_column):
return parse(value, is_column)
def _buildQuery(self, operator_value_dict, logical_operator, parsed, group):
"""
......
......@@ -341,7 +341,7 @@ class SearchKey(object):
query = ComplexQuery(query_list, operator=logical_operator)
return query
def parseSearchText(self, value, column_id_set):
def parseSearchText(self, value, is_column):
return None
verifyClass(ISearchKey, SearchKey)
......
......@@ -47,7 +47,7 @@ class AdvancedSearchTextDetector(lexer):
return 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'
return t
......@@ -89,8 +89,8 @@ class AdvancedSearchTextDetector(lexer):
def token(self):
return self.token_list.pop(0)
def __call__(self, input, column_id_set):
self.column_id_set = column_id_set
def __call__(self, input, is_column):
self.isColumn = is_column
self.found = False
check_grammar = False
self.token_list = token_list = []
......
......@@ -66,8 +66,8 @@ def getAdvancedSearchTextParser():
return parser
@profiler_decorator
def _parse(input, column_id_set, *args, **kw):
if getAdvancedSearchTextDetector()(input, column_id_set):
def _parse(input, is_column, *args, **kw):
if getAdvancedSearchTextDetector()(input, is_column):
result = getAdvancedSearchTextParser()(input, *args, **kw)
else:
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