Commit 1cea9468 authored by Julien Muchembled's avatar Julien Muchembled

ZSQLCatalog: add support for sets (in addition to lists/tuples) in several places

parent e5a37689
...@@ -32,7 +32,7 @@ from OperatorBase import OperatorBase ...@@ -32,7 +32,7 @@ from OperatorBase import OperatorBase
from Products.ZSQLCatalog.SQLExpression import SQLExpression from Products.ZSQLCatalog.SQLExpression import SQLExpression
from Products.ZSQLCatalog.interfaces.operator import IOperator from Products.ZSQLCatalog.interfaces.operator import IOperator
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
from Products.ZSQLCatalog.SQLCatalog import profiler_decorator from Products.ZSQLCatalog.SQLCatalog import profiler_decorator, list_type_list
class ComparisonOperatorBase(OperatorBase): class ComparisonOperatorBase(OperatorBase):
@profiler_decorator @profiler_decorator
...@@ -58,10 +58,11 @@ class MonovaluedComparisonOperator(ComparisonOperatorBase): ...@@ -58,10 +58,11 @@ class MonovaluedComparisonOperator(ComparisonOperatorBase):
""" """
value_list must either be a non-list or a single-value list. value_list must either be a non-list or a single-value list.
""" """
if isinstance(value_list, (tuple, list)): if isinstance(value_list, list_type_list):
if len(value_list) > 1: try:
value_list, = value_list
except ValueError:
raise ValueError, '%r: value_list must not contain more than one item. Got %r' % (self, value_list) raise ValueError, '%r: value_list must not contain more than one item. Got %r' % (self, value_list)
value_list = value_list[0]
return self._renderValue(value_list) return self._renderValue(value_list)
@profiler_decorator @profiler_decorator
...@@ -69,10 +70,11 @@ class MonovaluedComparisonOperator(ComparisonOperatorBase): ...@@ -69,10 +70,11 @@ class MonovaluedComparisonOperator(ComparisonOperatorBase):
""" """
value_list must either be a non-list or a single-value list. value_list must either be a non-list or a single-value list.
""" """
if isinstance(value_list, (tuple, list)): if isinstance(value_list, list_type_list):
if len(value_list) > 1: try:
value_list, = value_list
except ValueError:
raise ValueError, '%r: value_list must not contain more than one item. Got %r' % (self, value_list) raise ValueError, '%r: value_list must not contain more than one item. Got %r' % (self, value_list)
value_list = value_list[0]
return self._render(column, value_list) return self._render(column, value_list)
verifyClass(IOperator, MonovaluedComparisonOperator) verifyClass(IOperator, MonovaluedComparisonOperator)
...@@ -83,18 +85,18 @@ class MultivaluedComparisonOperator(ComparisonOperatorBase): ...@@ -83,18 +85,18 @@ class MultivaluedComparisonOperator(ComparisonOperatorBase):
""" """
value_list must be a multi-value list (more than one item). value_list must be a multi-value list (more than one item).
""" """
if not isinstance(value_list, (tuple, list)) or len(value_list) < 2: if not isinstance(value_list, list_type_list) or len(value_list) < 2:
raise ValueError, '%r: value_list must be a list of more than one item. Got %r' % (self, value_list) raise ValueError, '%r: value_list must be a list of more than one item. Got %r' % (self, value_list)
return '(%s)' % (', '.join([self._renderValue(x) for x in value_list]), ) return '(%s)' % ', '.join(map(self._renderValue, value_list))
@profiler_decorator @profiler_decorator
def render(self, column, value_list): def render(self, column, value_list):
""" """
value_list must be a multi-value list (more than one item). value_list must be a multi-value list (more than one item).
""" """
if not isinstance(value_list, (tuple, list)) or len(value_list) < 2: if not isinstance(value_list, list_type_list) or len(value_list) < 2:
raise ValueError, '%r: value_list must be a list of more than one item. Got %r' % (self, value_list) raise ValueError, '%r: value_list must be a list of more than one item. Got %r' % (self, value_list)
return column, '(%s)' % (', '.join([self._renderValue(x) for x in value_list]), ) return column, '(%s)' % ', '.join(map(self._renderValue, value_list))
verifyClass(IOperator, MultivaluedComparisonOperator) verifyClass(IOperator, MultivaluedComparisonOperator)
...@@ -140,10 +142,11 @@ class SphinxSEComparisonOperator(MonovaluedComparisonOperator): ...@@ -140,10 +142,11 @@ class SphinxSEComparisonOperator(MonovaluedComparisonOperator):
""" """
* add ';mode=extended2' to invoke extended search * add ';mode=extended2' to invoke extended search
""" """
if isinstance(value_list, (tuple, list)): if isinstance(value_list, list_type_list):
if len(value_list) > 1: try:
value_list, = value_list
except ValueError:
raise ValueError, '%r: value_list must not contain more than one item. Got %r' % (self, value_list) raise ValueError, '%r: value_list must not contain more than one item. Got %r' % (self, value_list)
value_list = value_list[0]
value_list = '%s;mode=extended2;limit=1000' % value_list value_list = '%s;mode=extended2;limit=1000' % value_list
return self._renderValue(value_list) return self._renderValue(value_list)
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
from Query import Query from Query import Query
from Products.ZSQLCatalog.interfaces.query import IQuery from Products.ZSQLCatalog.interfaces.query import IQuery
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
from Products.ZSQLCatalog.SQLCatalog import profiler_decorator from Products.ZSQLCatalog.SQLCatalog import profiler_decorator, list_type_list
from zLOG import LOG, WARNING from zLOG import LOG, WARNING
class SimpleQuery(Query): class SimpleQuery(Query):
...@@ -67,20 +67,20 @@ class SimpleQuery(Query): ...@@ -67,20 +67,20 @@ class SimpleQuery(Query):
# already). # already).
comparison_operator = comparison_operator.lower() comparison_operator = comparison_operator.lower()
if comparison_operator == 'in': if comparison_operator == 'in':
if isinstance(value, (list, tuple)): if isinstance(value, list_type_list):
if len(value) == 0: if len(value) == 0:
raise ValueError, 'Empty lists are not allowed.' raise ValueError, 'Empty lists are not allowed.'
elif len(value) == 1: elif len(value) == 1:
value = value[0] value, = value
comparison_operator = '=' comparison_operator = '='
else: else:
comparison_operator = '=' comparison_operator = '='
elif comparison_operator == '=': elif comparison_operator == '=':
if isinstance(value, (list, tuple)): if isinstance(value, list_type_list):
if len(value) == 0: if len(value) == 0:
raise ValueError, 'Empty lists are not allowed.' raise ValueError, 'Empty lists are not allowed.'
elif len(value) == 1: elif len(value) == 1:
value = value[0] value, = value
else: else:
comparison_operator = 'in' comparison_operator = 'in'
if value is None: if value is None:
......
...@@ -131,6 +131,7 @@ class transactional_cache_decorator: ...@@ -131,6 +131,7 @@ class transactional_cache_decorator:
return result return result
return wrapper return wrapper
list_type_list = list, tuple, set, frozenset
try: try:
from ZPublisher.HTTPRequest import record from ZPublisher.HTTPRequest import record
except ImportError: except ImportError:
...@@ -2173,12 +2174,12 @@ class Catalog(Folder, ...@@ -2173,12 +2174,12 @@ class Catalog(Folder,
value = dict(value) value = dict(value)
if ignore_empty_string and ( if ignore_empty_string and (
value == '' value == ''
or (isinstance(value, (list, tuple)) and len(value) == 0) or (isinstance(value, list_type_list) and not value)
or (isinstance(value, dict) and ( or (isinstance(value, dict) and (
'query' not in value 'query' not in value
or value['query'] == '' or value['query'] == ''
or (isinstance(value['query'], (list, tuple)) or (isinstance(value['query'], list_type_list)
and len(value['query']) == 0)))): and not value['query'])))):
# We have an empty value, do not create a query from it # We have an empty value, do not create a query from it
empty_value_dict[key] = value empty_value_dict[key] = value
else: else:
......
...@@ -34,7 +34,7 @@ from Products.ZSQLCatalog.Query.ComplexQuery import ComplexQuery ...@@ -34,7 +34,7 @@ from Products.ZSQLCatalog.Query.ComplexQuery import ComplexQuery
from Products.ZSQLCatalog.interfaces.search_key import ISearchKey from Products.ZSQLCatalog.interfaces.search_key import ISearchKey
from zope.interface.verify import verifyClass from zope.interface.verify import verifyClass
from zope.interface import implements from zope.interface import implements
from Products.ZSQLCatalog.SQLCatalog import profiler_decorator from Products.ZSQLCatalog.SQLCatalog import profiler_decorator, list_type_list
single_operator_dict = { single_operator_dict = {
'min': '>=', 'min': '>=',
...@@ -120,7 +120,7 @@ class SearchKey(object): ...@@ -120,7 +120,7 @@ class SearchKey(object):
operator_text = operator.getOperatorSearchText() operator_text = operator.getOperatorSearchText()
if column is None: if column is None:
column = self.getColumn() column = self.getColumn()
if isinstance(value, (list, tuple)): if isinstance(value, list_type_list):
assert operator_text == 'in' assert operator_text == 'in'
assert len(value) assert len(value)
value = [self._renderValueAsSearchText(x, operator) for x in value] value = [self._renderValueAsSearchText(x, operator) for x in value]
...@@ -272,14 +272,15 @@ class SearchKey(object): ...@@ -272,14 +272,15 @@ class SearchKey(object):
logical_operator = value_operator logical_operator = value_operator
search_value = actual_value search_value = actual_value
# Cast to list # Cast to list
if isinstance(search_value, (tuple, list)): if isinstance(search_value, list_type_list):
# Check list content (not empty, homogenous) # Check list content (not empty, homogenous)
search_value_len = len(search_value) iter_search_value = iter(search_value)
if search_value_len == 0: try:
reference_class = iter_search_value.next().__class__
except StopIteration:
raise ValueError, 'Value cannot be an empty list/tuple: %r' % \ raise ValueError, 'Value cannot be an empty list/tuple: %r' % \
(search_value, ) (search_value, )
reference_class = search_value[0].__class__ for x in iter_search_value:
for x in search_value[1:]:
if x.__class__ != reference_class: if x.__class__ != reference_class:
raise TypeError, 'List elements must be of the same class: %r' % \ raise TypeError, 'List elements must be of the same class: %r' % \
(search_value, ) (search_value, )
......
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