From 213d6dfe608fb54187e0bb477f40993e56635df8 Mon Sep 17 00:00:00 2001 From: Vincent Pelletier <vincent@nexedi.com> Date: Fri, 9 Jun 2017 15:48:23 +0900 Subject: [PATCH] CategoryTool: Get rid of build{,Advanced}SQLSelector. Writing SQL belongs to catalog. --- product/CMFCategory/CategoryTool.py | 119 ---------------------------- 1 file changed, 119 deletions(-) diff --git a/product/CMFCategory/CategoryTool.py b/product/CMFCategory/CategoryTool.py index 3d672aadfd..90759ed9a2 100644 --- a/product/CMFCategory/CategoryTool.py +++ b/product/CMFCategory/CategoryTool.py @@ -1532,125 +1532,6 @@ class CategoryTool( UniqueObject, Folder, Base ): result.append(o.getProperty(property_name, None)) return result - # SQL Expression Building - security.declareProtected(Permissions.AccessContentsInformation, 'buildSQLSelector') - def buildSQLSelector(self, category_list, query_table='category', none_sql_value=None): - """ - Returns an SQL selector expression from a list of categories - We make here a simple method wich simply checks membership - This is like an OR. More complex selections (AND of OR) will require - to generate a much more complex where_expression with table aliases - - List of lists - - - none_sql_value is used in order to specify what is the None value into - sql tables - """ - result = self.buildAdvancedSQLSelector(category_list, query_table, - none_sql_value, strict=False)['where_expression'] - # Quirk to keep strict backward compatibility. Should be removed when - # tested. - if result == '': - result = [] - return result - - # SQL Expression Building - security.declareProtected(Permissions.AccessContentsInformation, 'buildAdvancedSQLSelector') - def buildAdvancedSQLSelector(self, category_list, query_table='category', - none_sql_value=None, strict=True, catalog_table_name='catalog'): - # XXX: about "strict" parameter: This is a transition parameter, - # allowing someone hitting a bug to revert to original behaviour easily. - # It is not a correct name, as pointed out by Jerome. But instead of - # searching for another name, it would be much better to just remove it. - """ - Return chunks of SQL to check for category membership. - - none_sql_value (default=None): - Specify the SQL value of None in SQL. - None means SQL NULL. - - strict (boolean, default=True): - False: - Resulting query will match any document which matches at least one - of given categories. - True: - Resulting query will match any document which matches all given - categories, except for categories which are not defined on the - document. This usefull for example for predicates, where one wants - to fetch all predicates applicable for a given set of conditions, - including generic predicates which check only a subset of those - conditions. - Performance hint: Order given category list to have most - discriminant factors before lesser discriminant ones. - """ - result = {} - def renderUIDValue(uid): - uid = ((uid is None) and (none_sql_value, ) or (uid, ))[0] - if uid is None: - return 'NULL' - else: - return '%s' % (uid, ) - def renderUIDWithOperator(uid): - value = renderUIDValue(uid) - if value == 'NULL': - return 'IS NULL' - return '= %s' % (value, ) - if isinstance(category_list, str): - category_list = [category_list] - if strict: - category_uid_dict = {} - ordered_base_category_uid_list = [] - # Fetch all category and base category uids, and regroup by - # base_category. - for category in category_list: - if isinstance(category, str) and category: - base_category_uid = self.getBaseCategoryUid(category) - category_uid_list = category_uid_dict.setdefault(base_category_uid, []) - if len(category_uid_list) == 0: - # New base category, append it to the ordered list. - ordered_base_category_uid_list.append(base_category_uid) - category_uid = self.getCategoryUid(category) - category_uid_list.append(category_uid) - - if category_uid is None and category != 'NULL': - raise TypeError( - "Invalid category passed to buildAdvancedSQLSelector: %r" - % category ) - - # Generate "left join" and "where" expressions. - left_join_list = [catalog_table_name] - where_expression_list = [] - format_dict = {'catalog': catalog_table_name} - for base_category_uid in ordered_base_category_uid_list: - alias_name = 'base_%s' % (base_category_uid, ) - format_dict['alias'] = alias_name - format_dict['condition'] = renderUIDWithOperator(base_category_uid) - left_join_list.append( - '`%(alias)s` ON (`%(catalog)s`.uid = `%(alias)s`.uid AND '\ - '`%(alias)s`.category_strict_membership = "1" AND '\ - '`%(alias)s`.base_category_uid %(condition)s)' % format_dict) - category_uid_name = '`%s`.category_uid' % (alias_name, ) - category_uid_list = category_uid_dict[base_category_uid] - if category_uid_list == [None]: - # Only one UID and it's None: do not allow NULL value to be selected. - where_expression_list.append('(%s %s)' % \ - (category_uid_name, renderUIDWithOperator(base_category_uid))) - else: - # In any other case, allow it. - where_expression_list.append('(%s IS NULL OR %s = 0 OR %s IN (%s))' % \ - (category_uid_name, category_uid_name, category_uid_name, - ', '.join([renderUIDValue(x) for x in category_uid_list]))) - result['from_expression'] = {catalog_table_name: - ('\nLEFT JOIN `%s` AS ' % (query_table, )).join(left_join_list)} - result['where_expression'] = '(%s)' % (' AND '.join(where_expression_list), ) - else: - result['where_expression'] = \ - ' OR '.join(['(%s.category_uid %s AND %s.base_category_uid %s)' %\ - (query_table, renderUIDWithOperator(self.getCategoryUid(x)), - query_table, renderUIDWithOperator(self.getBaseCategoryUid(x))) - for x in category_list if isinstance(x, str) and x]) - return result - security.declareProtected( Permissions.AccessContentsInformation, 'getCategoryMemberValueList' ) def getCategoryMemberValueList(self, context, base_category=None, portal_type=(), strict_membership=False, strict=False, **kw): -- 2.30.9