Commit b3c58f18 authored by Ayush Tiwari's avatar Ayush Tiwari Committed by Ayush Tiwari

Products.ERP5Catalog: EPR5-ify catalog.

Move from SQLCatalog to ERP5Catalog as the default Catalog inside ERP5.
The major difference is use of Products.ERP5Type.Core.Folder as Catalog
base class.

Significant addition/changes in
-------------------------------

  ERP5Catalog class:
    Inherit from Catalog class from Products.ZSQLCatalog.SQLCatalog instead of copy-pasting the whole code again.
    Monkey patch some property setters and getters to maintain consistency
    Override getCatalogMethodIds cause it uses global variable in SQLCatalog.Catalog
    Add FilterDict and Filter class to have consistency with `filter_dict` attribute of SQLCatalog

  BusinessTemplate:
    Update BusinessTemplate installation with updated filter_dict
    Also, use dynamic migration while installing the catalog method objects for
    bt5. This way we have SQL Methods migrated just after installation.

  Tests:
    Update tests according to changes in portal_catalog

  SQLCatalog, testZSQLCatalog:
    Cleanup for unusable functions
parent 6f29c8b8
......@@ -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)
......
......@@ -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):
......
# -*- 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
##### Overriding setters functions for multple_selection properties #######
##### Required as after every edit we expect the values sorted #######
def _setSqlClearCatalogList(self, value, **kw):
self._baseSetSqlClearCatalogList(sorted(value), **kw)
def _setSqlCatalogFullTextSearchKeysList(self, value, **kw):
self._baseSetSqlCatalogFullTextSearchKeysList(sorted(value), **kw)
def _setSqlCatalogObjectListList(self, value, **kw):
self._baseSetSqlCatalogObjectListList(sorted(value), **kw)
def _setSqlUncatalogObjectList(self, value, **kw):
self._baseSetSqlUncatalogObjectList(sorted(value), **kw)
def _setSqlSearchTablesList(self, value, **kw):
self._baseSetSqlSearchTablesList(sorted(value), **kw)
def _setSqlCatalogDatetimeSearchKeysList(self, value, **kw):
value = sorted(value)
self._baseSetSqlCatalogDatetimeSearchKeysList(sorted(value), **kw)
def _setSqlCatalogKeywordSearchKeysList(self, value, **kw):
self._baseSetSqlCatalogKeywordSearchKeysList(sorted(value), **kw)
def _setSqlCatalogMultivalueKeysList(self, value, **kw):
self._baseSetSqlCatalogMultivalueKeysList(sorted(value), **kw)
def _setSqlCatalogRequestKeysList(self, value, **kw):
self._baseSetSqlCatalogRequestKeysList(sorted(value), **kw)
def _setSqlCatalogIndexOnOrderKeysList(self, value, **kw):
self._baseSetSqlCatalogIndexOnOrderKeysList(sorted(value), **kw)
def _setSqlCatalogTableVoteScriptsList(self, value, **kw):
self._baseSetSqlCatalogTableVoteScriptsList(sorted(value), **kw)
def _setSqlSearchResultKeysList(self, value, **kw):
self._baseSetSqlSearchResultKeysList(sorted(value), **kw)
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()
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('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
......@@ -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 = ()
......
......@@ -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
......
......@@ -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>
......
......@@ -67,7 +67,7 @@ def manage_page_footer(self):
+ ['printed', 'same_type', 'string', 'sequence', 'random', 'DateTime',
'whrandom', 'reorder', 'sets', 'test', 'math'])
live_check_python_script = 1 # XXX make it a preference ?
elif document.meta_type in ('Z SQL Method', ):
elif document.meta_type in ('Z SQL Method', 'ERP5 SQL Method'):
mode = 'sql'
textarea_selector = 'textarea[name="template:text"]'
elif document.meta_type in ('Page Template', 'ERP5 OOo Template', ):
......
......@@ -3258,9 +3258,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',
......
......@@ -744,8 +744,7 @@ class Catalog(Folder,
for item in item_list:
f.write(' <item type="str">%s</item>\n' % escape(str(item)))
f.write(' </property>\n')
# XXX Although filters are not properties, output filters here.
# XXX Ideally, filters should be properties in Z SQL Methods, shouldn't they?
# Filters are now propeties in ERP5 SQL Method(s)
filter_dict = self._getFilterDict()
if filter_dict:
for filter_id, filter_def in sorted(filter_dict.iteritems()):
......@@ -765,61 +764,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=''):
......@@ -2718,179 +2662,6 @@ class Catalog(Folder,
method = self._getOb(self.getSqlReadRecordedObjectList())
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):
"""
......@@ -2899,7 +2670,7 @@ class Catalog(Folder,
If 'deferred' is True, then returns the deferred connection
"""
for method in self.objectValues():
if method.meta_type == 'Z SQL Method':
if method.meta_type in ('Z SQL Method', 'ERP5 SQL Method',):
if ('deferred' in method.connection_id) == deferred:
return method.connection_id
......
......@@ -375,7 +375,7 @@ class ZCatalog(Folder, Persistent, Implicit):
security.declarePrivate('changeSQLConnectionIds')
def changeSQLConnectionIds(self, folder, sql_connection_id_dict):
if sql_connection_id_dict is not None:
if folder.meta_type == 'Z SQL Method':
if folder.meta_type in ('Z SQL Method', 'ERP5 SQL Method',):
connection_id = folder.connection_id
if connection_id in sql_connection_id_dict:
folder.connection_id = sql_connection_id_dict[connection_id]
......
......@@ -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
......
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