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...
|
Yet Another Relations (Reference) Engine...
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
|
($Id$)
|
||||||
|
|
||||||
>>> from zope.app.testing.placelesssetup import setUp
|
>>> from zope.app.testing.placelesssetup import setUp
|
||||||
>>> setUp()
|
>>> setUp()
|
||||||
|
|
||||||
|
@ -122,19 +124,31 @@ working with events).
|
||||||
>>> from zope.app import zapi
|
>>> from zope.app import zapi
|
||||||
>>> relations = zapi.getUtility(IRelationsRegistry)
|
>>> relations = zapi.getUtility(IRelationsRegistry)
|
||||||
|
|
||||||
In real life the indexes needed will be set up manually after object creation
|
In real life the indexes needed will be set up via subscription to
|
||||||
or via subscription to IObjectCreatedEvent - here we have to do this
|
IObjectCreatedEvent - here we have to do this explicitly:
|
||||||
explicitly:
|
|
||||||
|
|
||||||
>>> relations.setupIndexes()
|
>>> relations.setupIndexes()
|
||||||
|
|
||||||
In order to register relations the objects that are referenced have to be
|
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
|
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 cybertools.relation.tests import IntIdsStub
|
||||||
>>> from zope.app.intid.interfaces import IIntIds
|
>>> from zope.app.intid.interfaces import IIntIds
|
||||||
>>> ztapi.provideUtility(IIntIds, IntIdsStub())
|
>>> 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
|
We also have to provide an adapter for the Relation objects that provides
|
||||||
the attributes needed for indexing:
|
the attributes needed for indexing:
|
||||||
|
|
|
@ -27,10 +27,19 @@ $Id$
|
||||||
|
|
||||||
from persistent import Persistent
|
from persistent import Persistent
|
||||||
from zope.interface import implements
|
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)
|
implements(IDyadicRelation)
|
||||||
|
|
||||||
|
@ -39,7 +48,7 @@ class DyadicRelation(Persistent):
|
||||||
self.second = second
|
self.second = second
|
||||||
|
|
||||||
|
|
||||||
class TriadicRelation(Persistent):
|
class TriadicRelation(Relation):
|
||||||
|
|
||||||
implements(ITriadicRelation)
|
implements(ITriadicRelation)
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<browser:addMenuItem
|
<browser:addMenuItem
|
||||||
title="Relations Registry Utility"
|
title="Relations 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.RelationsRegistry"
|
||||||
permission="zope.ManageSite"
|
permission="zope.ManageSite"
|
||||||
|
|
|
@ -30,7 +30,7 @@ class BrowserTest(FunctionalTestCase):
|
||||||
browser.addHeader('Accept-Language', 'en-US')
|
browser.addHeader('Accept-Language', 'en-US')
|
||||||
browser.open('http://localhost/++etc++site/default/@@contents.html')
|
browser.open('http://localhost/++etc++site/default/@@contents.html')
|
||||||
self.assert_(browser.isHtml)
|
self.assert_(browser.isHtml)
|
||||||
addLink = browser.getLink('Relations Registry Utility')
|
addLink = browser.getLink('Relations Registry')
|
||||||
addLink.click()
|
addLink.click()
|
||||||
self.assert_(browser.isHtml)
|
self.assert_(browser.isHtml)
|
||||||
inp = browser.getControl(name='new_value')
|
inp = browser.getControl(name='new_value')
|
||||||
|
|
|
@ -28,10 +28,26 @@ from zope.app.event.interfaces import IObjectEvent
|
||||||
|
|
||||||
# relation interfaces
|
# 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):
|
class IRelation(Interface):
|
||||||
""" Base interface for relations.
|
""" Base interface for relations.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def getPredicateName():
|
||||||
|
""" Return the predicate of this relation as a string that may be
|
||||||
|
used for indexing.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class IDyadicRelation(IRelation):
|
class IDyadicRelation(IRelation):
|
||||||
""" Relation connecting two objects.
|
""" Relation connecting two objects.
|
||||||
|
|
|
@ -80,18 +80,20 @@ class RelationsRegistry(Catalog):
|
||||||
self[idx] = FieldIndex(idx, IIndexableRelation)
|
self[idx] = FieldIndex(idx, IIndexableRelation)
|
||||||
|
|
||||||
def register(self, relation):
|
def register(self, relation):
|
||||||
#self.setupIndexes()
|
if getattr(relation, '__parent__', None) is None:
|
||||||
self.index_doc(_getUid(relation), relation)
|
# 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):
|
def unregister(self, relation):
|
||||||
self.unindex_doc(_getUid(relation))
|
self.unindex_doc(zapi.getUtility(IIntIds).getId(relation))
|
||||||
|
|
||||||
def query(self, **kw):
|
def query(self, **kw):
|
||||||
for k in kw:
|
for k in kw:
|
||||||
if k == 'relationship':
|
if k == 'relationship':
|
||||||
quString = _getClassString(kw[k])
|
quString = kw[k].getPredicateName()
|
||||||
else:
|
else:
|
||||||
quString = _getUid(kw[k])
|
quString = zapi.getUtility(IIntIds).getId(kw[k])
|
||||||
# set min, max
|
# set min, max
|
||||||
kw[k] = (quString, quString)
|
kw[k] = (quString, quString)
|
||||||
return self.searchResults(**kw)
|
return self.searchResults(**kw)
|
||||||
|
@ -115,29 +117,17 @@ class IndexableRelationAdapter(object):
|
||||||
self.context = context
|
self.context = context
|
||||||
|
|
||||||
def getRelationship(self):
|
def getRelationship(self):
|
||||||
return _getRelationship(self.context)
|
return self.context.getPredicateName()
|
||||||
relationship = property(getRelationship)
|
relationship = property(getRelationship)
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
value = getattr(self.context, attr)
|
value = getattr(self.context, attr)
|
||||||
if isinstance(value, Persistent):
|
if isinstance(value, Persistent):
|
||||||
return _getUid(value)
|
return zapi.getUtility(IIntIds).getId(value)
|
||||||
else:
|
else:
|
||||||
return value
|
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
|
# events and handlers
|
||||||
|
|
||||||
class RelationInvalidatedEvent(ObjectEvent):
|
class RelationInvalidatedEvent(ObjectEvent):
|
||||||
|
|
|
@ -9,7 +9,8 @@ from zope.app import zapi
|
||||||
from zope.app.intid.interfaces import IIntIds
|
from zope.app.intid.interfaces import IIntIds
|
||||||
|
|
||||||
from cybertools.relation.interfaces import IDyadicRelation, ITriadicRelation
|
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.interfaces import IRelationsRegistry
|
||||||
from cybertools.relation.registry import RelationsRegistry
|
from cybertools.relation.registry import RelationsRegistry
|
||||||
|
|
||||||
|
@ -25,6 +26,9 @@ class IntIdsStub:
|
||||||
return self.objs[uid]
|
return self.objs[uid]
|
||||||
|
|
||||||
def getId(self, ob):
|
def getId(self, ob):
|
||||||
|
return self.objs.index(ob)
|
||||||
|
|
||||||
|
def register(self, ob):
|
||||||
if ob not in self.objs:
|
if ob not in self.objs:
|
||||||
self.objs.append(ob)
|
self.objs.append(ob)
|
||||||
return self.objs.index(ob)
|
return self.objs.index(ob)
|
||||||
|
@ -38,6 +42,8 @@ class TestRelation(unittest.TestCase):
|
||||||
"Basic tests for the relation package."
|
"Basic tests for the relation package."
|
||||||
|
|
||||||
def testInterfaces(self):
|
def testInterfaces(self):
|
||||||
|
verifyClass(IPredicate, Relation)
|
||||||
|
verifyClass(IRelation, Relation)
|
||||||
self.assert_(IDyadicRelation.providedBy(DyadicRelation(None, None)),
|
self.assert_(IDyadicRelation.providedBy(DyadicRelation(None, None)),
|
||||||
'Interface IDyadicRelation is not implemented by class DyadicRelation.')
|
'Interface IDyadicRelation is not implemented by class DyadicRelation.')
|
||||||
verifyClass(IDyadicRelation, DyadicRelation)
|
verifyClass(IDyadicRelation, DyadicRelation)
|
||||||
|
|
Loading…
Add table
Reference in a new issue