Commit 2677d091 authored by Vincent Pelletier's avatar Vincent Pelletier

ERP5Type.ERP5Type: Make updateRoleMapping work with 100k+ documents.

parent e9c4256e
...@@ -76,7 +76,7 @@ class LocalRoleAssignorMixIn(object): ...@@ -76,7 +76,7 @@ class LocalRoleAssignorMixIn(object):
security.declarePrivate('updateLocalRolesOnObject') security.declarePrivate('updateLocalRolesOnObject')
@UnrestrictedMethod @UnrestrictedMethod
def updateLocalRolesOnDocument(self, ob, user_name=None, reindex=True): def updateLocalRolesOnDocument(self, ob, user_name=None, reindex=True, activate_kw=()):
""" """
Assign Local Roles to Groups on object 'ob', based on Portal Type Role Assign Local Roles to Groups on object 'ob', based on Portal Type Role
Definitions and "ERP5 Role Definition" objects contained inside 'ob'. Definitions and "ERP5 Role Definition" objects contained inside 'ob'.
...@@ -132,7 +132,7 @@ class LocalRoleAssignorMixIn(object): ...@@ -132,7 +132,7 @@ class LocalRoleAssignorMixIn(object):
# XXX: Document modification detection assumes local roles are always # XXX: Document modification detection assumes local roles are always
# part of ob and not separate persistent objects. # part of ob and not separate persistent objects.
if reindex and ob._p_changed: if reindex and ob._p_changed:
ob.reindexObjectSecurity() ob.reindexObjectSecurity(activate_kw=dict(activate_kw))
security.declarePrivate('getFilteredRoleListFor') security.declarePrivate('getFilteredRoleListFor')
def getFilteredRoleListFor(self, ob=None): def getFilteredRoleListFor(self, ob=None):
...@@ -159,34 +159,28 @@ class LocalRoleAssignorMixIn(object): ...@@ -159,34 +159,28 @@ class LocalRoleAssignorMixIn(object):
security.declareProtected(Permissions.ModifyPortalContent, security.declareProtected(Permissions.ModifyPortalContent,
'updateRoleMapping') 'updateRoleMapping')
def updateRoleMapping(self, REQUEST=None, form_id=''): def updateRoleMapping(self, REQUEST=None, form_id='', priority=3):
"""Update the local roles in existing objects. """Update the local roles in existing objects.
XXX This should be implemented the same way as
ERP5Site_checkCatalogTable (cf erp5_administration).
""" """
portal = self.getPortalObject() self.getPortalObject().portal_catalog.searchAndActivate(
update_role_tag = self.__class__.__name__ + ".updateRoleMapping" 'updateLocalRolesOnSecurityGroups',
method_kw={
object_list = [x.path for x in 'activate_kw': {
portal.portal_catalog(portal_type=self.id, limit=None)] 'priority': priority,
object_list_len = len(object_list) },
# We need to use activities in order to make sure it will },
# work for an important number of objects activate_kw={
activate = portal.portal_activities.activate 'priority': priority,
for i in xrange(0, object_list_len, 100): # XXX: Tag is just for easier manual lookup in activity tables.
current_path_list = object_list[i:i+100] 'tag': self.id + '.updateRoleMapping',
activate(activity='SQLQueue', priority=3, tag=update_role_tag) \ },
.callMethodOnObjectList(current_path_list, portal_type=self.id,
'updateLocalRolesOnSecurityGroups', )
reindex=False)
activate(activity='SQLQueue', priority=3, after_tag=update_role_tag) \
.callMethodOnObjectList(current_path_list,
'reindexObjectSecurity')
if REQUEST is not None: if REQUEST is not None:
message = '%d objects updated' % object_list_len return REQUEST.RESPONSE.redirect(
return REQUEST.RESPONSE.redirect('%s/%s?portal_status_message=%s' self.absolute_url_path() + '/' + form_id +
% (self.absolute_url_path(), form_id, message)) '?portal_status_message=Updating%20local%20roles',
)
def _importRole(self, role_property_dict): def _importRole(self, role_property_dict):
"""Import a role from a BT or from an old portal type""" """Import a role from a BT or from an old portal type"""
......
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