def addIndex(self, indexName, indexType, **kwds): """ Add an index to this collection. A collection index provides positional access into the collection and maintains a key order which is be determined by the sequence of collection mutation operations or by constraints on values. A collection may have any number of indexes. Each index has a name which is used with the L{getByIndex}, L{getIndexEntryValue}, L{setIndexEntryValue}, L{resolveIndex}, L{first}, L{last}, L{next}, L{previous} methods. Because the implementation of an index depends on the persistence layer, the type of index is chosen with the C{indexType} parameter which can have one of the following values: - C{numeric}: a simple index reflecting the sequence of mutation operations. - C{attribute}: an index sorted on the value of an attribute of items in the collection. The name of the attribute is provided via the C{attribute} keyword. - C{compare}: an index sorted on the return value of a method invoked on items in the collection. The method is a comparison method whose name is provided with the C{compare} keyword, and it is invoked on C{i0}, with the other item being compared, C{i1}, and is expected to return a positive number if, in the context of this index, C{i0 > i1}, a negative number if C{i0 < i1}, or zero if C{i0 == i1}. @param indexName: the name of the index @type indexName: a string @param indexType: the type of index @type indexType: a string """ item, name = self._getOwner() if self._indexes is not None: if indexName in self._indexes: raise IndexAlreadyExists, (item, name, indexName) else: self._indexes = {} index = self._createIndex(indexType, **kwds) self._indexes[indexName] = index if not self._getView().isLoading(): self.fillIndex(index) self._setDirty(True) # noMonitors=True if indexType in ('attribute', 'string'): from repository.item.Monitors import Monitors Monitors.attach(item, '_reIndex', 'set', kwds['attribute'], name, indexName) return index
def _setOwner(self, item, attribute): oldItem, oldAttribute = super(KindSet, self)._setOwner(item, attribute) if item is not oldItem: if not self.itsView.isLoading(): if oldItem is not None: Monitors.detach(oldItem, '_kindChanged', 'schema', 'kind', oldAttribute) if item is not None: Monitors.attach(item, '_kindChanged', 'schema', 'kind', attribute)
def testMonitor(self): kh = self.rep.findPath('//CineGuide/KHepburn') m1 = kh.movies.first() actor = kh.itsKind movie = m1.itsKind attribute = actor.getAttribute('movies').itsKind self.assert_(kh.isItemOf(actor)) Monitors.attach(m1, 'kindChanged', 'schema', 'kind') m1.monitorAttribute = None mixin = kh.mixinKinds(('add', movie), ('add', attribute)) self.assert_(m1.monitorAttribute == 'kind')