relation: some minor changes; + __parent__ assignment for relation when registering it

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@668 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2005-11-09 11:21:56 +00:00
parent cb9dc6219f
commit 963a167f12
7 changed files with 64 additions and 29 deletions

View file

@ -1,6 +1,8 @@
Yet Another Relations (Reference) Engine...
===========================================
($Id$)
>>> from zope.app.testing.placelesssetup import setUp
>>> setUp()
@ -122,19 +124,31 @@ working with events).
>>> from zope.app import zapi
>>> relations = zapi.getUtility(IRelationsRegistry)
In real life the indexes needed will be set up manually after object creation
or via subscription to IObjectCreatedEvent - here we have to do this
explicitly:
In real life the indexes needed will be set up via subscription to
IObjectCreatedEvent - here we have to do this explicitly:
>>> relations.setupIndexes()
In order to register relations the objects that are referenced have to be
registered with an IntIds (unique ids) utility, so we have to set up such
an utility (using a stub/dummy implementation for testing purposes):
an utility (using a stub/dummy implementation for testing purposes) and
register the objects with it (in real life this is done automatically
when we add an object to a container):
>>> from cybertools.relation.tests import IntIdsStub
>>> from zope.app.intid.interfaces import IIntIds
>>> ztapi.provideUtility(IIntIds, IntIdsStub())
>>> intids = zapi.getUtility(IIntIds)
>>> intids.register(clark)
0
>>> intids.register(kirk)
1
>>> intids.register(audrey)
2
>>> intids.register(washington)
3
>>> intids.register(newyork)
4
We also have to provide an adapter for the Relation objects that provides
the attributes needed for indexing:

View file

@ -27,10 +27,19 @@ $Id$
from persistent import Persistent
from zope.interface import implements
from interfaces import IDyadicRelation, ITriadicRelation
from interfaces import IPredicate
from interfaces import IRelation, IDyadicRelation, ITriadicRelation
class Relation(Persistent):
implements(IPredicate, IRelation)
@classmethod
def getPredicateName(cls):
return '%s.%s' % (cls.__module__, cls.__name__)
class DyadicRelation(Persistent):
class DyadicRelation(Relation):
implements(IDyadicRelation)
@ -39,7 +48,7 @@ class DyadicRelation(Persistent):
self.second = second
class TriadicRelation(Persistent):
class TriadicRelation(Relation):
implements(ITriadicRelation)

View file

@ -63,7 +63,7 @@
/>
<browser:addMenuItem
title="Relations Registry Utility"
title="Relations Registry"
description="A utility that allows the registration of and query for relations"
class=".registry.RelationsRegistry"
permission="zope.ManageSite"

View file

@ -30,7 +30,7 @@ class BrowserTest(FunctionalTestCase):
browser.addHeader('Accept-Language', 'en-US')
browser.open('http://localhost/++etc++site/default/@@contents.html')
self.assert_(browser.isHtml)
addLink = browser.getLink('Relations Registry Utility')
addLink = browser.getLink('Relations Registry')
addLink.click()
self.assert_(browser.isHtml)
inp = browser.getControl(name='new_value')

View file

@ -28,10 +28,26 @@ from zope.app.event.interfaces import IObjectEvent
# relation interfaces
class IPredicate(Interface):
""" A predicate signifies a relationship. This may be implemented
directly as a relation class, or the relation object may
hold the predicate as an attribute.
"""
def getPredicateName():
""" Return this predicate as a string that may be used for indexing.
"""
class IRelation(Interface):
""" Base interface for relations.
"""
def getPredicateName():
""" Return the predicate of this relation as a string that may be
used for indexing.
"""
class IDyadicRelation(IRelation):
""" Relation connecting two objects.

View file

@ -80,18 +80,20 @@ class RelationsRegistry(Catalog):
self[idx] = FieldIndex(idx, IIndexableRelation)
def register(self, relation):
#self.setupIndexes()
self.index_doc(_getUid(relation), relation)
if getattr(relation, '__parent__', None) is None:
# Allow the IntIds utility to get a DB connection:
relation.__parent__ = self
self.index_doc(zapi.getUtility(IIntIds).register(relation), relation)
def unregister(self, relation):
self.unindex_doc(_getUid(relation))
self.unindex_doc(zapi.getUtility(IIntIds).getId(relation))
def query(self, **kw):
for k in kw:
if k == 'relationship':
quString = _getClassString(kw[k])
quString = kw[k].getPredicateName()
else:
quString = _getUid(kw[k])
quString = zapi.getUtility(IIntIds).getId(kw[k])
# set min, max
kw[k] = (quString, quString)
return self.searchResults(**kw)
@ -115,29 +117,17 @@ class IndexableRelationAdapter(object):
self.context = context
def getRelationship(self):
return _getRelationship(self.context)
return self.context.getPredicateName()
relationship = property(getRelationship)
def __getattr__(self, attr):
value = getattr(self.context, attr)
if isinstance(value, Persistent):
return _getUid(value)
return zapi.getUtility(IIntIds).getId(value)
else:
return value
# helper functions
def _getUid(ob):
return zapi.getUtility(IIntIds).getId(ob)
def _getRelationship(relation):
return _getClassString(removeSecurityProxy(relation).__class__)
def _getClassString(cls):
return '%s.%s' % (cls.__module__, cls.__name__)
# events and handlers
class RelationInvalidatedEvent(ObjectEvent):

View file

@ -9,7 +9,8 @@ from zope.app import zapi
from zope.app.intid.interfaces import IIntIds
from cybertools.relation.interfaces import IDyadicRelation, ITriadicRelation
from cybertools.relation import DyadicRelation, TriadicRelation
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
@ -25,6 +26,9 @@ class IntIdsStub:
return self.objs[uid]
def getId(self, ob):
return self.objs.index(ob)
def register(self, ob):
if ob not in self.objs:
self.objs.append(ob)
return self.objs.index(ob)
@ -38,6 +42,8 @@ class TestRelation(unittest.TestCase):
"Basic tests for the relation package."
def testInterfaces(self):
verifyClass(IPredicate, Relation)
verifyClass(IRelation, Relation)
self.assert_(IDyadicRelation.providedBy(DyadicRelation(None, None)),
'Interface IDyadicRelation is not implemented by class DyadicRelation.')
verifyClass(IDyadicRelation, DyadicRelation)