From 2f70bb2ce5cfddbcd1d6e3399c4e20ace57e6db8 Mon Sep 17 00:00:00 2001 From: helmutm Date: Wed, 2 Nov 2005 13:34:27 +0000 Subject: [PATCH] relation package now with a relations registry using catalog indexes git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@650 fd906abe-77d9-0310-91a1-e0d9ade77398 --- relation/README.txt | 28 ++++++++++++++++++++++- relation/registry.py | 53 +++++++++++++++++++++++++++++++++----------- relation/tests.py | 18 +++++++++++++++ 3 files changed, 85 insertions(+), 14 deletions(-) diff --git a/relation/README.txt b/relation/README.txt index 3f2cf85..28a7867 100644 --- a/relation/README.txt +++ b/relation/README.txt @@ -88,7 +88,8 @@ When we search for relations that contain clark as first we get both: So we want to look only for ParentsOf relationships - this should give us all relations for clark's children: - >>> clarkChildren = relations.query(relationship=ParentsOf, first=clark) + >>> clarkChildren = relations.query(relationship=ParentsOf, + ... first=clark) >>> len(clarkChildren) 1 >>> clarkChildren[0].second == audrey @@ -99,3 +100,28 @@ all relations for clark's children: Setting up and using a RelationsRegistry local utility ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We now do the same stuff as above with a real, catalog-based implementation of +the relations registry. + + >>> from cybertools.relation.registry import RelationsRegistry + >>> relations = RelationsRegistry() + +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): + + >>> from cybertools.relation.tests import IntIdsStub + >>> from zope.app.intid.interfaces import IIntIds + >>> from zope.app.testing import ztapi + >>> ztapi.provideUtility(IIntIds, IntIdsStub()) + +So we are ready again to register a set of relations with our new relations +registry and query it: + + >>> relations.register(LivesIn(clark, washington)) + >>> relations.register(LivesIn(audrey, newyork)) + >>> relations.register(LivesIn(kirk, newyork)) + + >>> clarkRels = relations.query(first=clark) + >>> len(clarkRels) + 1 diff --git a/relation/registry.py b/relation/registry.py index 0dc3abd..fb2b14d 100644 --- a/relation/registry.py +++ b/relation/registry.py @@ -24,8 +24,9 @@ $Id$ from zope.interface import implements from zope.app import zapi -from persistent import Persistent -from zope.app.container.contained import Contained +from zope.app.catalog.catalog import Catalog +from zope.index.field import FieldIndex +from zope.app.intid.interfaces import IIntIds from interfaces import IRelationsRegistry @@ -52,11 +53,9 @@ class DummyRelationsRegistry(object): for r in self.relations: hit = True for k in kw: - if k == 'relationship': - if kw[k] != r.__class__: - hit = False - break - elif not hasattr(r, k) or getattr(r, k) != kw[k]: + if ((k == 'relationship' and r.__class__ != kw[k]) + or (k != 'relationship' + and (not hasattr(r, k) or getattr(r, k) != kw[k]))): hit = False break if hit: @@ -64,20 +63,48 @@ class DummyRelationsRegistry(object): return result -class RelationsRegistry(Persistent, Contained): +class RelationsRegistry(Catalog): """ Local utility for registering (cataloguing) and searching relations. """ implements(IRelationsRegistry) + def __init__(self, *args, **kwargs): + Catalog.__init__(self, *args, **kwargs) + self['relationship'] = FieldIndex() + self['first'] = FieldIndex() + self['second'] = FieldIndex() + self['third'] = FieldIndex() + def register(self, relation): - pass + relid = self._getUid(relation) + for idx in self: + index = self[idx] + if idx == 'relationship': + index.index_doc(relid, self._getRelationship(relation)) + else: + target = getattr(relation, idx, None) + index.index_doc(relid, target and self._getUid(target)) def unregister(self, relation): - pass + self.unindex_doc(self._getUid(relation)) def query(self, **kw): - result = [] - return result + for k in kw: + if k == 'relationship': + quString = self._getClassString(kw[k]) + else: + quString = self._getUid(kw[k]) + # set min, max + kw[k] = (quString, quString) + return self.searchResults(**kw) - \ No newline at end of file + def _getUid(self, ob): + return zapi.getUtility(IIntIds).getId(ob) + + def _getRelationship(self, relation): + return self._getClassString(relation.__class__) + + def _getClassString(self, cls): + return cls.__module__ + '.' + cls.__name__ + diff --git a/relation/tests.py b/relation/tests.py index 0ec936f..e0a46c0 100755 --- a/relation/tests.py +++ b/relation/tests.py @@ -4,7 +4,9 @@ import unittest from zope.testing.doctestunit import DocFileSuite from zope.app.testing import ztapi from zope.interface.verify import verifyClass +from zope.interface import implements 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 @@ -12,6 +14,22 @@ from cybertools.relation.interfaces import IRelationsRegistry from cybertools.relation.registry import RelationsRegistry +class IntIdsStub: + """A testing stub (mock utility) for IntIds.""" + implements(IIntIds) + + def __init__(self): + self.objs = [] + + def getObject(self, uid): + return self.objs[uid] + + def getId(self, ob): + if ob not in self.objs: + self.objs.append(ob) + return self.objs.index(ob) + + class TestRelation(unittest.TestCase): "Basic tests for the relation package."