[Commits] (vajda) - moved alias functionality from RefDict to
LinkedMap
commits at osafoundation.org
commits at osafoundation.org
Thu Sep 2 10:34:30 PDT 2004
Commit by: vajda
Modified files:
chandler/repository/item/Item.py 1.156 1.157
chandler/repository/item/ItemHandler.py 1.45 1.46
chandler/repository/item/ItemRef.py 1.88 1.89
chandler/repository/item/Values.py 1.16 1.17
chandler/repository/persistence/FileRepository.py 1.29 1.30
chandler/repository/persistence/PackHandler.py 1.16 1.17
chandler/repository/persistence/Repository.py 1.81 1.82
chandler/repository/persistence/RepositoryError.py 1.2 1.3
chandler/repository/persistence/RepositoryView.py 1.6 1.7
chandler/repository/persistence/XMLRefDict.py 1.3 1.4
chandler/repository/persistence/XMLRepository.py 1.79 1.80
chandler/repository/persistence/XMLRepositoryView.py 1.52 1.53
chandler/repository/remote/RemoteRepository.py 1.3 1.4
chandler/repository/tests/RepositoryTestCase.py 1.13 1.14
chandler/repository/tests/TestItems.py 1.11 1.12
chandler/repository/tests/TestMove.py 1.1 1.2
chandler/repository/tests/TestRepository.py 1.8 1.9
chandler/repository/util/LinkedMap.py 1.13 1.14
chandler/repository/util/SAX.py 1.4 1.5
Log message:
- moved alias functionality from RefDict to LinkedMap
- roots, children and ref collections now use same storage
- eliminated SDIRTY bit, introduced NDIRTY bit
ViewCVS links:
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/Item.py.diff?r1=text&tr1=1.156&r2=text&tr2=1.157
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/ItemHandler.py.diff?r1=text&tr1=1.45&r2=text&tr2=1.46
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/ItemRef.py.diff?r1=text&tr1=1.88&r2=text&tr2=1.89
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/Values.py.diff?r1=text&tr1=1.16&r2=text&tr2=1.17
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/FileRepository.py.diff?r1=text&tr1=1.29&r2=text&tr2=1.30
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/PackHandler.py.diff?r1=text&tr1=1.16&r2=text&tr2=1.17
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/Repository.py.diff?r1=text&tr1=1.81&r2=text&tr2=1.82
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/RepositoryError.py.diff?r1=text&tr1=1.2&r2=text&tr2=1.3
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/RepositoryView.py.diff?r1=text&tr1=1.6&r2=text&tr2=1.7
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/XMLRefDict.py.diff?r1=text&tr1=1.3&r2=text&tr2=1.4
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/XMLRepository.py.diff?r1=text&tr1=1.79&r2=text&tr2=1.80
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/XMLRepositoryView.py.diff?r1=text&tr1=1.52&r2=text&tr2=1.53
http://cvs.osafoundation.org/index.cgi/chandler/repository/remote/RemoteRepository.py.diff?r1=text&tr1=1.3&r2=text&tr2=1.4
http://cvs.osafoundation.org/index.cgi/chandler/repository/tests/RepositoryTestCase.py.diff?r1=text&tr1=1.13&r2=text&tr2=1.14
http://cvs.osafoundation.org/index.cgi/chandler/repository/tests/TestItems.py.diff?r1=text&tr1=1.11&r2=text&tr2=1.12
http://cvs.osafoundation.org/index.cgi/chandler/repository/tests/TestMove.py.diff?r1=text&tr1=1.1&r2=text&tr2=1.2
http://cvs.osafoundation.org/index.cgi/chandler/repository/tests/TestRepository.py.diff?r1=text&tr1=1.8&r2=text&tr2=1.9
http://cvs.osafoundation.org/index.cgi/chandler/repository/util/LinkedMap.py.diff?r1=text&tr1=1.13&r2=text&tr2=1.14
http://cvs.osafoundation.org/index.cgi/chandler/repository/util/SAX.py.diff?r1=text&tr1=1.4&r2=text&tr2=1.5
Index: chandler/repository/tests/RepositoryTestCase.py
diff -u chandler/repository/tests/RepositoryTestCase.py:1.13 chandler/repository/tests/RepositoryTestCase.py:1.14
--- chandler/repository/tests/RepositoryTestCase.py:1.13 Wed Sep 1 15:35:32 2004
+++ chandler/repository/tests/RepositoryTestCase.py Thu Sep 2 10:34:26 2004
@@ -1,8 +1,8 @@
"""
A base class for repository testing
"""
-__revision__ = "$Revision: 1.13 $"
-__date__ = "$Date: 2004/09/01 22:35:32 $"
+__revision__ = "$Revision: 1.14 $"
+__date__ = "$Date: 2004/09/02 17:34:26 $"
__copyright__ = "Copyright (c) 2003 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -99,7 +99,7 @@
# Repository specific assertions
def assertIsRoot(self, item):
- self.assert_(item in self.rep.getRoots())
+ self.assert_(item in list(self.rep.iterRoots()))
def assertItemPathEqual(self, item, string):
self.assertEqual(str(item.itsPath), string)
Index: chandler/repository/item/Values.py
diff -u chandler/repository/item/Values.py:1.16 chandler/repository/item/Values.py:1.17
--- chandler/repository/item/Values.py:1.16 Mon Aug 30 14:27:15 2004
+++ chandler/repository/item/Values.py Thu Sep 2 10:34:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.16 $"
-__date__ = "$Date: 2004/08/30 21:27:15 $"
+__revision__ = "$Revision: 1.17 $"
+__date__ = "$Date: 2004/09/02 17:34:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -252,6 +252,20 @@
value._xmlValue(key, item, generator, withSchema, version,
attrs, mode)
+ def _clearDirties(self):
+
+ try:
+ for key, flags in self._flags.iteritems():
+ if flags & Values.DIRTY:
+ self._flags[key] &= ~Values.DIRTY
+
+ value = self.get(key)
+ if value is not None:
+ value._clearDirties()
+
+ except AttributeError:
+ pass
+
def _isRefDict(self):
return False
Index: chandler/repository/persistence/RepositoryError.py
diff -u chandler/repository/persistence/RepositoryError.py:1.2 chandler/repository/persistence/RepositoryError.py:1.3
--- chandler/repository/persistence/RepositoryError.py:1.2 Mon Aug 30 14:27:16 2004
+++ chandler/repository/persistence/RepositoryError.py Thu Sep 2 10:34:26 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.2 $"
-__date__ = "$Date: 2004/08/30 21:27:16 $"
+__revision__ = "$Revision: 1.3 $"
+__date__ = "$Date: 2004/09/02 17:34:26 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -26,3 +26,10 @@
def __str__(self):
return self.__doc__ % self.args
+
+
+class MergeError(VersionConflictError):
+ "(%s) merging %s failed because %s"
+
+ def __str__(self):
+ return self.__doc__ % self.args
Index: chandler/repository/persistence/Repository.py
diff -u chandler/repository/persistence/Repository.py:1.81 chandler/repository/persistence/Repository.py:1.82
--- chandler/repository/persistence/Repository.py:1.81 Wed Aug 25 18:00:52 2004
+++ chandler/repository/persistence/Repository.py Thu Sep 2 10:34:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.81 $"
-__date__ = "$Date: 2004/08/26 01:00:52 $"
+__revision__ = "$Revision: 1.82 $"
+__date__ = "$Date: 2004/09/02 17:34:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -224,14 +224,14 @@
Iterate over the roots of this repository using the current view.
"""
- return self.iterChildren()
-
- def iterChildren(self, load=True):
+ return self.view.__iter__()
+
+ def iterRoots(self, load=True):
"""
Iterate over the roots of this repository using the current view.
"""
- return self.view.iterChildren(load)
+ return self.view.iterRoots(load)
def isOpen(self):
"""
@@ -251,7 +251,7 @@
for more details.
"""
- return self.getRoot(name, load) is not None
+ return self.view.hasRoot(name, load)
def getRoot(self, name, load=True):
"""
@@ -268,17 +268,6 @@
return self.view.__getitem__(key)
- def getRoots(self, load=True):
- """
- Get all roots in the repository.
-
- See L{RepositoryView.getRoots
- <repository.persistence.RepositoryView.RepositoryView.getRoots>}
- for more details.
- """
-
- return self.view.getRoots(load)
-
def walk(self, path, callable, _index=0, **kwds):
"""
Walk a path in the current view and invoke a callable along the way.
@@ -468,9 +457,6 @@
def serveItem(self, version, uuid):
raise NotImplementedError, "%s.serveItem" %(type(self))
- def loadChild(self, version, uuid, name):
- raise NotImplementedError, "%s.loadChild" %(type(self))
-
def serveChild(self, version, uuid, name):
raise NotImplementedError, "%s.serveChild" %(type(self))
Index: chandler/repository/tests/TestItems.py
diff -u chandler/repository/tests/TestItems.py:1.11 chandler/repository/tests/TestItems.py:1.12
--- chandler/repository/tests/TestItems.py:1.11 Mon Jun 7 23:59:09 2004
+++ chandler/repository/tests/TestItems.py Thu Sep 2 10:34:26 2004
@@ -2,8 +2,8 @@
Basic Unit tests for Chandler repository
"""
-__revision__ = "$Revision: 1.11 $"
-__date__ = "$Date: 2004/06/08 06:59:09 $"
+__revision__ = "$Revision: 1.12 $"
+__date__ = "$Date: 2004/09/02 17:34:26 $"
__copyright__ = "Copyright (c) 2003 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -49,7 +49,7 @@
# Test to see that item became a respository root
self.rep.commit()
- roots = self.rep.getRoots()
+ roots = list(self.rep.iterRoots())
self.assert_(item in roots)
self.failIf(item.isDirty())
@@ -152,7 +152,7 @@
child2 = item['child2']
child3 = self.rep['child3']
- self.assert_(child3 in self.rep.getRoots())
+ self.assert_(child3 in list(self.rep.iterRoots()))
self.assertItemPathEqual(child3, '//child3')
self.assertIsRoot(child3.itsRoot)
Index: chandler/repository/persistence/FileRepository.py
diff -u chandler/repository/persistence/FileRepository.py:1.29 chandler/repository/persistence/FileRepository.py:1.30
--- chandler/repository/persistence/FileRepository.py:1.29 Thu Aug 19 11:06:29 2004
+++ chandler/repository/persistence/FileRepository.py Thu Sep 2 10:34:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.29 $"
-__date__ = "$Date: 2004/08/19 18:06:29 $"
+__revision__ = "$Revision: 1.30 $"
+__date__ = "$Date: 2004/09/02 17:34:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -94,9 +94,6 @@
def _loadItem(self, uuid):
return None
- def _loadChild(self, parent, name):
- return None
-
def purge(self):
'Purge the repository directory tree of all item files that do not correspond to currently existing items in the repository.'
Index: chandler/repository/persistence/PackHandler.py
diff -u chandler/repository/persistence/PackHandler.py:1.16 chandler/repository/persistence/PackHandler.py:1.17
--- chandler/repository/persistence/PackHandler.py:1.16 Sun May 30 12:28:57 2004
+++ chandler/repository/persistence/PackHandler.py Thu Sep 2 10:34:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.16 $"
-__date__ = "$Date: 2004/05/30 19:28:57 $"
+__revision__ = "$Revision: 1.17 $"
+__date__ = "$Date: 2004/09/02 17:34:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -148,6 +148,7 @@
for item in items:
item._status |= item.NEW
+ item.setDirty(item.NDIRTY, None)
return items[0]
Index: chandler/repository/persistence/XMLRepository.py
diff -u chandler/repository/persistence/XMLRepository.py:1.79 chandler/repository/persistence/XMLRepository.py:1.80
--- chandler/repository/persistence/XMLRepository.py:1.79 Mon Aug 30 14:27:16 2004
+++ chandler/repository/persistence/XMLRepository.py Thu Sep 2 10:34:26 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.79 $"
-__date__ = "$Date: 2004/08/30 21:27:16 $"
+__revision__ = "$Revision: 1.80 $"
+__date__ = "$Date: 2004/09/02 17:34:26 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -205,14 +205,6 @@
return None
- def loadChild(self, version, uuid, name):
-
- uuid = self.store.readName(version, uuid, name)
- if uuid is None:
- return None
-
- return self.loadItem(version, uuid)
-
def queryItems(self, version, query):
store = self.store
@@ -245,10 +237,6 @@
return results
- def deleteDocument(self, doc):
-
- self._xml.deleteDocument(self.store.txn, doc, self.store.updateCtx)
-
def getDocument(self, docId):
return self._xml.getDocument(self.store.txn, docId, DB_DIRTY_READ)
@@ -364,10 +352,6 @@
return self._data.loadItem(version, uuid)
- def loadChild(self, version, uuid, name):
-
- return self._data.loadChild(version, uuid, name)
-
def loadRef(self, version, uItem, uuid, key):
buffer = self._refs.prepareKey(uItem, uuid)
@@ -550,7 +534,7 @@
self.repository._env.lock_put(lock)
return None
- def saveItem(self, xml, uuid, version, currPN, origPN, status,
+ def saveItem(self, xml, uuid, version, parent, status,
dirtyValues, dirtyRefs):
doc = XmlDocument()
@@ -566,24 +550,15 @@
raise
if status & Item.DELETED:
- parent, name = origPN
self._versions.setDocVersion(uuid, version, 0)
self._history.writeVersion(uuid, version, 0, status,
parent, [], [])
- self.writeName(version, parent, name, None)
else:
self._versions.setDocVersion(uuid, version, docId)
self._history.writeVersion(uuid, version, docId, status,
None, dirtyValues, dirtyRefs)
- if origPN is not None:
- parent, name = origPN
- self.writeName(version, parent, name, None)
-
- parent, name = currPN
- self.writeName(version, parent, name, uuid)
-
def serveItem(self, version, uuid):
if version == 0:
Index: chandler/repository/item/ItemHandler.py
diff -u chandler/repository/item/ItemHandler.py:1.45 chandler/repository/item/ItemHandler.py:1.46
--- chandler/repository/item/ItemHandler.py:1.45 Sun Aug 29 19:50:28 2004
+++ chandler/repository/item/ItemHandler.py Thu Sep 2 10:34:25 2004
@@ -1,11 +1,9 @@
-__revision__ = "$Revision: 1.45 $"
-__date__ = "$Date: 2004/08/30 02:50:28 $"
+__revision__ = "$Revision: 1.46 $"
+__date__ = "$Date: 2004/09/02 17:34:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
-import repository.item as ItemPackage
-
from repository.item.PersistentCollections import PersistentCollection
from repository.item.PersistentCollections import PersistentList
from repository.item.PersistentCollections import PersistentDict
@@ -146,18 +144,19 @@
self.cls = None
self.kindRef = None
self.parentRef = None
- self.previous = self.next = None
- self.first = self.last = None
+ self.isContainer = False
self.withSchema = attrs.get('withSchema', 'False') == 'True'
self.uuid = UUID(attrs.get('uuid'))
self.version = long(attrs.get('version', '0L'))
def itemEnd(self, itemHandler, attrs):
+ from repository.item.Item import Item
+
cls = self.cls
if cls is None:
if self.kind is None:
- cls = ItemPackage.Item.Item
+ cls = Item
else:
cls = self.kind.getItemClass()
@@ -174,17 +173,14 @@
item._fillItem(self.name, self.parent, self.kind, uuid = self.uuid,
values = self.values, references = self.references,
- previous = self.previous, next = self.next,
afterLoadHooks = self.afterLoadHooks,
version = self.version)
+ if self.isContainer:
+ item._children = self.repository._createChildren(item)
+
if pinned:
item._status |= item.PINNED
- if self.first or self.last:
- item._children = ItemPackage.Item.Children(item)
- item._children._firstKey = self.first
- item._children._lastKey = self.last
-
self.repository._registerItem(item)
for attribute, value in self.values.iteritems():
@@ -239,22 +235,9 @@
else:
self.parentRef = Path(self.data)
+ self.isContainer = attrs.get('container', 'False') == 'True'
self.parent = self.repository.find(self.parentRef)
- if self.parent is None:
- if self.afterLoadHooks is not None:
- self.afterLoadHooks.append(self._move)
- else:
- raise ValueError, "Parent %s not found" %(self.parentRef)
-
- def containerEnd(self, itemHandler, attrs):
-
- self.parentRef = UUID(self.data)
- self.previous = attrs.get('previous')
- self.next = attrs.get('next')
- self.first = attrs.get('first')
- self.last = attrs.get('last')
- self.parent = self.repository.find(self.parentRef)
if self.parent is None:
if self.afterLoadHooks is not None:
self.afterLoadHooks.append(self._move)
@@ -268,7 +251,7 @@
if self.parent is None:
raise ValueError, 'Parent %s not found' %(self.parentRef)
else:
- self.item.move(self.parent, self.previous, self.next)
+ self.item.move(self.parent)
def classEnd(self, itemHandler, attrs):
@@ -598,10 +581,13 @@
generator.startElement(tag, attrs)
if attrCard == 'single':
- if isinstance(value, ItemPackage.Item.Item):
+
+ from repository.item.Item import Item
+
+ if isinstance(value, Item):
raise TypeError, "item %s cannot be stored as a literal value" %(value.itsPath)
- if value is ItemPackage.Item.Item.Nil:
+ if value is Item.Nil:
raise ValueError, 'Cannot persist Item.Nil'
if attrType is not None:
Index: chandler/repository/item/ItemRef.py
diff -u chandler/repository/item/ItemRef.py:1.88 chandler/repository/item/ItemRef.py:1.89
--- chandler/repository/item/ItemRef.py:1.88 Thu Aug 26 12:25:03 2004
+++ chandler/repository/item/ItemRef.py Thu Sep 2 10:34:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.88 $"
-__date__ = "$Date: 2004/08/26 19:25:03 $"
+__revision__ = "$Revision: 1.89 $"
+__date__ = "$Date: 2004/09/02 17:34:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -34,6 +34,9 @@
return '<ItemRef: %s - %s>' %(self._item, self._other)
+ def _clearDirties(self):
+ pass
+
def _setItem(self, item):
pass
@@ -481,13 +484,6 @@
items.
"""
- class link(LinkedMap.link):
-
- def __init__(self, value):
-
- super(RefDict.link, self).__init__(value)
- self._alias = None
-
def __init__(self, item, name, otherName, readOnly=False):
"""
The constructor for this class. A RefDict should not be instantiated
@@ -499,7 +495,6 @@
self._otherName = otherName
self._setItem(item)
self._count = 0
- self._aliases = None
self._readOnly = readOnly
self._indexes = None
self._flags = RefDict.SETDIRTY
@@ -797,21 +792,15 @@
value = ItemRef(self._getItem(), self._name,
value, self._otherName)
- link = super(RefDict, self).__setitem__(key, value,
- previousKey, nextKey)
+ super(RefDict, self).__setitem__(key, value,
+ previousKey, nextKey, alias)
+
if not loading:
self._count += 1
if self._indexes:
for index in self._indexes.itervalues():
index.insertKey(key, previousKey)
- if alias:
- link._alias = alias
- if self._aliases is None:
- self._aliases = { alias: key }
- else:
- self._aliases[alias] = key
-
return value
def placeItem(self, item, after, indexName=None):
@@ -879,13 +868,9 @@
value.detach(self._item, self._name,
value.other(self._item), self._otherName)
- link = super(RefDict, self).__delitem__(key)
- if link._alias is not None:
- del self._aliases[link._alias]
-
self._count -= 1
- return link
+ return super(RefDict, self).__delitem__(key)
def _load(self, key):
@@ -954,52 +939,6 @@
return default
- def getByAlias(self, alias, default=None, load=True):
- """
- Get the item referenced through its alias.
-
- @param alias: the alias of the item referenced.
- @type key: a string
- @param default: the default value to return if there is no reference
- for C{key} in this ref collection, C{None} by default.
- @type default: anything
- @param load: if the reference exists but hasn't been loaded yet,
- this method will return C{default} if this parameter is C{False}.
- @type load: boolean
- @return: an C{Item} instance or C{default}
- """
-
- key = None
-
- if self._aliases is not None:
- key = self._aliases.get(alias)
-
- if key is None and load:
- key = self.resolveAlias(alias, load)
-
- if key is None:
- return default
-
- return self.get(key, default, load)
-
- def resolveAlias(self, alias, load=True):
- """
- Resolve the alias to its corresponding reference key.
-
- @param alias: the alias to resolve.
- @type alias: a string
- @param load: if the reference exists but hasn't been loaded yet,
- this method will return C{None} if this parameter is C{False}.
- @type load: boolean
- @return: a L{UUID<repository.util.UUID.UUID>} or C{None} if the
- alias does not exist.
- """
-
- if self._aliases:
- return self._aliases.get(alias)
-
- return None
-
def getAlias(self, item):
"""
Get the alias this item is keyed on in this collection.
@@ -1276,6 +1215,9 @@
return True
+ def _clearDirties(self):
+ pass
+
SETDIRTY = 0x0001
Index: chandler/repository/persistence/XMLRepositoryView.py
diff -u chandler/repository/persistence/XMLRepositoryView.py:1.52 chandler/repository/persistence/XMLRepositoryView.py:1.53
--- chandler/repository/persistence/XMLRepositoryView.py:1.52 Mon Aug 30 17:19:56 2004
+++ chandler/repository/persistence/XMLRepositoryView.py Thu Sep 2 10:34:26 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.52 $"
-__date__ = "$Date: 2004/08/31 00:19:56 $"
+__revision__ = "$Revision: 1.53 $"
+__date__ = "$Date: 2004/09/02 17:34:26 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -18,7 +18,7 @@
from repository.persistence.Repository import Repository
from repository.persistence.Repository import RepositoryNotifications
from repository.persistence.XMLLob import XMLText, XMLBinary
-from repository.persistence.XMLRefDict import XMLRefDict
+from repository.persistence.XMLRefDict import XMLRefDict, XMLChildren
from repository.util.SAX import XMLGenerator
timing = False
@@ -66,11 +66,13 @@
for item in self._log:
if not item.isNew():
self.logger.debug('reloading version %d of %s',
- self.version, item)
+ self._version, item)
self._loadItem(item._uuid, instance=item)
del self._log[:]
- self._notRoots.clear()
+ if self._dirty:
+ self._roots._clearDirties()
+ self._dirty = 0
self.prune(10000)
@@ -79,7 +81,7 @@
store = self.repository.store
items = []
- for doc in store.queryItems(self.version, query):
+ for doc in store.queryItems(self._version, query):
uuid = store.getDocUUID(doc)
if not uuid in self._deletedRegistry:
# load and doc, trick to pass doc directly to find
@@ -93,7 +95,7 @@
store = self.repository.store
results = []
- docs = store.searchItems(self.version, query)
+ docs = store.searchItems(self._version, query)
for (uuid, (ver, attribute)) in docs.iteritems():
if not uuid in self._deletedRegistry:
item = self.find(uuid, load=load)
@@ -109,6 +111,10 @@
else:
return TransientRefDict(item, name, otherName, readOnly)
+ def _createChildren(self, parent):
+
+ return XMLChildren(self, parent)
+
def _getLobType(self, mode):
if mode == 'text':
@@ -188,13 +194,15 @@
ood[uuid] = item
if ood:
- self._mergeItems(ood, self.version, newVersion,
+ self._mergeItems(ood, self._version, newVersion,
history)
for item in self._log:
size += self._saveItem(item, newVersion, store, ood)
+ if self._dirty:
+ self._roots._saveValues(newVersion)
- if newVersion > self.version:
+ if newVersion > self._version:
histNotifications = RepositoryNotifications()
def unload(uuid, version, docId, status, parent, dirties):
@@ -215,7 +223,7 @@
item._version < newVersion):
unloads[item._uuid] = item
- history.apply(unload, self.version, newVersion)
+ history.apply(unload, self._version, newVersion)
if txnStarted:
self._commitTransaction()
@@ -244,6 +252,7 @@
raise
if self._log:
+
for item in self._log:
if not item._status & Item.MERGED:
item._version = newVersion
@@ -251,10 +260,14 @@
item._status &= ~(Item.NEW | Item.MERGED | Item.SAVED)
del self._log[:]
- if newVersion > self.version:
+ if self._dirty:
+ self._roots._clearDirties()
+ self._dirty = 0
+
+ if newVersion > self._version:
self.logger.debug('refreshing view from version %d to %d',
- self.version, newVersion)
- self.version = newVersion
+ self._version, newVersion)
+ self._version = newVersion
for item in unloads.itervalues():
self.logger.debug('unloading version %d of %s',
item._version, item)
@@ -265,8 +278,6 @@
newVersion, item)
self._loadItem(item._uuid, instance=item)
- self._notRoots.clear()
-
after = datetime.now()
if count > 0:
self.logger.info('%s committed %d items (%ld bytes) in %s',
@@ -318,14 +329,8 @@
xml = out.getvalue()
out.close()
- if '_origName' in item.__dict__:
- origPN = item.__dict__['_origName']
- del item.__dict__['_origName']
- else:
- origPN = None
-
- store.saveItem(xml, uuid, newVersion,
- (item.itsParent.itsUUID, item._name), origPN,
+ parent = item.itsParent.itsUUID
+ store.saveItem(xml, uuid, newVersion, parent,
item._status & Item.SAVEMASK,
item._values._getDirties(),
item._references._getDirties())
@@ -335,7 +340,7 @@
store.saveACL(newVersion, uuid, name, acl)
if isDeleted:
- self._notifications.changed(uuid, 'deleted', parent=origPN[0])
+ self._notifications.changed(uuid, 'deleted', parent=parent)
elif isNew:
self._notifications.changed(uuid, 'added')
else:
@@ -353,11 +358,9 @@
if newDirty & oldDirty:
raise VersionConflictError, (item, newDirty, oldDirty)
else:
- if (newDirty == item.VDIRTY or oldDirty == item.VDIRTY or
- newDirty == item.RDIRTY or oldDirty == item.RDIRTY or
- newDirty == item.VRDIRTY or oldDirty == item.VRDIRTY):
+ if newDirty == item.VDIRTY or oldDirty == item.VDIRTY:
items[uuid] = (docId, oldDirty, newDirty)
else:
- raise NotImplementedError, 'Item %s may be mergeable but this particular merge (0x%x:0x%x) is not implemented yet' %(item.itsPath, newDirty, oldDirty)
+ raise NotImplementedError, 'Item %s may be mergeable but this particular merge (0x%x:0x%x) is not implemented yet' %(item.itsPath, newDirty, oldDirty)
history.apply(check, oldVersion, newVersion)
Index: chandler/repository/persistence/XMLRefDict.py
diff -u chandler/repository/persistence/XMLRefDict.py:1.3 chandler/repository/persistence/XMLRefDict.py:1.4
--- chandler/repository/persistence/XMLRefDict.py:1.3 Thu Aug 19 11:06:29 2004
+++ chandler/repository/persistence/XMLRefDict.py Thu Sep 2 10:34:26 2004
@@ -1,11 +1,12 @@
-__revision__ = "$Revision: 1.3 $"
-__date__ = "$Date: 2004/08/19 18:06:29 $"
+__revision__ = "$Revision: 1.4 $"
+__date__ = "$Date: 2004/09/02 17:34:26 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
from cStringIO import StringIO
+from repository.item.Item import Children
from repository.item.ItemRef import RefDict
from repository.item.Indexes import NumericIndex
from repository.util.UUID import UUID
@@ -50,14 +51,18 @@
super(XMLRefDict, self)._changeRef(key, alias, noMonitors)
if not self.view.isLoading():
- self._changedRefs[key] = (0, alias)
+ op, alias = self._changedRefs.get(key, (1, alias))
+ if op != 0:
+ self._changedRefs[key] = (0, alias)
def _removeRef(self, key, _detach=False):
link = super(XMLRefDict, self)._removeRef(key, _detach)
if not self.view.isLoading():
- self._changedRefs[key] = (1, link._alias)
+ op, alias = self._changedRefs.get(key, (0, link._alias))
+ if op != 1:
+ self._changedRefs[key] = (1, alias)
else:
raise ValueError, 'detach during load'
@@ -84,8 +89,12 @@
if load and key is None:
view = self.view
- key = view.repository.store.readName(view.version, self._uuid,
+ key = view.repository.store.readName(view._version, self._uuid,
alias)
+ if key is not None:
+ op, oldAlias = self._changedRefs.get(key, (0, None))
+ if oldAlias == alias:
+ key = None
return key
@@ -122,7 +131,7 @@
alias = value._alias
self._writeRef(key, version, previous, next, alias)
- if oldAlias is not None:
+ if oldAlias is not None and oldAlias != alias:
store.writeName(version, self._uuid, oldAlias,
None)
if alias is not None:
@@ -132,7 +141,8 @@
elif op == 1: # remove
self._deleteRef(key, version)
if oldAlias is not None:
- store.writeName(version, key, oldAlias, None)
+ store.writeName(version, self._uuid, oldAlias,
+ None)
else: # error
raise ValueError, op
@@ -140,8 +150,6 @@
if self._changedRefs:
self.view._notifications.changed(self._item._uuid, self._name)
- self._changedRefs.clear()
-
if len(self) > 0:
generator.startElement('db', {})
generator.characters(self._uuid.str64())
@@ -158,6 +166,13 @@
else:
raise ValueError, mode
+ def _clearDirties(self):
+
+ self._changedRefs.clear()
+ if self._indexes:
+ for name, index in self._indexes.iteritems():
+ index._clearDirties()
+
def _createIndex(self, indexType, **kwds):
if indexType == 'numeric':
@@ -284,7 +299,6 @@
indexes.saveKey(self._key, self._value,
version, key, node)
- self._changedKeys.clear()
self._version = version
elif mode == 'serialize':
@@ -292,4 +306,132 @@
else:
raise ValueError, mode
+
+ def _clearDirties(self):
+
+ self._changedKeys.clear()
+
+
+class XMLChildren(Children):
+
+ def __init__(self, view, item):
+
+ super(XMLChildren, self).__init__(item)
+
+ self.view = view
+
+ self._uuid = item.itsUUID
+ self._changedRefs = {}
+ self._key = self._getRefs().prepareKey(self._uuid, self._uuid)
+ self._value = StringIO()
+
+ ref = self._getRefs().loadRef(self._key, self._item._version,
+ self._uuid)
+ if ref is not None:
+ self._firstKey, self._lastKey, alias = ref
+
+ def resolveAlias(self, alias, load=True):
+
+ load = load and not self._item.isNew()
+ key = None
+
+ if self._aliases:
+ key = self._aliases.get(alias)
+
+ if load and key is None:
+ view = self.view
+ key = view.repository.store.readName(view._version,
+ self._uuid, alias)
+ if key is not None:
+ op, oldAlias = self._changedRefs.get(key, (0, None))
+ if oldAlias == alias:
+ key = None
+
+ return key
+
+ def _load(self, key):
+
+ if self.view._loadItem(key) is not None:
+ return True
+
+ return False
+
+ def linkChanged(self, link, key):
+
+ super(XMLChildren, self).linkChanged(link, key)
+ if not self.view.isLoading():
+ op, alias = self._changedRefs.get(key, (1, link._alias))
+ if op != 0:
+ # changed element: key, maybe old alias: alias
+ self._changedRefs[key] = (0, alias)
+
+ def __delitem__(self, key):
+
+ link = super(XMLChildren, self).__delitem__(key)
+ op, alias = self._changedRefs.get(key, (0, link._alias))
+ if op != 1:
+ # deleted element: key, maybe old alias: alias
+ self._changedRefs[key] = (1, alias)
+
+ def __setitem__(self, key, value,
+ previousKey=None, nextKey=None, alias=None):
+
+ if previousKey is None and nextKey is None and self.view.isLoading():
+ ref = self._getRefs().loadRef(self._key, self._item._version, key)
+ if ref is not None:
+ previousKey, nextKey, refAlias = ref
+ assert alias == refAlias
+
+ super(XMLChildren, self).__setitem__(key, value,
+ previousKey, nextKey, alias)
+
+ def _getRefs(self):
+
+ return self.view.repository.store._refs
+
+ def _writeRef(self, key, version, previous, next, alias):
+
+ self._getRefs().saveRef(self._key, self._value, version, key,
+ previous, next, alias)
+
+ def _deleteRef(self, key, version):
+
+ self._getRefs().deleteRef(self._key, self._value, version, key)
+
+ def _saveValues(self, version):
+
+ store = self.view.repository.store
+
+ for key, (op, oldAlias) in self._changedRefs.iteritems():
+ try:
+ link = self._get(key, load=False)
+ except KeyError:
+ link = None
+
+ if op == 0: # change
+ if link is not None:
+ ref = link._value
+ previous = link._previousKey
+ next = link._nextKey
+ alias = link._alias
+
+ self._writeRef(key, version, previous, next, alias)
+ if oldAlias != alias:
+ store.writeName(version, self._uuid, oldAlias, None)
+ store.writeName(version, self._uuid, alias, key)
+
+ elif key is None:
+ self._writeRef(self._uuid, version,
+ self._firstKey, self._lastKey, None)
+
+ elif op == 1: # remove
+ self._deleteRef(key, version)
+ store.writeName(version, self._uuid, oldAlias, None)
+
+ else: # error
+ raise ValueError, op
+
+ def _clearDirties(self):
+
+ self._changedRefs.clear()
Index: chandler/repository/persistence/RepositoryView.py
diff -u chandler/repository/persistence/RepositoryView.py:1.6 chandler/repository/persistence/RepositoryView.py:1.7
--- chandler/repository/persistence/RepositoryView.py:1.6 Thu Jul 8 17:00:01 2004
+++ chandler/repository/persistence/RepositoryView.py Thu Sep 2 10:34:26 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.6 $"
-__date__ = "$Date: 2004/07/09 00:00:01 $"
+__revision__ = "$Revision: 1.7 $"
+__date__ = "$Date: 2004/09/02 17:34:26 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -74,6 +74,10 @@
raise NotImplementedError, "%s._createRefDict" %(type(self))
+ def _createChildren(self, parent):
+
+ raise NotImplementedError, "%s._createChildren" %(type(self))
+
def _getLobType(self):
raise NotImplementedError, "%s._getLobType" %(type(self))
@@ -86,7 +90,8 @@
re-opening a closed view.
"""
- self._roots = {}
+ self._roots = self._createChildren(self)
+ self._dirty = 0
self._registry = {}
self._deletedRegistry = {}
self._childrenRegistry = {}
@@ -95,6 +100,10 @@
self.repository.store.attachView(self)
+ def setDirty(self, dirty, attribute):
+
+ self._dirty = dirty
+
def closeView(self):
"""
Close this repository view.
@@ -113,7 +122,8 @@
item._setStale()
self._registry.clear()
- self._roots.clear()
+ self._roots = None
+ self._dirty = 0
self._deletedRegistry.clear()
self._childrenRegistry.clear()
del self._stubs[:]
@@ -150,6 +160,10 @@
return ((self._status & RepositoryView.OPEN) != 0 and
self.repository.isOpen())
+ def isNew(self):
+
+ return False
+
def isStale(self):
return False
@@ -328,7 +342,7 @@
@return: an L{ACL<repository.item.Access.ACL>} instance or C{None}
"""
- return self.repository.store.loadACL(self.version, uuid, name)
+ return self.repository.store.loadACL(self._version, uuid, name)
def loadPack(self, path, parent=None):
"""
@@ -369,7 +383,7 @@
if item is None:
path = Path('//')
- for root in self.getRoots():
+ for root in self.iterRoots():
self.dir(root, path)
else:
if path is None:
@@ -451,7 +465,7 @@
"""
result = True
- for root in self.getRoots():
+ for root in self.iterRoots():
check = root.check(True)
result = result and check
@@ -470,7 +484,7 @@
@return: C{True} or C{False}
"""
- return self.getRoot(name, load) is not None
+ return self._roots.resolveAlias(name, load) is not None
def getRoot(self, name, load=True):
"""
@@ -485,10 +499,7 @@
@return: a root item or C{None} if not found.
"""
- try:
- return self._roots[name]
- except KeyError:
- return self._loadRoot(name)
+ return self._roots.getByAlias(name, None, load)
def __getitem__(self, key):
@@ -514,29 +525,30 @@
def __iter__(self):
"""
- Iterate over the roots of this repository in this view.
+ See L{iterRoots}
"""
- return self.iterChildren()
+ return self.iterRoots()
- def iterChildren(self, load=True):
+ def iterChildren(self):
"""
- Iterate over the roots of this repository in this view.
+ See L{iterRoots}
"""
- return self.getRoots(load).__iter__()
-
- def getRoots(self, load=True):
+ return self.iterRoots()
+
+ def iterRoots(self, load=True):
+ """
+ Iterate over the roots of this repository in this view.
"""
- Get all roots in the repository from this view.
- A repository root is defined as an item whose parent is this view.
+ if not load:
+ for child in self._roots._itervalues():
+ yield child._value
- @param load: if load is C{False}, only return the loaded roots.
- @type load: boolean
- """
-
- return self._roots.values()
+ else:
+ for child in self._roots:
+ yield child
def _getPath(self, path=None):
@@ -564,20 +576,20 @@
name = item.itsName
- if name in self._roots:
+ if self._roots.resolveAlias(name, not self.isLoading()):
raise ValueError, "A root named '%s' exists already" %(name)
- self._roots[name] = item
+ self._roots.__setitem__(item._uuid, item, alias=name)
return item
def _removeItem(self, item):
- del self._roots[item.itsName]
+ del self._roots[item.itsUUID]
- def _unloadChild(self, name):
+ def _unloadChild(self, child):
- del self._roots[name]
+ self._roots._unload(child)
def _registerItem(self, item):
@@ -674,9 +686,6 @@
def _loadRoot(self, name):
raise NotImplementedError, "%s._loadRoot" %(type(self))
- def _loadChild(self, parent, name):
- raise NotImplementedError, "%s._loadChild" %(type(self))
-
def _newItems(self):
raise NotImplementedError, "%s._newItems" %(type(self))
@@ -701,6 +710,10 @@
return self.repository.logger.getEffectiveLevel() <= logging.DEBUG
+ def getRepositoryView(self):
+
+ return self
+
itsUUID = property(__getUUID)
itsName = property(__getName)
itsPath = property(_getPath)
@@ -717,13 +730,16 @@
class OnDemandRepositoryView(RepositoryView):
def __init__(self, repository, name):
-
- super(OnDemandRepositoryView, self).__init__(repository, name)
- self.version = repository.store.getVersion()
+ self._version = repository.store.getVersion()
self._hooks = None
- self._notRoots = {}
+ super(OnDemandRepositoryView, self).__init__(repository, name)
+
+ def isNew(self):
+
+ return self._version == 0
+
def _loadDoc(self, doc, instance=None):
try:
@@ -781,7 +797,7 @@
def _loadItem(self, uuid, instance=None):
if not uuid in self._deletedRegistry:
- doc = self.repository.store.loadItem(self.version, uuid)
+ doc = self.repository.store.loadItem(self._version, uuid)
if doc is not None:
self.logger.debug("loading item %s", uuid)
@@ -789,46 +805,6 @@
return None
- def _loadRoot(self, name):
-
- return self._loadChild(None, name)
-
- def getRoots(self, load=True):
- 'Return a list of the roots in the repository.'
-
- if load:
- for uuid in self.repository.store.readNames(self.version,
- self.itsUUID):
- self.find(uuid)
-
- return super(OnDemandRepositoryView, self).getRoots(load)
-
- def _loadChild(self, parent, name):
-
- if parent is not None and parent is not self:
- uuid = parent.itsUUID
- else:
- uuid = self.itsUUID
-
- store = self.repository.store
- doc = store.loadChild(self.version, uuid, name)
-
- if doc is not None:
- uuid = store.getDocUUID(doc)
-
- if (not self._deletedRegistry or
- not uuid in self._deletedRegistry):
- if self.isDebug():
- if parent is not None and parent is not self:
- self.logger.debug("loading child %s of %s",
- name, parent.itsPath)
- else:
- self.logger.debug("loading root %s", name)
-
- return self._loadDoc(doc)
-
- return None
-
def _findKind(self, spec, withSchema):
if withSchema:
@@ -852,10 +828,6 @@
super(OnDemandRepositoryView, self)._addItem(item, previous, next)
- name = item.itsName
- if name in self._notRoots:
- del self._notRoots[name]
-
item.setPinned(True)
return item
@@ -864,18 +836,8 @@
super(OnDemandRepositoryView, self)._removeItem(item)
- name = item.itsName
- self._notRoots[name] = name
-
item.setPinned(False)
- def getRoot(self, name, load=True):
-
- if not name in self._notRoots:
- return super(OnDemandRepositoryView, self).getRoot(name, load)
-
- return None
-
def prune(self, size):
registry = self._registry
Index: chandler/repository/remote/RemoteRepository.py
diff -u chandler/repository/remote/RemoteRepository.py:1.3 chandler/repository/remote/RemoteRepository.py:1.4
--- chandler/repository/remote/RemoteRepository.py:1.3 Tue May 18 20:19:21 2004
+++ chandler/repository/remote/RemoteRepository.py Thu Sep 2 10:34:26 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.3 $"
-__date__ = "$Date: 2004/05/19 03:19:21 $"
+__revision__ = "$Revision: 1.4 $"
+__date__ = "$Date: 2004/09/02 17:34:26 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -62,20 +62,6 @@
return doc
- def loadChild(self, version, uuid, name):
-
- doc = super(RemoteStore, self).loadChild(version, uuid, name)
- if doc is None:
- versionId = self._versions.getVersionId(self.itsUUID)
- remoteVersion = self._versions.getVersion(versionId)
- xml = self.transport.serveChild(remoteVersion, uuid, name)
- if xml is not None:
- filter = RemoteFilter(self, versionId)
- self.transport.parseDoc(xml, filter)
- doc = filter.getDocument()
-
- return doc
-
def getVersion(self):
version = super(RemoteStore, self).getVersion()
Index: chandler/repository/tests/TestRepository.py
diff -u chandler/repository/tests/TestRepository.py:1.8 chandler/repository/tests/TestRepository.py:1.9
--- chandler/repository/tests/TestRepository.py:1.8 Mon Jun 21 17:54:08 2004
+++ chandler/repository/tests/TestRepository.py Thu Sep 2 10:34:26 2004
@@ -2,8 +2,8 @@
Basic Unit tests for Chandler repository
"""
-__revision__ = "$Revision: 1.8 $"
-__date__ = "$Date: 2004/06/22 00:54:08 $"
+__revision__ = "$Revision: 1.9 $"
+__date__ = "$Date: 2004/09/02 17:34:26 $"
__copyright__ = "Copyright (c) 2003 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -39,11 +39,11 @@
root = self.rep['Packs']
self.assert_(root.itsName == 'Packs')
- def testGetRoots(self):
+ def testIterRoots(self):
""" Make sure the roots of the repository are correct"""
# (The parcel manager sticks the //parcels root in there)
- for root in self.rep.getRoots():
+ for root in self.rep.iterRoots():
self.assert_(root.itsName in ['Schema', 'Packs', 'parcels'])
def testWalk(self):
Index: chandler/repository/item/Item.py
diff -u chandler/repository/item/Item.py:1.156 chandler/repository/item/Item.py:1.157
--- chandler/repository/item/Item.py:1.156 Mon Aug 30 17:19:56 2004
+++ chandler/repository/item/Item.py Thu Sep 2 10:34:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.156 $"
-__date__ = "$Date: 2004/08/31 00:19:56 $"
+__revision__ = "$Revision: 1.157 $"
+__date__ = "$Date: 2004/09/02 17:34:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -66,6 +66,8 @@
if kind is not None:
kind.getInitialValues(self, self._values, self._references)
+ self.setDirty(Item.NDIRTY, None)
+
def _fillItem(self, name, parent, kind, **kwds):
self._uuid = kwds['uuid']
@@ -86,7 +88,7 @@
references._setItem(self)
self._references = references
- self._setParent(parent, kwds.get('previous'), kwds.get('next'))
+ self._setParent(parent)
def __iter__(self):
"""
@@ -644,9 +646,7 @@
"""
return ('_children' in self.__dict__ and
- not ('_notChildren' in self.__dict__ and
- name in self._notChildren) and
- self._children.has_key(name, load))
+ self._children.resolveAlias(name, load) is not None)
def hasChildren(self):
"""
@@ -677,11 +677,11 @@
if not (after is None or after.itsParent is self):
raise ValueError, '%s not a child of %s' %(after, self)
- key = child._name
+ key = child._uuid
if after is None:
afterKey = None
else:
- afterKey = after._name
+ afterKey = after._uuid
self._children.place(key, afterKey)
@@ -1312,9 +1312,8 @@
C{False}.
@param dirty: one of L{Item.VDIRTY <VDIRTY>},
- L{Item.RDIRTY <RDIRTY>}, L{Item.CDIRTY <CDIRTY>},
- L{Item.SDIRTY, <SDIRTY>} or a bitwise or'ed combination, defaults to
- C{Item.VDIRTY}.
+ L{Item.RDIRTY <RDIRTY>}, L{Item.CDIRTY <CDIRTY>}, or a bitwise or'ed
+ combination, defaults to C{Item.VDIRTY}.
@type dirty: an integer
@param attribute: the name of the attribute that was changed,
optional, defaults to C{None} which means that no attribute was
@@ -1338,6 +1337,7 @@
if self._status & Item.DIRTY == 0:
repository = self.getRepositoryView()
if repository is not None and not repository.isLoading():
+
if attribute is not None:
if self.getAttributeAspect(attribute, 'persist',
default=True) == False:
@@ -1354,6 +1354,8 @@
self._status &= ~(Item.DIRTY | Item.ADIRTY)
self._values._clearDirties()
self._references._clearDirties()
+ if '_children' in self.__dict__:
+ self._children._clearDirties()
return False
@@ -1491,12 +1493,10 @@
self.removeAttributeValue(name, _attrDict=self._references)
parent = self.itsParent
-
+ view = self.getRepositoryView()
+
parent._removeItem(self)
- self._setRoot(None)
-
- if not '_origName' in self.__dict__:
- self.__dict__['_origName'] = (parent.itsUUID, self._name)
+ self._setRoot(None, view)
self._status |= Item.DELETED | Item.STALE
self._status &= ~Item.DELETING
@@ -1575,29 +1575,26 @@
return self._root
- def _setRoot(self, root):
+ def _setRoot(self, root, oldView):
if root is not self._root:
- oldRepository = self.getRepositoryView()
self._root = root
- newRepository = self.getRepositoryView()
+ newView = self.getRepositoryView()
- if oldRepository is not newRepository:
+ if oldView is not newView:
- if oldRepository is not None and newRepository is not None:
+ if oldView is not None and newView is not None:
raise NotImplementedError, 'changing repositories'
- if oldRepository is not None:
- oldRepository._unregisterItem(self)
+ if oldView is not None:
+ oldView._unregisterItem(self)
- if newRepository is not None:
- newRepository._registerItem(self)
-
- self.setDirty(Item.CDIRTY, None)
+ if newView is not None:
+ newView._registerItem(self)
for child in self.iterChildren(load=False):
- child._setRoot(root)
+ child._setRoot(root, oldView)
def __getParent(self):
@@ -1806,24 +1803,19 @@
"""
if name != self._name:
- origName = self._name
parent = self.itsParent
if parent._isItem():
- link = parent._children._get(self._name)
- parent._removeItem(self)
- self._name = name or self._uuid.str64()
- parent._addItem(self, link._previousKey, link._nextKey)
- else:
- parent._removeItem(self)
- self._name = name or self._uuid.str64()
- parent._addItem(self)
- self.setDirty(Item.SDIRTY, None)
-
- if not '_origName' in self.__dict__:
- self.__dict__['_origName'] = (parent.itsUUID, origName)
+ link = parent._children._get(self._uuid)
+ else:
+ link = parent._roots._get(self._uuid)
+ parent._removeItem(self)
+ self._name = name or self._uuid.str64()
+ parent._addItem(self, link._previousKey, link._nextKey)
+ self.setDirty(Item.NDIRTY, None)
+
def move(self, newParent, previous=None, next=None):
"""
Move this item under another container.
@@ -1850,10 +1842,10 @@
parent = self.itsParent
if parent is not newParent:
+ oldView = parent.getRepositoryView()
parent._removeItem(self)
- self._setParent(newParent, previous, next)
- if not '_origName' in self.__dict__:
- self.__dict__['_origName'] = (parent.itsUUID, self._name)
+ self._setParent(newParent, previous, next, oldView)
+ self.setDirty(Item.NDIRTY, None)
def _isRepository(self):
return False
@@ -1861,14 +1853,13 @@
def _isItem(self):
return True
- def _setParent(self, parent, previous=None, next=None):
+ def _setParent(self, parent, previous=None, next=None, oldView=None):
if parent is not None:
if parent._isRepository():
parent = parent.view
self._parent = parent
- self._root = None
- self._setRoot(parent._addItem(self, previous, next))
+ self._setRoot(parent._addItem(self, previous, next), oldView)
else:
self._parent = None
@@ -1876,33 +1867,22 @@
name = item._name
- if self.__dict__.has_key('_children'):
+ if '_children' in self.__dict__:
loading = self.getRepositoryView().isLoading()
- current = self.getItemChild(name, not loading)
-
- if current is not None:
+ if self._children.resolveAlias(name, not loading):
raise ValueError, "A child '%s' exists already under %s" %(item._name, self.itsPath)
else:
- self._children = Children(self)
+ self._children = self.getRepositoryView()._createChildren(self)
- self._children.__setitem__(name, item, previous, next)
+ self._children.__setitem__(item._uuid, item, previous, next, name)
- if '_notChildren' in self.__dict__ and name in self._notChildren:
- del self._notChildren[name]
-
return self.itsRoot
def _removeItem(self, item):
- name = item._name
- del self._children[name]
-
- if '_notChildren' in self.__dict__:
- self._notChildren[name] = name
- else:
- self._notChildren = { name: name }
+ del self._children[item._uuid]
def getItemChild(self, name, load=True):
"""
@@ -1924,17 +1904,7 @@
child = None
if '_children' in self.__dict__:
- child = self._children.get(name, None, False)
-
- if load and child is None:
- hasNot = '_notChildren' in self.__dict__
- if not (hasNot and name in self._notChildren):
- child = self.getRepositoryView()._loadChild(self, name)
- if child is None:
- if not hasNot:
- self._notChildren = { name: name }
- else:
- self._notChildren[name] = name
+ child = self._children.getByAlias(name, None, load)
return child
@@ -2216,16 +2186,8 @@
self._status |= Item.MERGED
if newDirty == Item.VDIRTY:
- mergeNewOld('attribute')
- elif newDirty == Item.RDIRTY:
- mergeNewOld('ref')
- elif newDirty == Item.VRDIRTY:
mergeNewOld('attribute', 'ref')
elif oldDirty == Item.VDIRTY:
- mergeOldNew(Item.VDIRTY, 'attribute')
- elif oldDirty == Item.RDIRTY:
- mergeOldNew(Item.RDIRTY, 'ref')
- elif oldDirty == Item.VRDIRTY:
mergeOldNew(Item.VRDIRTY, 'attribute', 'ref')
else:
raise NotImplementedError, "merge %0.4x:%0.4x" %(oldDirty,
@@ -2264,33 +2226,17 @@
xmlTag('class', { 'module': self.__module__ },
type(self).__name__, generator)
- attrs = {}
- parent = self.itsParent
- parentID = parent.itsUUID.str64()
-
- if not isDeleted:
- if parent._isItem():
- link = parent._children._get(self._name)
- if link._previousKey is not None:
- attrs['previous'] = link._previousKey
- if link._nextKey is not None:
- attrs['next'] = link._nextKey
-
- if '_children' in self.__dict__:
- children = self._children
- if children._firstKey is not None:
- attrs['first'] = children._firstKey
- if children._lastKey is not None:
- attrs['last'] = children._lastKey
-
- xmlTag('container', attrs, parentID, generator)
+ attrs = { 'type': 'uuid' }
+ if '_children' in self.__dict__:
+ attrs['container'] = 'True'
+ if mode == 'save':
+ self._children._saveValues(version)
- if not isDeleted:
- if save & Item.VDIRTY:
- self._values._xmlValues(generator, withSchema, version, mode)
- if save & Item.RDIRTY:
- self._references._xmlValues(generator, withSchema, version,
- mode)
+ xmlTag('parent', attrs, self.itsParent.itsUUID.str64(), generator)
+
+ if not isDeleted and save & Item.VRDIRTY:
+ self._values._xmlValues(generator, withSchema, version, mode)
+ self._references._xmlValues(generator, withSchema, version, mode)
generator.endElement('item')
@@ -2317,15 +2263,15 @@
self._references._unload()
repository._unregisterItem(self)
- self._parent._unloadChild(self._name)
+ self._parent._unloadChild(self)
if '_children' in self.__dict__ and len(self._children) > 0:
repository._registerChildren(self._uuid, self._children)
self._status |= Item.STALE
- def _unloadChild(self, name):
+ def _unloadChild(self, child):
- self._children._unload(name)
+ self._children._unload(child)
def _refDict(self, name, otherName=None, persist=None):
@@ -2366,8 +2312,8 @@
SCHEMA = 0x0020
NEW = 0x0040
STALE = 0x0080
- SDIRTY = 0x0100 # name of sibling(s) changed
- CDIRTY = 0x0200 # parent or first/last child changed
+ NDIRTY = 0x0100 # parent or name changed
+ CDIRTY = 0x0200 # children list changed
RDIRTY = 0x0400 # ref collection changed
MERGED = 0x0800
SAVED = 0x1000
@@ -2376,7 +2322,7 @@
NODIRTY = 0x8000 # turn off dirtying
VRDIRTY = VDIRTY | RDIRTY
- DIRTY = VDIRTY | RDIRTY | SDIRTY | CDIRTY
+ DIRTY = VDIRTY | RDIRTY | NDIRTY | CDIRTY
SAVEMASK = DIRTY | ADIRTY | NEW | DELETED | SCHEMA
__access__ = 0L
@@ -2465,23 +2411,27 @@
class Children(LinkedMap):
- def __init__(self, item, dictionary=None):
+ def __init__(self, item):
- super(Children, self).__init__(dictionary)
+ super(Children, self).__init__()
self._item = item
def _setItem(self, item):
+ assert item._uuid == self._item._uuid
self._item = item
+
for link in self._itervalues():
link._value._parent = item
def linkChanged(self, link, key):
- if key is None:
- self._item.setDirty(Item.CDIRTY, None)
- else:
- link._value.setDirty(Item.SDIRTY, None)
+ self._item.setDirty(Item.CDIRTY, None)
+
+ def _unload(self, child):
+
+ link = super(Children, self)._unload(child._uuid)
+ del self._aliases[child._name]
def __repr__(self):
@@ -2509,8 +2459,11 @@
def _load(self, key):
- if self._item.getRepositoryView()._loadChild(self._item,
- key) is not None:
+ if self._item.getRepositoryView()._loadItem(key) is not None:
return True
return False
+
+ def _saveValues(self, version):
+
+ pass
Index: chandler/repository/tests/TestMove.py
diff -u chandler/repository/tests/TestMove.py:1.1 chandler/repository/tests/TestMove.py:1.2
--- chandler/repository/tests/TestMove.py:1.1 Tue Feb 3 19:37:52 2004
+++ chandler/repository/tests/TestMove.py Thu Sep 2 10:34:26 2004
@@ -2,8 +2,8 @@
Text blocked read of appended storage compression unit tests
"""
-__revision__ = "$Revision: 1.1 $"
-__date__ = "$Date: 2004/02/04 03:37:52 $"
+__revision__ = "$Revision: 1.2 $"
+__date__ = "$Date: 2004/09/02 17:34:26 $"
__copyright__ = "Copyright (c) 2003 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -25,10 +25,12 @@
cineguidePack = os.path.join(self.testdir, 'data', 'packs',
'cineguide.pack')
self.rep.loadPack(cineguidePack)
- self.rep.commit()
-
+
def move(self, withCommit):
+ if withCommit:
+ self.rep.commit()
+
c = self.rep['CineGuide']
k = c['KHepburn']
m = k.movies.first()
@@ -55,6 +57,14 @@
def testMove(self):
self.move(False)
+ def testReopenCommit(self):
+ self._reopenRepository()
+ self.move(True)
+
+ def testReopen(self):
+ self._reopenRepository()
+ self.move(False)
+
if __name__ == "__main__":
# import hotshot
Index: chandler/repository/util/LinkedMap.py
diff -u chandler/repository/util/LinkedMap.py:1.13 chandler/repository/util/LinkedMap.py:1.14
--- chandler/repository/util/LinkedMap.py:1.13 Wed Jul 21 14:34:29 2004
+++ chandler/repository/util/LinkedMap.py Thu Sep 2 10:34:27 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.13 $"
-__date__ = "$Date: 2004/07/21 21:34:29 $"
+__revision__ = "$Revision: 1.14 $"
+__date__ = "$Date: 2004/09/02 17:34:27 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -17,6 +17,7 @@
self._previousKey = self._nextKey = None
self._value = value
+ self._alias = None
def __repr__(self):
@@ -41,13 +42,12 @@
linkedMap.linkChanged(self, key)
- def __init__(self, dictionary=None):
+ def __init__(self):
super(LinkedMap, self).__init__()
- self._firstKey = self._lastKey = None
- if dictionary is not None:
- self.update(dictionary)
+ self._firstKey = self._lastKey = None
+ self._aliases = None
def __repr__(self):
@@ -102,7 +102,8 @@
return self._get(key, load)._value
- def __setitem__(self, key, value, previousKey=None, nextKey=None):
+ def __setitem__(self, key, value,
+ previousKey=None, nextKey=None, alias=None):
link = super(LinkedMap, self).get(key)
@@ -125,6 +126,13 @@
super(LinkedMap, self).__setitem__(key, link)
+ if alias:
+ link._alias = alias
+ if self._aliases is None:
+ self._aliases = { alias: key }
+ else:
+ self._aliases[alias] = key
+
return link
def place(self, key, afterKey=None):
@@ -183,6 +191,9 @@
super(LinkedMap, self).__delitem__(key)
+ if link._alias is not None:
+ del self._aliases[link._alias]
+
return link
def has_key(self, key, load=True):
@@ -205,6 +216,52 @@
return default
+ def getByAlias(self, alias, default=None, load=True):
+ """
+ Get the value referenced through its alias.
+
+ @param alias: the alias of the item referenced.
+ @type key: a string
+ @param default: the default value to return if there is no value
+ for C{key} in this collection, C{None} by default.
+ @type default: anything
+ @param load: if the value exists but hasn't been loaded yet,
+ this method will return C{default} if this parameter is C{False}.
+ @type load: boolean
+ @return: a value of the collection or C{default}
+ """
+
+ key = None
+
+ if self._aliases is not None:
+ key = self._aliases.get(alias)
+
+ if key is None and load:
+ key = self.resolveAlias(alias, load)
+
+ if key is None:
+ return default
+
+ return self.get(key, default, load)
+
+ def resolveAlias(self, alias, load=True):
+ """
+ Resolve the alias to its corresponding reference key.
+
+ @param alias: the alias to resolve.
+ @type alias: a string
+ @param load: if the value exists but hasn't been loaded yet,
+ this method will return C{None} if this parameter is C{False}.
+ @type load: boolean
+ @return: a key into the collection or C{None} if the alias does not
+ exist.
+ """
+
+ if self._aliases:
+ return self._aliases.get(alias)
+
+ return None
+
def firstKey(self):
"Return the first key of this mapping."
Index: chandler/repository/util/SAX.py
diff -u chandler/repository/util/SAX.py:1.4 chandler/repository/util/SAX.py:1.5
--- chandler/repository/util/SAX.py:1.4 Thu May 13 23:34:27 2004
+++ chandler/repository/util/SAX.py Thu Sep 2 10:34:27 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.4 $"
-__date__ = "$Date: 2004/05/14 06:34:27 $"
+__revision__ = "$Revision: 1.5 $"
+__date__ = "$Date: 2004/09/02 17:34:27 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -34,6 +34,12 @@
return self.exception is not None
+ def parse(self, xml):
+
+ createPushParser(self, xml, len(xml), 'filter').parseChunk('', 0, 1)
+ if self.errorOccurred():
+ raise self.saxError()
+
def saxError(self):
try:
@@ -190,12 +196,6 @@
raise NotImplementedError, 'XMLFilter.output'
- def parse(self, xml):
-
- createPushParser(self, xml, len(xml), 'filter').parseChunk('', 0, 1)
- if self.errorOccurred():
- raise self.saxError()
-
def endDocument(self):
if self.cdata:
More information about the Commits
mailing list