diff --git a/relation/README.txt b/relation/README.txt index 2686444..9737e56 100644 --- a/relation/README.txt +++ b/relation/README.txt @@ -4,7 +4,7 @@ Quickstart Instructions ($Id$) In the ++etc++/default folder of your Zope 3 site create a Unique Id Utility -and a Relations Registry. +and a relation registry. In your application @@ -14,9 +14,9 @@ In your application ``MyRelation(object1, object2)``. - register these relation objects by getting a utility providing - ``IRelationsRegistry`` and call the ``register(relation)`` on this utility. + ``IRelationRegistry`` and call the ``register(relation)`` on this utility. -You are now ready to retrieve relations by using the relations registry's +You are now ready to retrieve relations by using the relation registry's ``query()`` method as described below. You may also like to read the file concepts.txt that gives you some more basic @@ -111,12 +111,12 @@ Dyadic Relations >>> class LivesIn(DyadicRelation): ... pass -We don't directly keep track of relations but use a relations registry for -this. The relations registry is usually a local utility; for testing we use +We don't directly keep track of relations but use a relation registry for +this. The relation registry is usually a local utility; for testing we use a simple dummy implementation: - >>> from cybertools.relation.registry import DummyRelationsRegistry - >>> relations = DummyRelationsRegistry() + >>> from cybertools.relation.registry import DummyRelationRegistry + >>> relations = DummyRelationRegistry() So we are ready to connect a person and a city using the LivesIn relationship: @@ -124,7 +124,7 @@ So we are ready to connect a person and a city using the LivesIn relationship: >>> relations.register(LivesIn(audrey, newyork)) >>> relations.register(LivesIn(kirk, newyork)) -We can now query the relations registry to find out where clark lives and +We can now query the relation registry to find out where clark lives and who lives in New York. For this we use the standard attributes of dyadic relations, first and second: @@ -183,21 +183,21 @@ all relations for clark's children: True -Setting up and using a RelationsRegistry local utility +Setting up and using a RelationRegistry local utility ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We now do the same stuff as above with a real, catalog-based implementation of -the relations registry. We also register the relations registry as a +the relation registry. We also register the relation registry as a utility for demonstration purposes (and to be able to use it later when working with events). - >>> from cybertools.relation.registry import RelationsRegistry - >>> from cybertools.relation.interfaces import IRelationsRegistry + >>> from cybertools.relation.registry import RelationRegistry + >>> from cybertools.relation.interfaces import IRelationRegistry >>> from zope.app.testing import ztapi - >>> ztapi.provideUtility(IRelationsRegistry, RelationsRegistry()) + >>> ztapi.provideUtility(IRelationRegistry, RelationRegistry()) >>> from zope.app import zapi - >>> relations = zapi.getUtility(IRelationsRegistry) + >>> relations = zapi.getUtility(IRelationRegistry) In real life the indexes needed will be set up via subscription to IObjectCreatedEvent - here we have to do this explicitly: @@ -281,7 +281,7 @@ It should work also for triadic relations: True There is also a convenience function that it makes even easier to query -a relations registry; it allows to query for more than one relationship: +a relation registry; it allows to query for more than one relationship: >>> from cybertools.relation.registry import getRelations >>> len(getRelations(first=clark)) @@ -383,7 +383,7 @@ our LivesIn relation class from above) and use for registration: >>> relations.register(PredicateRelation(livesIn, kirk, newyork)) The predicate may then be used as the relationship argument when querying -the relations registry. +the relation registry. >>> len(relations.query(relationship=livesIn, second=washington)) 1 diff --git a/relation/concepts.txt b/relation/concepts.txt index b4de85c..47f1dfb 100644 --- a/relation/concepts.txt +++ b/relation/concepts.txt @@ -35,7 +35,7 @@ I want to use. So the question arises what to do with the relation objects? The point here is not so much where to store them but how to make sure that we can find -them. So we need a registry for relations - interface IRelationsRegistry. +them. So we need a registry for relations - interface IRelationRegistry. This has three methods: @@ -62,9 +62,9 @@ Default Implementation ---------------------- You see that this looks very much like a catalog search - so why not implement -the relations registry as a subclass of Catalog (see zope.app.catalog). +the relation registry as a subclass of Catalog (see zope.app.catalog). -OK, so the RelationsRegistry class is derived from Catalog, and of course it is +OK, so the RelationRegistry class is derived from Catalog, and of course it is a local utility. The indexes are just FieldIndex objects, using an adapter to provide unique ids for the objects involved via the IntIds utility; the same is done for providing an id for the relation objects diff --git a/relation/configure.zcml b/relation/configure.zcml index 5a43d7c..6d32cd8 100644 --- a/relation/configure.zcml +++ b/relation/configure.zcml @@ -5,14 +5,14 @@ xmlns:browser="http://namespaces.zope.org/browser" i18n_domain="zope"> - + - + @@ -57,15 +57,15 @@ diff --git a/relation/interfaces.py b/relation/interfaces.py index 53a9d51..d2703d6 100644 --- a/relation/interfaces.py +++ b/relation/interfaces.py @@ -90,11 +90,11 @@ class IRelationInvalidatedEvent(IObjectEvent): """ -# relations registry interfaces +# relation registry interfaces -class IRelationsRegistryUpdate(Interface): +class IRelationRegistryUpdate(Interface): """ Interface for registering and unregistering relations with a - relations registry. + relation registry. """ def register(relation): @@ -105,9 +105,12 @@ class IRelationsRegistryUpdate(Interface): """ Remove the relation given from this registry. """ +#BBB +#IRelationsRegistryUpdate = IRelationRegistryUpdate -class IRelationsRegistryQuery(Interface): - """ Interface for querying a relations registry. + +class IRelationRegistryQuery(Interface): + """ Interface for querying a relation registry. """ def query(relation=None, **kw): @@ -122,10 +125,15 @@ class IRelationsRegistryQuery(Interface): rr.queryRelations(first=someObject, second=anotherObject, relationship=SomeRelationClass) """ +#BBB +#IRelationsRegistryQuery = IRelationRegistryQuery -class IRelationsRegistry(IRelationsRegistryUpdate, IRelationsRegistryQuery): +class IRelationRegistry(IRelationRegistryUpdate, IRelationRegistryQuery): """ A registry for registering and searching relations typically implemented as a local utility . """ +#BBB +#IRelationsRegistry = IRelationRegistry + diff --git a/relation/registry.py b/relation/registry.py index bec85a6..dd02ed8 100644 --- a/relation/registry.py +++ b/relation/registry.py @@ -34,14 +34,14 @@ from zope.event import notify from zope.app.event.objectevent import ObjectEvent from zope.security.proxy import removeSecurityProxy -from interfaces import IRelationsRegistry, IRelationInvalidatedEvent +from interfaces import IRelationRegistry, IRelationInvalidatedEvent -class DummyRelationsRegistry(object): +class DummyRelationRegistry(object): """ Dummy implementation for demonstration and test purposes. """ - implements(IRelationsRegistry) + implements(IRelationRegistry) def __init__(self): self.relations = [] @@ -69,12 +69,15 @@ class DummyRelationsRegistry(object): result.append(r) return result +#BBB +#DummyRelationsRegistry = DummyRelationRegistry -class RelationsRegistry(Catalog): + +class RelationRegistry(Catalog): """ Local utility for registering (cataloguing) and searching relations. """ - implements(IRelationsRegistry) + implements(IRelationRegistry) def setupIndexes(self): for idx in ('relationship', 'first', 'second', 'third'): @@ -101,6 +104,9 @@ class RelationsRegistry(Catalog): kw[k] = (quString, quString) return self.searchResults(**kw) +#BBB +#RelationsRegistry = RelationRegistry + class IIndexableRelation(Interface): @@ -140,7 +146,7 @@ def getRelations(first=None, second=None, third=None, relationships=None): The relationships parameter expects a sequence of relationships (relation classes or predicate objects). """ - registry = zapi.getUtility(IRelationsRegistry) + registry = zapi.getUtility(IRelationRegistry) query = {} if first is not None: query['first'] = first if second is not None: query['second'] = second @@ -166,15 +172,16 @@ def invalidateRelations(context, event): all relations the object to be removed is involved in. """ relations = [] - registry = zapi.getUtility(IRelationsRegistry) - for attr in ('first', 'second', 'third'): - relations = registry.query(**{attr: context}) - for relation in relations: - registry.unregister(relation) + registry = zapi.queryUtility(IRelationRegistry) + if registry is not None: + for attr in ('first', 'second', 'third'): + relations = registry.query(**{attr: context}) + for relation in relations: + registry.unregister(relation) def removeRelation(context, event): """ Handles IRelationInvalidatedEvent by removing the relation - (that should be already unregistered from the relations registry) + (that should be already unregistered from the relation registry) from its container (if appropriate) and the IntIds utility. """ if ILocation.providedBy(context): @@ -185,9 +192,9 @@ def removeRelation(context, event): intids.unregister(context) def setupIndexes(context, event): - """ Handles IObjectAdded event for the RelationsRegistry utility + """ Handles IObjectAdded event for the RelationRegistry utility and creates the indexes needed. """ - if isinstance(context, RelationsRegistry): + if isinstance(context, RelationRegistry): context.setupIndexes() diff --git a/relation/tests.py b/relation/tests.py index a3478c9..67f942d 100755 --- a/relation/tests.py +++ b/relation/tests.py @@ -11,8 +11,8 @@ from zope.app.intid.interfaces import IIntIds from cybertools.relation.interfaces import IDyadicRelation, ITriadicRelation from cybertools.relation.interfaces import IRelation, IPredicate from cybertools.relation import Relation, DyadicRelation, TriadicRelation -from cybertools.relation.interfaces import IRelationsRegistry -from cybertools.relation.registry import RelationsRegistry +from cybertools.relation.interfaces import IRelationRegistry +from cybertools.relation.registry import RelationRegistry class IntIdsStub: @@ -50,9 +50,9 @@ class TestRelation(unittest.TestCase): self.assert_(ITriadicRelation.providedBy(TriadicRelation(None, None, None)), 'Interface ITriadicRelation is not implemented by class TriadicRelation.') verifyClass(ITriadicRelation, TriadicRelation) - self.assert_(IRelationsRegistry.providedBy(RelationsRegistry()), - 'Interface IRelationsRegistry is not implemented by class RelationsRegistry.') - verifyClass(IRelationsRegistry, RelationsRegistry) + self.assert_(IRelationRegistry.providedBy(RelationRegistry()), + 'Interface IRelationRegistry is not implemented by class RelationRegistry.') + verifyClass(IRelationRegistry, RelationRegistry) def test_suite():