From 93bd0efeb1ba3c71f2b44c1f5d93b134dd566cf9 Mon Sep 17 00:00:00 2001 From: Sebastien Robin <seb@nexedi.com> Date: Thu, 21 Jun 2007 15:48:59 +0000 Subject: [PATCH] - added method callMethodOnObjectList on Folder - Make the updateRoleMapping method on RoleProviderBase much more scallable. It will easily works with thousands of objects, but probably not enough for millions git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@14916 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5Type/Core/Folder.py | 17 +++++++++++++++++ product/ERP5Type/RoleProviderBase.py | 27 ++++++++++++++++----------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/product/ERP5Type/Core/Folder.py b/product/ERP5Type/Core/Folder.py index 5e42d7b93f..19ed7ffda1 100644 --- a/product/ERP5Type/Core/Folder.py +++ b/product/ERP5Type/Core/Folder.py @@ -33,6 +33,7 @@ import ExtensionClass from Products.CMFCore.utils import _getAuthenticatedUser from Products.CMFCore.CMFCatalogAware import CMFCatalogAware +from Products.CMFCore import CMFCorePermissions from Products.ERP5Type.Base import Base from Products.ERP5Type.CopySupport import CopyContainer @@ -932,5 +933,21 @@ class Folder( CopyContainer, CMFBTreeFolder, Base, FolderMixIn): object.manage_beforeDelete(object, self) self._delOb(id) + security.declareProtected( CMFCorePermissions.ManagePortal, 'callMethodOnObjectList' ) + def callMethodOnObjectList(self, object_path_list, method_id, *args, **kw): + """ + Very usefull if we want to activate the call of a method + on many objects at a time. Like this we could prevent creating + too much acitivities at a time, and we may have only the path + + """ + portal = self.getPortalObject() + for object_path in object_path_list: + current_object = portal.unrestrictedTraverse(object_path) + method = getattr(current_object, method_id, None) + if method is None: + raise ValueError, "The method %s was not found" % method_id + method(*args, **kw) + # Overwrite Zope setTitle() Folder.setTitle = Base.setTitle diff --git a/product/ERP5Type/RoleProviderBase.py b/product/ERP5Type/RoleProviderBase.py index 73ee3e9f66..5658a25c46 100644 --- a/product/ERP5Type/RoleProviderBase.py +++ b/product/ERP5Type/RoleProviderBase.py @@ -23,6 +23,8 @@ from Products.ERP5Type import _dtmldir from RoleInformation import RoleInformation from Permissions import ManagePortal +from zLOG import LOG + #from interfaces.portal_roles import RoleProvider as IRoleProvider @@ -257,18 +259,21 @@ class RoleProviderBase: """Update the local roles in existing objects. """ portal_catalog = self.portal_catalog - i = 0 - for brain in portal_catalog(portal_type = self.id): - obj = brain.getObject() - user_id = None - owner_tuple = obj.getOwnerTuple() - if owner_tuple is not None: - user_id = owner_tuple[1] - obj.updateLocalRolesOnSecurityGroups(user_name = user_id) - i += 1 - if REQUEST is not None: - return self.manage_editRolesForm(REQUEST, manage_tabs_message='%d objects updated' % (i,)) + object_list = portal_catalog(portal_type = self.id, limit=None) + # We need to use activities in order to make sure it will + # work for an important number of objects + object_list_len = len(object_list) + portal_activities = self.portal_activities + object_path_list = [x.path for x in object_list] + for i in xrange(0, object_list_len, 100): + current_path_list = object_path_list[i:i+100] + portal_activities.activate(activity='SQLQueue')\ + .callMethodOnObjectList(current_path_list, + 'updateLocalRolesOnSecurityGroups') + if REQUEST is not None: + return self.manage_editRolesForm(REQUEST, + manage_tabs_message='%d objects updated' % (object_list_len,)) InitializeClass(RoleProviderBase) -- 2.30.9