From db8d38e7cb19378eb7b07532e2e715c0dd6773a8 Mon Sep 17 00:00:00 2001 From: helmutm Date: Fri, 11 Nov 2005 10:18:24 +0000 Subject: [PATCH] Added 'Named Predicate' example to README.txt git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@673 fd906abe-77d9-0310-91a1-e0d9ade77398 --- relation/README.txt | 48 ++++++++++++++++++++++++++++++++++++++++++++ relation/registry.py | 6 +++--- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/relation/README.txt b/relation/README.txt index be4ad49..888cbc8 100644 --- a/relation/README.txt +++ b/relation/README.txt @@ -257,3 +257,51 @@ Thus there should only remain one relation containing clark as first: >>> len(relations.query(first=clark)) 1 + +Named Predicates +~~~~~~~~~~~~~~~~ + +Up to now we had to create a new class for each relationship we want to use. +This is also the way the standard implementation works. + +But often it is desirable to create new relationships on the fly by +providing some string as the name of the relationship. This can be done by +creating a special relation class that uses named predicates. + + >>> class PredicateRelation(DyadicRelation): + ... def __init__(self, predicate, first, second): + ... self.predicate = predicate + ... self.first = first + ... self.second = second + ... def getPredicateName(self): + ... return self.predicate.getPredicateName() + +We also need a class for the predicate objects that will be used for +the constructor of the NamedPredicateRelation class: + + >>> from cybertools.relation.interfaces import IPredicate + >>> from zope.interface import implements + + >>> class Predicate(object): + ... implements(IPredicate) + ... def __init__(self, name): + ... self.name = name + ... def getPredicateName(self): + ... return self.name + +We can now create a predicate with the name '_lives in_' (that may replace +our LivesIn relation class from above) and use for registration: + + >>> livesIn = Predicate('_ lives in _') + + >>> relations.register(PredicateRelation(livesIn, clark, washington)) + >>> relations.register(PredicateRelation(livesIn, audrey, newyork)) + >>> relations.register(PredicateRelation(livesIn, kirk, newyork)) + +The predicate may then be used as the relationship argument when querying +the relations registry. + + >>> len(relations.query(relationship=livesIn, second=washington)) + 1 + >>> len(relations.query(relationship=livesIn, second=newyork)) + 2 diff --git a/relation/registry.py b/relation/registry.py index eaafca8..ec36469 100644 --- a/relation/registry.py +++ b/relation/registry.py @@ -23,6 +23,7 @@ $Id$ """ from persistent import Persistent +from persistent.interfaces import IPersistent from zope.interface import Interface, Attribute, implements from zope.app import zapi from zope.app.catalog.catalog import Catalog @@ -122,7 +123,7 @@ class IndexableRelationAdapter(object): def __getattr__(self, attr): value = getattr(self.context, attr) - if isinstance(value, Persistent): + if IPersistent.providedBy(value): return zapi.getUtility(IIntIds).getId(value) else: return value @@ -160,10 +161,9 @@ def removeRelation(context, event): intids.unregister(context) def setupIndexes(context, event): - """ Handles IObjectCreated event for the RelationsRegistry utility + """ Handles IObjectAdded event for the RelationsRegistry utility and creates the indexes needed. """ if isinstance(context, RelationsRegistry): context.setupIndexes() -