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:
parent
cb9dc6219f
commit
963a167f12
7 changed files with 64 additions and 29 deletions
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue