[Commits] (vajda) - added Item.onItemDelete() hook
commits at osafoundation.org
commits at osafoundation.org
Wed Feb 2 12:15:55 PST 2005
Commit by: vajda
Modified files:
chandler/repository/item/Item.py 1.192 1.193
chandler/repository/item/ItemError.py 1.5 1.6
chandler/repository/item/Monitors.py 1.7 1.8
chandler/repository/schema/Cloud.py 1.22 1.23
chandler/repository/tests/TestDelete.py 1.2 1.3
Log message:
- added Item.onItemDelete() hook
- first pass at cloud-based deletion
ViewCVS links:
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/Item.py.diff?r1=text&tr1=1.192&r2=text&tr2=1.193
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/ItemError.py.diff?r1=text&tr1=1.5&r2=text&tr2=1.6
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/Monitors.py.diff?r1=text&tr1=1.7&r2=text&tr2=1.8
http://cvs.osafoundation.org/index.cgi/chandler/repository/schema/Cloud.py.diff?r1=text&tr1=1.22&r2=text&tr2=1.23
http://cvs.osafoundation.org/index.cgi/chandler/repository/tests/TestDelete.py.diff?r1=text&tr1=1.2&r2=text&tr2=1.3
Index: chandler/repository/schema/Cloud.py
diff -u chandler/repository/schema/Cloud.py:1.22 chandler/repository/schema/Cloud.py:1.23
--- chandler/repository/schema/Cloud.py:1.22 Fri Jan 21 11:16:07 2005
+++ chandler/repository/schema/Cloud.py Wed Feb 2 12:15:52 2005
@@ -1,12 +1,13 @@
-__revision__ = "$Revision: 1.22 $"
-__date__ = "$Date: 2005/01/21 19:16:07 $"
+__revision__ = "$Revision: 1.23 $"
+__date__ = "$Date: 2005/02/02 20:15:52 $"
__copyright__ = "Copyright (c) 2004 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
import re
from repository.item.Item import Item
+from repository.item.ItemError import RecursiveDeleteError
from repository.item.RefCollections import RefList
from repository.item.PersistentCollections import PersistentCollection
from repository.remote.CloudFilter import CloudFilter, EndpointFilter
@@ -161,6 +162,54 @@
return results
+ def deleteItems(self, item, recursive=False, cloudAlias=None):
+ """
+ Delete all items in the cloud.
+
+ Items are first gathered as documented in L{getItems}. They are then
+ deleted as follows:
+
+ - items in the result set returned by L{getItems} are deleted.
+
+ - references to items in the C{references} dictionary upon
+ returning from L{getItems}, that is, references to items that
+ are not considered part of the cloud but are nonetheless
+ referenced by items in it are removed.
+
+ It is an error to delete an item with children unless C{recursive}
+ is set to C{True}.
+
+ @param item: the entry point of the cloud.
+ @type item: an C{Item<repository.item.Item.Item>} instance
+ @param recursive: C{True} to recursively delete the items' children
+ too, C{False} otherwise (the default).
+ @type recursive: boolean
+ @param cloudAlias: the optional alias name to use for C{byCloud}
+ policy endpoints where the cloud is unspecified.
+ @type cloudAlias: a string
+ @return: the list of all item copies considered part of the cloud.
+ """
+
+ items = {}
+ references = {}
+ deleting = self.getItems(item, cloudAlias, items, references)
+
+ def deleteItem(item):
+ if not (item.isDeleted() or item.isDeleting()):
+ if recursive:
+ item.delete(recursive=True, deletePolicy='remove')
+ else:
+ if item.hasChildren():
+ for child in item.iterChildren():
+ if child._uuid in items:
+ deleteItem(child)
+ else:
+ raise RecursiveDeleteError, item
+ item.delete(deletePolicy='remove')
+
+ for item in deleting:
+ deleteItem(item)
+
def getAttributeEndpoints(self, attrName, index=0, cloudAlias=None):
endpoints = []
Index: chandler/repository/item/ItemError.py
diff -u chandler/repository/item/ItemError.py:1.5 chandler/repository/item/ItemError.py:1.6
--- chandler/repository/item/ItemError.py:1.5 Tue Jan 11 14:11:59 2005
+++ chandler/repository/item/ItemError.py Wed Feb 2 12:15:52 2005
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.5 $"
-__date__ = "$Date: 2005/01/11 22:11:59 $"
+__revision__ = "$Revision: 1.6 $"
+__date__ = "$Date: 2005/02/02 20:15:52 $"
__copyright__ = "Copyright (c) 2003-2004 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -55,6 +55,13 @@
self.args[1])
+class RecursiveDeleteError(ValueError, ItemError):
+ 'Item %s has children, delete must be recursive'
+
+ def __str__(self):
+ return self.__doc__ %(self.getItem()._repr_())
+
+
class NoSuchItemInCollectionError(ValueError, ItemError):
"Item %s: no item %s in collection on attribute '%s'"
Index: chandler/repository/item/Monitors.py
diff -u chandler/repository/item/Monitors.py:1.7 chandler/repository/item/Monitors.py:1.8
--- chandler/repository/item/Monitors.py:1.7 Fri Jan 28 15:45:11 2005
+++ chandler/repository/item/Monitors.py Wed Feb 2 12:15:52 2005
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.7 $"
-__date__ = "$Date: 2005/01/28 23:45:11 $"
+__revision__ = "$Revision: 1.8 $"
+__date__ = "$Date: 2005/02/02 20:15:52 $"
__copyright__ = "Copyright (c) 2004 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -13,11 +13,8 @@
if not view.isRefCounted():
self.setPinned()
- Monitors.instances[view] = self
- if 'monitoring' not in self._values:
- self.setAttributeValue('monitoring', { 'set': {} },
- _attrDict=self._values)
+ Monitors.instances[view] = self
def getInstance(cls, view):
@@ -73,4 +70,4 @@
# recursive import prevention
#
-Item._invokeMonitors = Monitors.invoke
+Item._monitorsClass = Monitors
Index: chandler/repository/item/Item.py
diff -u chandler/repository/item/Item.py:1.192 chandler/repository/item/Item.py:1.193
--- chandler/repository/item/Item.py:1.192 Fri Jan 28 15:45:11 2005
+++ chandler/repository/item/Item.py Wed Feb 2 12:15:52 2005
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.192 $"
-__date__ = "$Date: 2005/01/28 23:45:11 $"
+__revision__ = "$Revision: 1.193 $"
+__date__ = "$Date: 2005/02/02 20:15:52 $"
__copyright__ = "Copyright (c) 2003-2004 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -1267,8 +1267,7 @@
assert attrDict is not None
attrDict._setDirty(attribute)
if not noMonitors:
- # Item._invokeMonitors is defined in Monitors.py
- Item._invokeMonitors('set', self, attribute)
+ Item._monitorsClass.invoke('set', self, attribute)
self._lastAccess = Item._countAccess()
if self._status & Item.DIRTY == 0:
@@ -1406,42 +1405,71 @@
return item
- def delete(self, recursive=False):
+ def delete(self, recursive=False, deletePolicy=None, cloudAlias=None):
"""
Delete this item.
+ By default, an attribute's deletePolicy aspect is C{remove} for
+ bi-directional references.
+
If this item has references to other items and the C{deletePolicy}
aspect of the attributes containing them is C{cascade} then these
- other items are deleted too.
+ other items are deleted too when their count of counted references
+ is zero. References in an attribute are counted when the countPolicy
+ of the attribute is C{count}. It is C{none} by default.
+
+ Attribute delete policies can be overriden with a
+ L{Cloud<repository.schema.Cloud.Cloud>} instance to drive the delete
+ operation by using the C{cloudAlias} argument.
It is an error to delete an item with children unless C{recursive}
is set to C{True}.
+ If this item has an C{onItemDelete} method defined, it is invoked
+ before the item's deletion process is started.
+
+ @param deletePolicy: an optional deletePolicy to override the reference
+ attributes delete policies with.
+ @type deletePolicy: a string
+ @param cloudAlias: the optional alias name of a cloud in the item's
+ kind clouds list.
+ @type cloudAlias: a string
@param recursive: C{True} to recursively delete this item's children
too, C{False} otherwise (the default).
@type recursive: boolean
"""
- if not self._status & (Item.DELETED | Item.DELETING):
+ if cloudAlias is not None:
+ clouds = self._kind.getClouds(cloudAlias)
+ for cloud in clouds:
+ cloud.deleteItems(self, recursive, cloudAlias)
+
+ elif not self._status & (Item.DELETED | Item.DELETING):
if self._status & Item.STALE:
raise StaleItemError, self
if not recursive and self.hasChildren():
- raise ValueError, 'item %s has children, delete must be recursive' %(self)
+ raise RecursiveDeleteError, self
+
+ view = self.getRepositoryView()
+
+ if hasattr(type(self), 'onItemDelete'):
+ self.onItemDelete(view)
self.setDirty(Item.NDIRTY)
self._status |= Item.DELETING
others = []
for child in self.iterChildren():
- child.delete(True)
+ child.delete(recursive=True, deletePolicy=deletePolicy)
self._values.clear()
for name in self._references.keys():
- policy = self.getAttributeAspect(name, 'deletePolicy',
- default='remove')
+ policy = (deletePolicy or
+ self.getAttributeAspect(name, 'deletePolicy',
+ default='remove'))
if policy == 'cascade':
value = self._references._getRef(name)
if value is not None:
@@ -1452,10 +1480,7 @@
self.removeAttributeValue(name, _attrDict=self._references)
- parent = self.itsParent
- view = self.getRepositoryView()
-
- parent._removeItem(self)
+ self.itsParent._removeItem(self)
self._setRoot(None, view)
self._status |= Item.DELETED | Item.STALE
@@ -1463,7 +1488,7 @@
for other in others:
if other.refCount(counted=True) == 0:
- other.delete()
+ other.delete(recursive=recursive, deletePolicy=deletePolicy)
self._kind = None
Index: chandler/repository/tests/TestDelete.py
diff -u chandler/repository/tests/TestDelete.py:1.2 chandler/repository/tests/TestDelete.py:1.3
--- chandler/repository/tests/TestDelete.py:1.2 Sat Jan 15 22:12:52 2005
+++ chandler/repository/tests/TestDelete.py Wed Feb 2 12:15:53 2005
@@ -2,8 +2,8 @@
Test deletion of items
"""
-__revision__ = "$Revision: 1.2 $"
-__date__ = "$Date: 2005/01/16 06:12:52 $"
+__revision__ = "$Revision: 1.3 $"
+__date__ = "$Date: 2005/02/02 20:15:53 $"
__copyright__ = "Copyright (c) 2003-2004 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -29,6 +29,7 @@
def testDeleteItemsInCollection(self):
tools.timing.reset()
+
self._reopenRepository()
k = self.rep.findPath('//CineGuide/KHepburn')
for m in k.movies:
@@ -44,6 +45,20 @@
tools.timing.results(verbose=False)
+ def testCloudDelete(self):
+
+ tools.timing.reset()
+
+ k = self.rep.findPath('//CineGuide/KHepburn')
+ k.delete(cloudAlias='remote')
+ self.rep.commit()
+ self.rep.check()
+ self._reopenRepository()
+ self.rep.check()
+
+ tools.timing.results(verbose=False)
+
+
if __name__ == "__main__":
# import hotshot
# profiler = hotshot.Profile('/tmp/TestItems.hotshot')
More information about the Commits
mailing list