Add LDAPMultiQuery base class and make it the base of LDAPDelete.

In other words: make *-del commands accept 1 or more primary keys
of entries to be deleted.

Ticket #20
This commit is contained in:
Pavel Zuna 2010-10-01 12:35:27 -04:00 committed by Adam Young
parent c53831037c
commit 838c1f2c94

View File

@ -345,6 +345,19 @@ class LDAPQuery(CallbackInterface, crud.PKQuery):
yield self.obj.primary_key.clone(attribute=True, query=True) yield self.obj.primary_key.clone(attribute=True, query=True)
class LDAPMultiQuery(LDAPQuery):
"""
Base class for commands that need to retrieve one or more existing entries.
"""
def get_args(self):
for key in self.obj.get_ancestor_primary_keys():
yield key
if self.obj.primary_key:
yield self.obj.primary_key.clone(
attribute=True, query=True, multivalue=True
)
class LDAPRetrieve(LDAPQuery): class LDAPRetrieve(LDAPQuery):
""" """
Retrieve an LDAP entry. Retrieve an LDAP entry.
@ -512,7 +525,7 @@ class LDAPUpdate(LDAPQuery, crud.Update):
raise exc raise exc
class LDAPDelete(LDAPQuery): class LDAPDelete(LDAPMultiQuery):
""" """
Delete an LDAP entry and all of its direct subentries. Delete an LDAP entry and all of its direct subentries.
""" """
@ -521,47 +534,66 @@ class LDAPDelete(LDAPQuery):
def execute(self, *keys, **options): def execute(self, *keys, **options):
ldap = self.obj.backend ldap = self.obj.backend
dn = self.obj.get_dn(*keys, **options) def delete_entry(pkey):
nkeys = keys[:-1] + (pkey, )
dn = self.obj.get_dn(*nkeys, **options)
for callback in self.PRE_CALLBACKS: for callback in self.PRE_CALLBACKS:
if hasattr(callback, 'im_self'): if hasattr(callback, 'im_self'):
dn = callback(ldap, dn, *keys, **options) dn = callback(ldap, dn, *nkeys, **options)
else:
dn = callback(self, ldap, dn, *keys, **options)
def delete_subtree(base_dn):
truncated = True
while truncated:
try:
(subentries, truncated) = ldap.find_entries(
None, [''], base_dn, ldap.SCOPE_ONELEVEL
)
except errors.NotFound:
break
else: else:
for (dn_, entry_attrs) in subentries: dn = callback(self, ldap, dn, *nkeys, **options)
delete_subtree(dn_)
try: def delete_subtree(base_dn):
ldap.delete_entry(base_dn, normalize=self.obj.normalize_dn) truncated = True
except errors.ExecutionError, e: while truncated:
try:
(subentries, truncated) = ldap.find_entries(
None, [''], base_dn, ldap.SCOPE_ONELEVEL
)
except errors.NotFound:
break
else:
for (dn_, entry_attrs) in subentries:
delete_subtree(dn_)
try: try:
self._call_exc_callbacks( ldap.delete_entry(base_dn, normalize=self.obj.normalize_dn)
keys, options, e, ldap.delete_entry, base_dn, except errors.ExecutionError, e:
normalize=self.obj.normalize_dn try:
) self._call_exc_callbacks(
except errors.NotFound: nkeys, options, e, ldap.delete_entry, base_dn,
self.obj.handle_not_found(*keys) normalize=self.obj.normalize_dn
)
except errors.NotFound:
self.obj.handle_not_found(*nkeys)
delete_subtree(dn) delete_subtree(dn)
for callback in self.POST_CALLBACKS: for callback in self.POST_CALLBACKS:
if hasattr(callback, 'im_self'): if hasattr(callback, 'im_self'):
result = callback(ldap, dn, *keys, **options) result = callback(ldap, dn, *nkeys, **options)
else:
result = callback(self, ldap, dn, *nkeys, **options)
return result
if not self.obj.primary_key or not isinstance(keys[-1], (list, tuple)):
keys = keys[:-1] + (keys[-1], )
deleted = []
failed = []
result = True
for pkey in keys[-1]:
try:
if not delete_entry(pkey):
result = False
except errors.ExecutionError:
failed.append(pkey)
else: else:
result = callback(self, ldap, dn, *keys, **options) deleted.append(pkey)
if self.obj.primary_key and keys[-1] is not None: if self.obj.primary_key and keys[-1] is not None:
return dict(result=result, value=keys[-1]) return dict(result=result, value=u','.join(deleted))
return dict(result=result, value=u'') return dict(result=result, value=u'')
def pre_callback(self, ldap, dn, *keys, **options): def pre_callback(self, ldap, dn, *keys, **options):