diff --git a/expert/README.txt b/expert/README.txt index 0c26af1..2275004 100644 --- a/expert/README.txt +++ b/expert/README.txt @@ -16,62 +16,56 @@ Setting up a loops Site and Utilities Let's do some basic set up + >>> from zope import component, interface >>> from zope.app.testing.setup import placefulSetUp, placefulTearDown >>> site = placefulSetUp(True) - >>> from zope import component, interface - and build a simple loops site with a concept manager and some concepts (with a relation registry, a catalog, and all the type machinery - what -in real life is done via standard ZCML setup): +in real life is done via standard ZCML setup or via local utility +configuration): - >>> from cybertools.relation.tests import IntIdsStub - >>> component.provideUtility(IntIdsStub()) - >>> from cybertools.relation.registry import RelationRegistry - >>> from cybertools.relation.interfaces import IRelationRegistry - >>> relations = RelationRegistry() - >>> relations.setupIndexes() - >>> component.provideUtility(relations, IRelationRegistry) - - >>> from loops.type import ConceptType, TypeConcept - >>> component.provideAdapter(ConceptType) - >>> component.provideAdapter(TypeConcept) - - >>> from zope.app.catalog.catalog import Catalog - >>> catalog = Catalog() - >>> from zope.app.catalog.interfaces import ICatalog - >>> component.provideUtility(catalog, ICatalog) - - >>> from zope.app.catalog.field import FieldIndex - >>> from zope.app.catalog.text import TextIndex - >>> from loops.interfaces import IIndexAttributes - >>> catalog['loops_title'] = TextIndex('title', IIndexAttributes) - >>> catalog['loops_text'] = TextIndex('text', IIndexAttributes) - >>> catalog['loops_type'] = TextIndex('type', IIndexAttributes) - - >>> from loops import Loops - >>> loopsRoot = site['loops'] = Loops() - - >>> from loops.knowledge.setup import SetupManager - >>> component.provideAdapter(SetupManager, name='knowledge') - >>> from loops.setup import SetupManager - >>> setup = SetupManager(loopsRoot) - >>> concepts, resources, views = setup.setup() - - >>> from loops import util - >>> from loops.concept import IndexAttributes - >>> component.provideAdapter(IndexAttributes) - - >>> from loops.concept import Concept - - >>> for c in concepts: - ... catalog.index_doc(util.getUidForObject(c), c) + >>> from loops.expert.testsetup import TestSite + >>> t = TestSite(site) + >>> concepts, resources, views = t.setup() >>> #sorted(concepts) + >>> #sorted(resources) + >>> len(concepts) + len(resources) + 35 + + >>> #from zope.app.catalog.interfaces import ICatalog + >>> #sorted(component.getUtility(ICatalog).keys()) -Text Queries -============ +Type- and Text-based Queries +============================ + + >>> from loops.expert import query + >>> t = query.Title('ty*') + >>> list(t.apply()) + [0, 1, 39] + + >>> t = query.Type('loops:*') + >>> len(list(t.apply())) + 35 + + >>> t = query.Type('loops:concept:predicate') + >>> len(list(t.apply())) + 6 + + >>> t = query.Type('loops:concept:predicate') & query.Title('t*') + >>> list(t.apply()) + [1] + + +Relationship-based Queries +========================== + +In addition to the simple methods of concepts and resources for accessing +relations to other objects the expert package provides methods +for selecting and filtering related objects using our basic querying +syntax (that in turn is based on hurry.query). Fin de partie diff --git a/expert/query.py b/expert/query.py index 65a79c7..d71c0ef 100644 --- a/expert/query.py +++ b/expert/query.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2006 Helmut Merz helmutm@cy55.de +# Copyright (c) 2007 Helmut Merz helmutm@cy55.de # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -23,8 +23,29 @@ $Id$ """ from zope import interface, component -from zope.app import zapi from zope.component import adapts from zope.interface import implements from zope.cachedescriptors.property import Lazy +from hurry.query.query import Text as BaseText +from hurry.query.query import Eq, Between + + +titleIndex = ('', 'loops_title') +textIndex = ('', 'loops_text') +typeIndex = ('', 'loops_type') + + +def Title(value): + return BaseText(titleIndex, value) + +def Text(value): + return BaseText(textIndex, value) + +def Type(value): + if value.endswith('*'): + v1 = value[:-1] + v2 = value[:-1] + '\x7f' + return Between(typeIndex, v1, v2) + return Eq(typeIndex, value) + diff --git a/setup.py b/setup.py index 2ad80e1..fead5f0 100644 --- a/setup.py +++ b/setup.py @@ -94,11 +94,15 @@ class SetupManager(object): standard.conceptType = predicate def addObject(self, container, class_, name, **kw): - if name in container: - return container[name] - obj = container[name] = class_() - for attr in kw: - setattr(obj, attr, kw[attr]) - notify(ObjectCreatedEvent(obj)) - notify(ObjectModifiedEvent(obj)) - return obj + return addObject(container, class_, name, **kw) + + +def addObject(container, class_, name, **kw): + if name in container: + return container[name] + obj = container[name] = class_() + for attr in kw: + setattr(obj, attr, kw[attr]) + notify(ObjectCreatedEvent(obj)) + notify(ObjectModifiedEvent(obj)) + return obj