Commit 886a6526 authored by Vincent Pelletier's avatar Vincent Pelletier

ZSQLCatalog: Drop support for *_expression arguments

parent c335c68f
......@@ -3546,31 +3546,6 @@ VALUES
self.assertEqual([x.getTitle() for x in
folder_object_list], real_title_list)
def test_countResultsUsesFromExpression(self):
person_module = self.getPersonModule()
module_len = len(person_module)
if module_len == 0:
person = person_module.newContent(portal_type='Person')
module_len = len(person_module)
module_uid = person_module.getUid()
self.tic()
catalog = self.getCatalogTool()
# Test sanity checks
self.assertEqual(len(catalog.searchResults(parent_uid=module_uid)),
module_len)
self.assertEqual(catalog.countResults(parent_uid=module_uid)[0][0],
module_len)
from_expression = {
'catalog': '(SELECT sub_catalog.* FROM catalog AS sub_catalog'
' WHERE sub_catalog.parent_uid=%i)'
' AS catalog' % (module_uid, ),
}
count = catalog.countResults(from_expression=from_expression)[0][0]
self.assertEqual(count, module_len)
def test_getParentUid(self):
from Products.ERP5.Document.Assignment import Assignment
import erp5.portal_type
......
......@@ -30,7 +30,6 @@
from Query import Query
from Products.ZSQLCatalog.SQLExpression import SQLExpression
from SQLQuery import SQLQuery
from Products.ZSQLCatalog.interfaces.query import IQuery
from zope.interface.verify import verifyClass
from Products.ZSQLCatalog.Query.AutoQuery import AutoQuery
......@@ -53,20 +52,9 @@ class ComplexQuery(Query):
logical_operator ('and', 'or', 'not')
Logical operator.
Default: 'and'
Deprecated
unknown_column_dict (dict)
Only one key of this dictionnary is used here:
key: 'from_expression'
value: string
This value will be passed through to SQLExpression. If it is
provided, this ComplexQuery must have no subquery (regular
SQLExpression limitation)
"""
self.logical_operator = kw.pop('logical_operator', 'and').lower()
assert self.logical_operator in ('and', 'or', 'not'), self.logical_operator
unknown_column_dict = kw.pop('unknown_column_dict', {})
self.from_expression = unknown_column_dict.pop('from_expression', None)
if kw:
raise TypeError('Unknown named arguments: %r' % (kw.keys(), ))
query_list = []
......@@ -78,14 +66,10 @@ class ComplexQuery(Query):
extend(arg)
else:
append(arg)
new_query_list = []
append = new_query_list.append
# Iterate over the flaten argument list to cast each into a query type.
for query in query_list:
if not isinstance(query, Query):
query = SQLQuery(query)
append(query)
self.query_list = new_query_list
raise TypeError('Got a non-query argument: %r' % (query, ))
self.query_list = query_list
self.checkQueryTree()
def _findRelatedQuery(self, query):
......@@ -190,7 +174,7 @@ class ComplexQuery(Query):
return SQLExpression(self,
sql_expression_list=sql_expression_list,
where_expression_operator=self.logical_operator,
from_expression=self.from_expression)
)
def registerColumnMap(self, sql_catalog, column_map):
for query in self.query_list:
......
......@@ -64,12 +64,9 @@ class EntireQuery(object):
catalog_table_name=None,
catalog_table_alias=None,
extra_column_list=(),
from_expression=None,
order_by_override_list=None,
implicit_join=False):
self.query = query
self.order_by_list = list(order_by_list)
self.order_by_override_set = frozenset(order_by_override_list)
self.group_by_list = list(group_by_list)
self.select_dict = defaultDict(select_dict)
self.left_join_list = left_join_list
......@@ -78,7 +75,6 @@ class EntireQuery(object):
self.catalog_table_name = catalog_table_name
self.catalog_table_alias = catalog_table_alias
self.extra_column_list = list(extra_column_list)
self.from_expression = from_expression
self.implicit_join = implicit_join
def asSearchTextExpression(self, sql_catalog):
......@@ -91,7 +87,6 @@ class EntireQuery(object):
# method or do it here ?
# Column Map was not built yet, do it.
column_map = ColumnMap(catalog_table_name=self.catalog_table_name,
table_override_map=self.from_expression,
left_join_list=self.left_join_list,
inner_join_list=self.inner_join_list,
implicit_join=self.implicit_join,
......@@ -115,8 +110,6 @@ class EntireQuery(object):
else:
column_map.ignoreColumn(alias)
column_map.registerColumn(column)
for override in self.order_by_override_set:
column_map.ignoreColumn(override)
for order_by in self.order_by_list:
assert isinstance(order_by, (tuple, list))
assert len(order_by)
......@@ -155,15 +148,11 @@ class EntireQuery(object):
append = new_order_by_list.append
for order_by in self.order_by_list:
column = order_by[0]
if column in self.order_by_override_set:
LOG('EntireQuery', WARNING, 'Order-by column %r is forcibly accepted. This use is strongly discouraged.' % (column, ))
rendered = column
else:
try:
rendered = column_map.asSQLColumn(column)
except KeyError:
LOG('EntireQuery', WARNING, 'Order by %r ignored: it could not be mapped to a known column.' % (order_by, ))
rendered = None
try:
rendered = column_map.asSQLColumn(column)
except KeyError:
LOG('EntireQuery', WARNING, 'Order by %r ignored: it could not be mapped to a known column.' % (order_by, ))
rendered = None
if rendered is not None:
append((rendered, ) + tuple(order_by[1:]) + (
None, ) * (3 - len(order_by)))
......@@ -196,21 +185,11 @@ class EntireQuery(object):
# where_pattern % (x, ) for x in join_table_list
# )))
# BBB self.from_expression forces use of implicit inner join
table_alias_dict = column_map.getTableAliasDict()
if self.from_expression:
warnings.warn("Providing a 'from_expression' is deprecated.",
DeprecationWarning)
# XXX: perhaps move this code to ColumnMap?
legacy_from_expression = self.from_expression
from_expression = LegacyTableDefinition(legacy_from_expression,
table_alias_dict)
table_alias_dict = None
else:
from_expression = column_map.getTableDefinition()
assert ((from_expression is None) !=
(table_alias_dict is None)), ("Got both a from_expression "
"and a table_alias_dict")
from_expression = column_map.getTableDefinition()
assert ((from_expression is None) !=
(table_alias_dict is None)), ("Got both a from_expression "
"and a table_alias_dict")
self.sql_expression_list = sql_expression_list
# TODO: wrap the table_alias_dict above into a TableDefinition as well,
# even without a legacy_table_definition.
......
......@@ -296,7 +296,7 @@ class Catalog(Folder,
An Object Catalog maintains a table of object metadata, and a
series of manageable indexes to quickly search for objects
(references in the metadata) that satisfy a search where_expression.
(references in the metadata) that satisfy search conditions.
This class is not Zope specific, and can be used in any python
program to build catalogs of objects. Note that it does require
......@@ -2014,11 +2014,7 @@ class Catalog(Folder,
query_list = []
append = query_list.append
# unknown_column_dict: contains all (key, value) pairs which could not be
# changed into queries. This is here for backward compatibility, because
# scripts can invoke this method and expect extra parameters (such as
# from_expression) to be handled. As they are normaly handled at
# buildSQLQuery level, we must store them into final ComplexQuery, which
# will handle them.
# changed into queries.
unknown_column_dict = {}
# empty_value_dict: contains all keys whose value causes them to be
# discarded.
......@@ -2107,11 +2103,10 @@ class Catalog(Folder,
LOG('SQLCatalog', WARNING, message)
else:
raise TypeError(message)
return ComplexQuery(query_list, logical_operator=operator,
unknown_column_dict=unknown_column_dict)
return ComplexQuery(query_list, logical_operator=operator)
security.declarePrivate('buildOrderByList')
def buildOrderByList(self, sort_on=None, sort_order=None, order_by_expression=None):
def buildOrderByList(self, sort_on=None, sort_order=None):
"""
Internal method. Should not be used by code outside buildSQLQuery.
......@@ -2128,8 +2123,6 @@ class Catalog(Folder,
order_by_list = []
append = order_by_list.append
if sort_on is not None:
if order_by_expression is not None:
LOG('SQLCatalog', WARNING, 'order_by_expression (%r) and sort_on (%r) were given. Ignoring order_by_expression.' % (order_by_expression, sort_on))
if not isinstance(sort_on, (tuple, list)):
sort_on = [[sort_on]]
for item in sort_on:
......@@ -2150,16 +2143,6 @@ class Catalog(Folder,
elif item[2] == 'float':
item[2] = 'DECIMAL'
append(item)
elif order_by_expression is not None:
if not isinstance(order_by_expression, basestring):
raise TypeError, 'order_by_expression must be a basestring instance. Got %r.' % (order_by_expression, )
for x in order_by_expression.split(','):
x = x.strip()
item = x.rsplit(None, 1)
if len(item) > 1 and item[-1].upper() in ('ASC', 'DESC'):
append(item)
else:
append([x])
return order_by_list
security.declarePrivate('buildEntireQuery')
......@@ -2182,23 +2165,9 @@ class Catalog(Folder,
implicit_join = kw.pop('implicit_join', True)
# Handle order_by_list
order_by_list = kw.pop('order_by_list', [])
# Handle from_expression
from_expression = kw.pop('from_expression', None)
# Handle where_expression
where_expression = kw.get('where_expression', None)
if isinstance(where_expression, basestring) and len(where_expression):
LOG('SQLCatalog', INFO, 'Giving where_expression a string value is deprecated.')
# Transform given where_expression into a query, and update kw.
kw['where_expression'] = SQLQuery(where_expression)
# Handle select_expression_key
# It is required to support select_expression_key parameter for backward
# compatiblity, but I'm not sure if there can be a serious use for it in
# new API.
order_by_override_list = kw.pop('select_expression_key', ())
return EntireQuery(
query=self.buildQuery(kw, ignore_empty_string=ignore_empty_string, ignore_unknown_columns=ignore_unknown_columns),
order_by_list=order_by_list,
order_by_override_list=order_by_override_list,
group_by_list=group_by_list,
select_dict=select_dict,
left_join_list=left_join_list,
......@@ -2208,7 +2177,7 @@ class Catalog(Folder,
catalog_table_name=query_table,
catalog_table_alias=query_table_alias,
extra_column_list=extra_column_list,
from_expression=from_expression)
)
security.declarePublic('buildSQLQuery')
def buildSQLQuery(self, query_table='catalog',
......@@ -2240,56 +2209,32 @@ class Catalog(Folder,
"""
Convert some catalog arguments to generic arguments.
group_by, group_by_expression -> group_by_list
select_list, select_expression -> select_dict
sort_on, sort_on_order, order_by_expression -> order_list
group_by -> group_by_list
select_list -> select_dict
sort_on, sort_on_order -> order_list
"""
kw = kw.copy()
group_by = kw.pop('group_by', None)
group_by_expression = kw.pop('group_by_expression', None)
group_by_list = kw.pop('group_by_list', None) or group_by or group_by_expression or []
if isinstance(group_by_list, basestring):
group_by_list = [x.strip() for x in group_by_list.split(',')]
kw['group_by_list'] = group_by_list
select_list = kw.pop('select_list', None)
select_expression = kw.pop('select_expression', None)
select_dict = kw.pop('select_dict', None) or select_list or select_expression or {}
kw['group_by_list'] = kw.pop('group_by_list', None) or kw.pop('group_by', [])
select_dict = kw.pop('select_dict', None) or kw.pop('select_list', {})
if isinstance(select_dict, (list, tuple)):
select_dict = dict.fromkeys(select_dict)
if isinstance(select_dict, basestring):
if len(select_dict):
real_select_dict = {}
for column in select_dict.split(','):
index = column.lower().find(' as ')
if index != -1:
real_select_dict[column[index + 4:].strip()] = column[:index].strip()
else:
real_select_dict[column.strip()] = None
select_dict = real_select_dict
else:
select_dict = None
elif isinstance(select_dict, (list, tuple)):
select_dict = dict.fromkeys(select_dict)
kw['select_dict'] = select_dict
order_by_list = kw.pop('order_by_list', None)
sort_on = kw.pop('sort_on', None)
sort_order = kw.pop('sort_order', None)
order_by_expression = kw.pop('order_by_expression', None)
if order_by_list is None:
order_by_list = self.buildOrderByList(
sort_on=sort_on,
sort_order=sort_order,
order_by_expression=order_by_expression,
)
else:
if sort_on is not None:
LOG('SQLCatalog', WARNING, 'order_by_list and sort_on were given, ignoring sort_on.')
if sort_order is not None:
LOG('SQLCatalog', WARNING, 'order_by_list and sort_order were given, ignoring sort_order.')
if order_by_expression is not None:
LOG('SQLCatalog', WARNING, 'order_by_list and order_by_expression were given, ignoring order_by_expression.')
kw['order_by_list'] = order_by_list or []
return kw
......@@ -2412,7 +2357,7 @@ class Catalog(Folder,
security.declarePrivate('countResults')
def countResults(self, REQUEST=None, **kw):
""" Returns the number of items which satisfy the where_expression """
""" Returns the number of items which satisfy the conditions """
return self.queryResults(
self.getCountResultsMethod(),
REQUEST=REQUEST,
......
......@@ -45,8 +45,7 @@ class IEntireQuery(Interface):
def __init__(query, order_by_list=None, group_by_list=None,
select_dict=None, limit=None, catalog_table_name=None,
extra_column_list=None, from_expression=None,
order_by_override_list=None):
extra_column_list=None):
"""
query (Query instance)
The root of the Query tree this query will contain.
......@@ -73,12 +72,6 @@ class IEntireQuery(Interface):
The list of columns to register to column map. They will not be used
in final rendering, but are hint on which table are supposed to be
used when mapping columns.
from_expression
See SQLExpression.
order_by_override_list (list of string)
If a column is in order_by_list, cannot be mapped to a table column
but is present in this list, it will be passed through to
SQLExpression.
"""
def asSQLExpression(sql_catalog, only_group_columns):
......
......@@ -805,21 +805,6 @@ class TestSQLCatalog(ERP5TypeTestCase):
sort_on=[['default', 'DESC', 'INT']]
)
self.assertEqual(order_by_list, [['default', 'DESC', 'INT']])
order_by_list = self._catalog.buildOrderByList(
order_by_expression='default'
)
order_by_list = self._catalog.buildOrderByList(
order_by_expression='default DESC'
)
self.assertEqual(order_by_list, [['default', 'DESC']])
order_by_list = self._catalog.buildOrderByList(
order_by_expression='CAST(default AS INT) DESC'
)
self.assertEqual(order_by_list, [['CAST(default AS INT)', 'DESC']])
order_by_list = self._catalog.buildOrderByList(
order_by_expression='CAST(default AS INT)'
)
self.assertEqual(order_by_list, [['CAST(default AS INT)']])
##return catalog(title=Query(title='a', operator='not'))
#return catalog(title={'query': 'a', 'operator': 'not'})
......
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