Renamed *RelationsRegistry* to *RelationRegistry*
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1065 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
5004253f98
commit
2011cf593d
6 changed files with 68 additions and 53 deletions
|
@ -4,7 +4,7 @@ Quickstart Instructions
|
||||||
($Id$)
|
($Id$)
|
||||||
|
|
||||||
In the ++etc++/default folder of your Zope 3 site create a Unique Id Utility
|
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
|
In your application
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@ In your application
|
||||||
``MyRelation(object1, object2)``.
|
``MyRelation(object1, object2)``.
|
||||||
|
|
||||||
- register these relation objects by getting a utility providing
|
- 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.
|
``query()`` method as described below.
|
||||||
|
|
||||||
You may also like to read the file concepts.txt that gives you some more basic
|
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):
|
>>> class LivesIn(DyadicRelation):
|
||||||
... pass
|
... pass
|
||||||
|
|
||||||
We don't directly keep track of relations but use a relations registry for
|
We don't directly keep track of relations but use a relation registry for
|
||||||
this. The relations registry is usually a local utility; for testing we use
|
this. The relation registry is usually a local utility; for testing we use
|
||||||
a simple dummy implementation:
|
a simple dummy implementation:
|
||||||
|
|
||||||
>>> from cybertools.relation.registry import DummyRelationsRegistry
|
>>> from cybertools.relation.registry import DummyRelationRegistry
|
||||||
>>> relations = DummyRelationsRegistry()
|
>>> relations = DummyRelationRegistry()
|
||||||
|
|
||||||
So we are ready to connect a person and a city using the LivesIn relationship:
|
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(audrey, newyork))
|
||||||
>>> relations.register(LivesIn(kirk, 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
|
who lives in New York. For this we use the standard attributes of dyadic
|
||||||
relations, first and second:
|
relations, first and second:
|
||||||
|
|
||||||
|
@ -183,21 +183,21 @@ all relations for clark's children:
|
||||||
True
|
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
|
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
|
utility for demonstration purposes (and to be able to use it later when
|
||||||
working with events).
|
working with events).
|
||||||
|
|
||||||
>>> from cybertools.relation.registry import RelationsRegistry
|
>>> from cybertools.relation.registry import RelationRegistry
|
||||||
>>> from cybertools.relation.interfaces import IRelationsRegistry
|
>>> from cybertools.relation.interfaces import IRelationRegistry
|
||||||
>>> from zope.app.testing import ztapi
|
>>> from zope.app.testing import ztapi
|
||||||
>>> ztapi.provideUtility(IRelationsRegistry, RelationsRegistry())
|
>>> ztapi.provideUtility(IRelationRegistry, RelationRegistry())
|
||||||
|
|
||||||
>>> from zope.app import zapi
|
>>> 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
|
In real life the indexes needed will be set up via subscription to
|
||||||
IObjectCreatedEvent - here we have to do this explicitly:
|
IObjectCreatedEvent - here we have to do this explicitly:
|
||||||
|
@ -281,7 +281,7 @@ It should work also for triadic relations:
|
||||||
True
|
True
|
||||||
|
|
||||||
There is also a convenience function that it makes even easier to query
|
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
|
>>> from cybertools.relation.registry import getRelations
|
||||||
>>> len(getRelations(first=clark))
|
>>> len(getRelations(first=clark))
|
||||||
|
@ -383,7 +383,7 @@ our LivesIn relation class from above) and use for registration:
|
||||||
>>> relations.register(PredicateRelation(livesIn, kirk, newyork))
|
>>> relations.register(PredicateRelation(livesIn, kirk, newyork))
|
||||||
|
|
||||||
The predicate may then be used as the relationship argument when querying
|
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))
|
>>> len(relations.query(relationship=livesIn, second=washington))
|
||||||
1
|
1
|
||||||
|
|
|
@ -35,7 +35,7 @@ I want to use.
|
||||||
|
|
||||||
So the question arises what to do with the relation objects? The point here
|
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
|
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:
|
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
|
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
|
a local utility. The indexes are just FieldIndex objects, using an adapter
|
||||||
to provide unique ids for the objects involved via the IntIds
|
to provide unique ids for the objects involved via the IntIds
|
||||||
utility; the same is done for providing an id for the relation objects
|
utility; the same is done for providing an id for the relation objects
|
||||||
|
|
|
@ -5,14 +5,14 @@
|
||||||
xmlns:browser="http://namespaces.zope.org/browser"
|
xmlns:browser="http://namespaces.zope.org/browser"
|
||||||
i18n_domain="zope">
|
i18n_domain="zope">
|
||||||
|
|
||||||
<localUtility class=".registry.RelationsRegistry">
|
<localUtility class=".registry.RelationRegistry">
|
||||||
<require
|
<require
|
||||||
permission="zope.View"
|
permission="zope.View"
|
||||||
interface=".interfaces.IRelationsRegistryQuery"
|
interface=".interfaces.IRelationRegistryQuery"
|
||||||
/>
|
/>
|
||||||
<require
|
<require
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent"
|
||||||
interface=".interfaces.IRelationsRegistryUpdate"
|
interface=".interfaces.IRelationRegistryUpdate"
|
||||||
/>
|
/>
|
||||||
<require
|
<require
|
||||||
interface="zope.app.catalog.interfaces.ICatalogQuery"
|
interface="zope.app.catalog.interfaces.ICatalogQuery"
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
interface="zope.app.container.interfaces.IContainer"
|
interface="zope.app.container.interfaces.IContainer"
|
||||||
permission="zope.ManageServices"
|
permission="zope.ManageServices"
|
||||||
/>
|
/>
|
||||||
<factory id="cybertools.relation.registry.RelationsRegistry" />
|
<factory id="cybertools.relation.registry.RelationRegistry" />
|
||||||
</localUtility>
|
</localUtility>
|
||||||
|
|
||||||
<adapter
|
<adapter
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<subscriber
|
<subscriber
|
||||||
for=".interfaces.IRelationsRegistry
|
for=".interfaces.IRelationRegistry
|
||||||
zope.app.container.interfaces.IObjectAddedEvent"
|
zope.app.container.interfaces.IObjectAddedEvent"
|
||||||
handler=".registry.setupIndexes"
|
handler=".registry.setupIndexes"
|
||||||
/>
|
/>
|
||||||
|
@ -57,15 +57,15 @@
|
||||||
<!-- browser settings -->
|
<!-- browser settings -->
|
||||||
|
|
||||||
<browser:tool
|
<browser:tool
|
||||||
interface=".interfaces.IRelationsRegistry"
|
interface=".interfaces.IRelationRegistry"
|
||||||
title="Relations Registry"
|
title="Relation Registry"
|
||||||
description="Registry for relation objects."
|
description="Registry for relation objects."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<browser:addMenuItem
|
<browser:addMenuItem
|
||||||
title="Relations Registry"
|
title="Relation Registry"
|
||||||
description="A utility that allows the registration of and query for relations"
|
description="A utility that allows the registration of and query for relations"
|
||||||
class=".registry.RelationsRegistry"
|
class=".registry.RelationRegistry"
|
||||||
permission="zope.ManageSite"
|
permission="zope.ManageSite"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -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
|
""" Interface for registering and unregistering relations with a
|
||||||
relations registry.
|
relation registry.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def register(relation):
|
def register(relation):
|
||||||
|
@ -105,9 +105,12 @@ class IRelationsRegistryUpdate(Interface):
|
||||||
""" Remove the relation given from this registry.
|
""" 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):
|
def query(relation=None, **kw):
|
||||||
|
@ -122,10 +125,15 @@ class IRelationsRegistryQuery(Interface):
|
||||||
rr.queryRelations(first=someObject, second=anotherObject,
|
rr.queryRelations(first=someObject, second=anotherObject,
|
||||||
relationship=SomeRelationClass)
|
relationship=SomeRelationClass)
|
||||||
"""
|
"""
|
||||||
|
#BBB
|
||||||
|
#IRelationsRegistryQuery = IRelationRegistryQuery
|
||||||
|
|
||||||
|
|
||||||
class IRelationsRegistry(IRelationsRegistryUpdate, IRelationsRegistryQuery):
|
class IRelationRegistry(IRelationRegistryUpdate, IRelationRegistryQuery):
|
||||||
""" A registry for registering and searching relations typically
|
""" A registry for registering and searching relations typically
|
||||||
implemented as a local utility .
|
implemented as a local utility .
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
#BBB
|
||||||
|
#IRelationsRegistry = IRelationRegistry
|
||||||
|
|
||||||
|
|
|
@ -34,14 +34,14 @@ from zope.event import notify
|
||||||
from zope.app.event.objectevent import ObjectEvent
|
from zope.app.event.objectevent import ObjectEvent
|
||||||
from zope.security.proxy import removeSecurityProxy
|
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.
|
""" Dummy implementation for demonstration and test purposes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
implements(IRelationsRegistry)
|
implements(IRelationRegistry)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.relations = []
|
self.relations = []
|
||||||
|
@ -69,12 +69,15 @@ class DummyRelationsRegistry(object):
|
||||||
result.append(r)
|
result.append(r)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
#BBB
|
||||||
|
#DummyRelationsRegistry = DummyRelationRegistry
|
||||||
|
|
||||||
class RelationsRegistry(Catalog):
|
|
||||||
|
class RelationRegistry(Catalog):
|
||||||
""" Local utility for registering (cataloguing) and searching relations.
|
""" Local utility for registering (cataloguing) and searching relations.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
implements(IRelationsRegistry)
|
implements(IRelationRegistry)
|
||||||
|
|
||||||
def setupIndexes(self):
|
def setupIndexes(self):
|
||||||
for idx in ('relationship', 'first', 'second', 'third'):
|
for idx in ('relationship', 'first', 'second', 'third'):
|
||||||
|
@ -101,6 +104,9 @@ class RelationsRegistry(Catalog):
|
||||||
kw[k] = (quString, quString)
|
kw[k] = (quString, quString)
|
||||||
return self.searchResults(**kw)
|
return self.searchResults(**kw)
|
||||||
|
|
||||||
|
#BBB
|
||||||
|
#RelationsRegistry = RelationRegistry
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class IIndexableRelation(Interface):
|
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
|
The relationships parameter expects a sequence of relationships
|
||||||
(relation classes or predicate objects).
|
(relation classes or predicate objects).
|
||||||
"""
|
"""
|
||||||
registry = zapi.getUtility(IRelationsRegistry)
|
registry = zapi.getUtility(IRelationRegistry)
|
||||||
query = {}
|
query = {}
|
||||||
if first is not None: query['first'] = first
|
if first is not None: query['first'] = first
|
||||||
if second is not None: query['second'] = second
|
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.
|
all relations the object to be removed is involved in.
|
||||||
"""
|
"""
|
||||||
relations = []
|
relations = []
|
||||||
registry = zapi.getUtility(IRelationsRegistry)
|
registry = zapi.queryUtility(IRelationRegistry)
|
||||||
for attr in ('first', 'second', 'third'):
|
if registry is not None:
|
||||||
relations = registry.query(**{attr: context})
|
for attr in ('first', 'second', 'third'):
|
||||||
for relation in relations:
|
relations = registry.query(**{attr: context})
|
||||||
registry.unregister(relation)
|
for relation in relations:
|
||||||
|
registry.unregister(relation)
|
||||||
|
|
||||||
def removeRelation(context, event):
|
def removeRelation(context, event):
|
||||||
""" Handles IRelationInvalidatedEvent by removing the relation
|
""" 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.
|
from its container (if appropriate) and the IntIds utility.
|
||||||
"""
|
"""
|
||||||
if ILocation.providedBy(context):
|
if ILocation.providedBy(context):
|
||||||
|
@ -185,9 +192,9 @@ def removeRelation(context, event):
|
||||||
intids.unregister(context)
|
intids.unregister(context)
|
||||||
|
|
||||||
def setupIndexes(context, event):
|
def setupIndexes(context, event):
|
||||||
""" Handles IObjectAdded event for the RelationsRegistry utility
|
""" Handles IObjectAdded event for the RelationRegistry utility
|
||||||
and creates the indexes needed.
|
and creates the indexes needed.
|
||||||
"""
|
"""
|
||||||
if isinstance(context, RelationsRegistry):
|
if isinstance(context, RelationRegistry):
|
||||||
context.setupIndexes()
|
context.setupIndexes()
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ from zope.app.intid.interfaces import IIntIds
|
||||||
from cybertools.relation.interfaces import IDyadicRelation, ITriadicRelation
|
from cybertools.relation.interfaces import IDyadicRelation, ITriadicRelation
|
||||||
from cybertools.relation.interfaces import IRelation, IPredicate
|
from cybertools.relation.interfaces import IRelation, IPredicate
|
||||||
from cybertools.relation import Relation, DyadicRelation, TriadicRelation
|
from cybertools.relation import Relation, DyadicRelation, TriadicRelation
|
||||||
from cybertools.relation.interfaces import IRelationsRegistry
|
from cybertools.relation.interfaces import IRelationRegistry
|
||||||
from cybertools.relation.registry import RelationsRegistry
|
from cybertools.relation.registry import RelationRegistry
|
||||||
|
|
||||||
|
|
||||||
class IntIdsStub:
|
class IntIdsStub:
|
||||||
|
@ -50,9 +50,9 @@ class TestRelation(unittest.TestCase):
|
||||||
self.assert_(ITriadicRelation.providedBy(TriadicRelation(None, None, None)),
|
self.assert_(ITriadicRelation.providedBy(TriadicRelation(None, None, None)),
|
||||||
'Interface ITriadicRelation is not implemented by class TriadicRelation.')
|
'Interface ITriadicRelation is not implemented by class TriadicRelation.')
|
||||||
verifyClass(ITriadicRelation, TriadicRelation)
|
verifyClass(ITriadicRelation, TriadicRelation)
|
||||||
self.assert_(IRelationsRegistry.providedBy(RelationsRegistry()),
|
self.assert_(IRelationRegistry.providedBy(RelationRegistry()),
|
||||||
'Interface IRelationsRegistry is not implemented by class RelationsRegistry.')
|
'Interface IRelationRegistry is not implemented by class RelationRegistry.')
|
||||||
verifyClass(IRelationsRegistry, RelationsRegistry)
|
verifyClass(IRelationRegistry, RelationRegistry)
|
||||||
|
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
|
|
Loading…
Add table
Reference in a new issue