provide State query and fix bug in state event notification

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2561 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2008-04-27 20:55:02 +00:00
parent 883656bd1e
commit 45efbd3c6f
5 changed files with 71 additions and 24 deletions

View file

@ -27,7 +27,7 @@ configuration):
>>> concepts, resources, views = t.setup() >>> concepts, resources, views = t.setup()
>>> len(concepts) + len(resources) >>> len(concepts) + len(resources)
36 32
>>> loopsRoot = site['loops'] >>> loopsRoot = site['loops']
@ -47,11 +47,11 @@ Type- and text-based queries
>>> from loops.expert import query >>> from loops.expert import query
>>> qu = query.Title('ty*') >>> qu = query.Title('ty*')
>>> list(qu.apply()) >>> list(qu.apply())
[0, 1, 47] [0, 1, 45]
>>> qu = query.Type('loops:*') >>> qu = query.Type('loops:*')
>>> len(list(qu.apply())) >>> len(list(qu.apply()))
36 32
>>> qu = query.Type('loops:concept:predicate') >>> qu = query.Type('loops:concept:predicate')
>>> len(list(qu.apply())) >>> len(list(qu.apply()))
@ -61,6 +61,53 @@ Type- and text-based queries
>>> list(qu.apply()) >>> list(qu.apply())
[1] [1]
State-based queries
-------------------
>>> qu = query.State('loops.classification_quality', 'new')
>>> list(qu.apply())
[]
>>> from cybertools.stateful.publishing import simplePublishing
>>> component.provideUtility(simplePublishing(), name='loops.simple_publishing')
>>> from loops.organize.stateful.base import SimplePublishable
>>> component.provideAdapter(SimplePublishable, name='loops.simple_publishing')
>>> from loops.organize.stateful.quality import classificationQuality
>>> component.provideUtility(classificationQuality(),
... name='loops.classification_quality')
>>> from loops.organize.stateful.quality import ClassificationQualityCheckable
>>> component.provideAdapter(ClassificationQualityCheckable,
... name='loops.classification_quality')
>>> loopsRoot.options = ['organize.stateful.resource:'
... 'loops.classification_quality,loops.simple_publishing']
>>> from zope.app.catalog.interfaces import ICatalog
>>> catalog = component.getUtility(ICatalog)
>>> from loops import util
>>> for r in resources.values():
... catalog.index_doc(int(util.getUidForObject(r)), r)
>>> qu = query.State('loops.classification_quality', 'new')
>>> list(qu.apply())
[23, 25, 27]
>>> from cybertools.stateful.interfaces import IStateful
>>> statefulD001 = component.getAdapter(resources['d001.txt'], IStateful,
... name='loops.classification_quality')
>>> from loops.organize.stateful.base import handleTransition
>>> component.provideHandler(handleTransition)
>>> statefulD001.doTransition('classify')
>>> list(qu.apply())
[25, 27]
>>> qu = query.State('loops.classification_quality', 'classified')
>>> list(qu.apply())
[23]
Relationship-based queries Relationship-based queries
-------------------------- --------------------------
@ -69,10 +116,10 @@ relations to other objects the expert package provides methods
for selecting and filtering related objects using our basic querying for selecting and filtering related objects using our basic querying
syntax (that in turn is based on hurry.query). syntax (that in turn is based on hurry.query).
>>> stateNew = concepts['new'] >>> cust1 = concepts['cust1']
>>> qu = query.Resources(stateNew) >>> qu = query.Resources(cust1)
>>> list(qu.apply()) >>> list(qu.apply())
[25, 27] [23, 27]
Getting objects Getting objects
--------------- ---------------
@ -136,7 +183,7 @@ Organizing Queries and Filters with Query Instances
A query instance consists of A query instance consists of
- a base query (a composition of terms) - a base query (a composition of terms)
- one or more query filter that will be joined with the base query - one or more query filters that will be joined with the base query
- a result filter that will be applied to the result set of the - a result filter that will be applied to the result set of the
preceding steps preceding steps

View file

@ -23,8 +23,8 @@ $Id$
""" """
from BTrees.IIBTree import IITreeSet from BTrees.IIBTree import IITreeSet
from BTrees.IFBTree import IFBTree, IFTreeSet from BTrees.IFBTree import IFBucket, IFBTree, IFTreeSet
from BTrees.IOBTree import IOBTree from BTrees.IOBTree import IOBucket, IOBTree
from zope import interface, component from zope import interface, component
from zope.app.intid.interfaces import IIntIds from zope.app.intid.interfaces import IIntIds
from zope.component import adapts from zope.component import adapts
@ -33,6 +33,7 @@ from zope.cachedescriptors.property import Lazy
from cybertools.catalog.query import Term, Eq, Between from cybertools.catalog.query import Term, Eq, Between
from cybertools.catalog.query import Text as BaseText from cybertools.catalog.query import Text as BaseText
from cybertools.catalog.query import AnyOf
from loops.expert.interfaces import IQuery from loops.expert.interfaces import IQuery
from loops.security.common import canListObject from loops.security.common import canListObject
from loops import util from loops import util
@ -40,8 +41,11 @@ from loops import util
titleIndex = ('', 'loops_title') titleIndex = ('', 'loops_title')
textIndex = ('', 'loops_text') textIndex = ('', 'loops_text')
typeIndex = ('', 'loops_type') typeIndex = ('', 'loops_type')
stateIndex = ('', 'loops_state')
# standard text/field/keyword index queries
@implementer(IQuery) @implementer(IQuery)
def Title(value): def Title(value):
return BaseText(titleIndex, value) return BaseText(titleIndex, value)
@ -58,6 +62,12 @@ def Type(value):
return Between(typeIndex, v1, v2) return Between(typeIndex, v1, v2)
return Eq(typeIndex, value) return Eq(typeIndex, value)
@implementer(IQuery)
def State(statesDefinition, value):
return AnyOf(stateIndex, ':'.join((statesDefinition, value)))
# concept map queries
class ConceptMapTerm(Term): class ConceptMapTerm(Term):
@ -105,6 +115,8 @@ class Children(ConceptMapTerm):
self.getRecursive(c, result) self.getRecursive(c, result)
# utility functions
def getObjects(uids, root=None, checkPermission=canListObject): def getObjects(uids, root=None, checkPermission=canListObject):
intIds = component.getUtility(IIntIds) intIds = component.getUtility(IIntIds)
for uid in uids: for uid in uids:

