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