Automatic indexing with events¶
In order to automatically keep the catalog up-to-date any objects that are added to a intid utility are indexed automatically. Also when an object gets modified it is reindexed by listening to IObjectModified events.
Let us create a fake catalog to demonstrate this behaviour. We only need to implement the index_doc method for this test.
>>> from zope.catalog.interfaces import ICatalog
>>> from zope import interface, component
>>> @interface.implementer(ICatalog)
... class FakeCatalog(object):
... indexed = []
... def index_doc(self, docid, obj):
... self.indexed.append((docid, obj))
>>> cat = FakeCatalog()
>>> component.provideUtility(cat)
We also need an intid util and a keyreference adapter.
>>> from zope.intid import IntIds
>>> from zope.intid.interfaces import IIntIds
>>> intids = IntIds()
>>> component.provideUtility(intids, IIntIds)
>>> from zope.keyreference.testing import SimpleKeyReference
>>> component.provideAdapter(SimpleKeyReference)
>>> from zope.container.contained import Contained
>>> class Dummy(Contained):
... def __init__(self, name):
... self.__name__ = name
... def __repr__(self):
... return '<Dummy %r>' % self.__name__
We have a subscriber to IIntidAddedEvent.
>>> from zope.catalog import catalog
>>> from zope.intid.interfaces import IntIdAddedEvent
>>> d1 = Dummy(u'one')
>>> id1 = intids.register(d1)
>>> catalog.indexDocSubscriber(IntIdAddedEvent(d1, None))
Now we have indexed the object.
>>> cat.indexed.pop()
(..., <Dummy u'one'>)
When an object is modified an objectmodified event should be fired by the application. Here is the handler for such an event.
>>> from zope.lifecycleevent import ObjectModifiedEvent
>>> catalog.reindexDocSubscriber(ObjectModifiedEvent(d1))
>>> len(cat.indexed)
1
>>> cat.indexed.pop()
(..., <Dummy u'one'>)
Preventing automatic indexing¶
Sometimes it is not accurate to automatically index an object. For example when a lot of indexes are in the catalog and only specific indexes needs to be updated. There are marker interfaces to achieve this.
>>> from zope.catalog.interfaces import INoAutoIndex
If an object provides this interface it is not automatically indexed.
>>> interface.alsoProvides(d1, INoAutoIndex)
>>> catalog.indexDocSubscriber(IntIdAddedEvent(d1, None))
>>> len(cat.indexed)
0
>>> from zope.catalog.interfaces import INoAutoReindex
If an object provides this interface it is not automatically reindexed.
>>> interface.alsoProvides(d1, INoAutoReindex)
>>> catalog.reindexDocSubscriber(ObjectModifiedEvent(d1))
>>> len(cat.indexed)
0