View file

@ -44,8 +44,6 @@ class TestSite(BaseTestSite):
type=tType) type=tType)
tCustomer = addObject(concepts, Concept, 'customer', title=u'Customer', tCustomer = addObject(concepts, Concept, 'customer', title=u'Customer',
type=tType) type=tType)
tState = addObject(concepts, Concept, 'state', title=u'State',
type=tType)
tDocumentType = addObject(concepts, Concept, 'documenttype', tDocumentType = addObject(concepts, Concept, 'documenttype',
title=u'Document Type', type=tType) title=u'Document Type', type=tType)
dGeneral = addObject(concepts, Concept, 'general', dGeneral = addObject(concepts, Concept, 'general',
@ -53,7 +51,6 @@ class TestSite(BaseTestSite):
dProjects = addObject(concepts, Concept, 'projects', dProjects = addObject(concepts, Concept, 'projects',
title=u'Project Domain', type=tDomain) title=u'Project Domain', type=tDomain)
tCountry.assignParent(dGeneral) tCountry.assignParent(dGeneral)
tState.assignParent(dGeneral)
tCustomer.assignParent(dProjects) tCustomer.assignParent(dProjects)
tDocumentType.assignParent(dProjects) tDocumentType.assignParent(dProjects)
@ -70,12 +67,6 @@ class TestSite(BaseTestSite):
cust1.assignParent(countryDe) cust1.assignParent(countryDe)
cust2.assignParent(countryDe) cust2.assignParent(countryDe)
cust3.assignParent(countryUs) cust3.assignParent(countryUs)
stateNew = addObject(concepts, Concept, 'new',
title=u'New', type=tState)
stateReleased = addObject(concepts, Concept, 'released',
title=u'Released', type=tState)
stateObsolete = addObject(concepts, Concept, 'obsolete',
title=u'Obsolete', type=tState)
dtStudy = addObject(concepts, Concept, 'dt_study', dtStudy = addObject(concepts, Concept, 'dt_study',
title=u'Study', type=tDocumentType) title=u'Study', type=tDocumentType)
dtNote = addObject(concepts, Concept, 'dt_note', dtNote = addObject(concepts, Concept, 'dt_note',
@ -86,15 +77,12 @@ class TestSite(BaseTestSite):
d001 = resources['d001.txt'] d001 = resources['d001.txt']
d001.assignConcept(cust1) d001.assignConcept(cust1)
d001.assignConcept(stateReleased)
d001.assignConcept(dtNote) d001.assignConcept(dtNote)
d002 = resources['d002.txt'] d002 = resources['d002.txt']
d002.assignConcept(cust3) d002.assignConcept(cust3)
d002.assignConcept(stateNew)
d002.assignConcept(dtNote) d002.assignConcept(dtNote)
d003 = resources['d003.txt'] d003 = resources['d003.txt']
d003.assignConcept(cust1) d003.assignConcept(cust1)
d003.assignConcept(stateNew)
d003.assignConcept(dtStudy) d003.assignConcept(dtStudy)
catalog = component.getUtility(ICatalog) catalog = component.getUtility(ICatalog)

View file

@ -95,7 +95,7 @@ later.
... title='DocFive') ... title='DocFive')
When we change the concept assignments of the resource - i.e. its classification When we change the concept assignments of the resource - i.e. its classification
- the classification quality state changes automaticalls - the classification quality state changes automatically
>>> c01.assignResource(doc01) >>> c01.assignResource(doc01)
>>> qcheckedDoc01 = component.getAdapter(doc01, IStateful, >>> qcheckedDoc01 = component.getAdapter(doc01, IStateful,

View file

@ -61,9 +61,9 @@ class StatefulResourceIndexInfo(IndexInfo):
@adapter(IResource, ITransitionEvent) @adapter(IResource, ITransitionEvent)
def handleTransition(self, obj, event): def handleTransition(obj, event):
previous = event.previousState previous = event.previousState
next = event.transition.targetState next = event.transition.targetState
if next != previous: if next != previous:
cat = getUtility(ICatalog) cat = component.getUtility(ICatalog)
cat.index_doc(int(util.getUidForObject(obj)), obj) cat.index_doc(int(util.getUidForObject(obj)), obj)