r347 - / python-hurry.query python-hurry.query/branches
python-hurry.query/branches/upstream
python-hurry.query/branches/upstream/current
python-hurry.query/branches/upstream/current/src
python-hurry.query/branches/upstream/current/src/hurry
python-hurry.query/branches/upstream/current/src/hurry/query
python-hurry.query/branches/upstream/current/src/hurry.query.egg-info
Brian Sutherland
jinty-guest at costa.debian.org
Wed Oct 25 11:23:38 UTC 2006
Author: jinty-guest
Date: 2006-10-25 11:23:38 +0000 (Wed, 25 Oct 2006)
New Revision: 347
Added:
python-hurry.query/
python-hurry.query/branches/
python-hurry.query/branches/upstream/
python-hurry.query/branches/upstream/current/
python-hurry.query/branches/upstream/current/CHANGES.txt
python-hurry.query/branches/upstream/current/CREDITS.txt
python-hurry.query/branches/upstream/current/INSTALL.txt
python-hurry.query/branches/upstream/current/LICENSE.txt
python-hurry.query/branches/upstream/current/PKG-INFO
python-hurry.query/branches/upstream/current/README.txt
python-hurry.query/branches/upstream/current/hurry.query-configure.zcml
python-hurry.query/branches/upstream/current/setup.py
python-hurry.query/branches/upstream/current/src/
python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/
python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/PKG-INFO
python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/SOURCES.txt
python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/namespace_packages.txt
python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/not-zip-safe
python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/top_level.txt
python-hurry.query/branches/upstream/current/src/hurry/
python-hurry.query/branches/upstream/current/src/hurry/__init__.py
python-hurry.query/branches/upstream/current/src/hurry/query/
python-hurry.query/branches/upstream/current/src/hurry/query/__init__.py
python-hurry.query/branches/upstream/current/src/hurry/query/configure.zcml
python-hurry.query/branches/upstream/current/src/hurry/query/interfaces.py
python-hurry.query/branches/upstream/current/src/hurry/query/query.py
python-hurry.query/branches/upstream/current/src/hurry/query/query.txt
python-hurry.query/branches/upstream/current/src/hurry/query/set.py
python-hurry.query/branches/upstream/current/src/hurry/query/tests.py
python-hurry.query/branches/upstream/current/src/hurry/query/value.py
python-hurry.query/branches/upstream/current/zc.catalog-configure.zcml
python-hurry.query/tags/
Log:
[svn-inject] Installing original source of python-hurry.query
Added: python-hurry.query/branches/upstream/current/CHANGES.txt
===================================================================
--- python-hurry.query/branches/upstream/current/CHANGES.txt (rev 0)
+++ python-hurry.query/branches/upstream/current/CHANGES.txt 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,14 @@
+hurry changes
+=============
+
+0.9 (2006-05-16)
+----------------
+
+* Separate hurry.query from the other hurry packages. Eggification work.
+
+* Support for ValueIndex from zc.catalog.
+
+0.8 (2006-05-01)
+----------------
+
+Initial public release.
Property changes on: python-hurry.query/branches/upstream/current/CHANGES.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/CREDITS.txt
===================================================================
--- python-hurry.query/branches/upstream/current/CREDITS.txt (rev 0)
+++ python-hurry.query/branches/upstream/current/CREDITS.txt 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,9 @@
+Credits
+-------
+
+Martijn Faassen - initial and main developer
+Stephan Richter - additional hurry.query index support
+Jan-Wijbrand Kolman - suggestions and feedback
+
+The hurry.query library for Zope 3 was originally developed at Infrae
+(http://www.infrae.com).
Property changes on: python-hurry.query/branches/upstream/current/CREDITS.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/INSTALL.txt
===================================================================
--- python-hurry.query/branches/upstream/current/INSTALL.txt (rev 0)
+++ python-hurry.query/branches/upstream/current/INSTALL.txt 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,14 @@
+Installation
+------------
+
+hurry.query needs Zope 3.1 or Zope 3.2.
+
+Make sure hurry.query's src directory is on the Python path somehow,
+and then copy hurry.query-configure.zcml into your Zope's
+`etc/package-includes` directory.
+
+hurry.query also has support for zc.catalog SetIndexes in
+hurry.query.set. If you want to use this extension, you need to
+install zc.catalog. It can be found in Zope's SVN repository. You
+then also need to copy `zc.catalog-configure.zcml` into your Zope's
+`etc/package-includes` directory.
Property changes on: python-hurry.query/branches/upstream/current/INSTALL.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/LICENSE.txt
===================================================================
--- python-hurry.query/branches/upstream/current/LICENSE.txt (rev 0)
+++ python-hurry.query/branches/upstream/current/LICENSE.txt 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,29 @@
+Copyright (c) 2005-2006 Infrae. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ 3. Neither the name of Infrae nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INFRAE OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Property changes on: python-hurry.query/branches/upstream/current/LICENSE.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/PKG-INFO
===================================================================
--- python-hurry.query/branches/upstream/current/PKG-INFO (rev 0)
+++ python-hurry.query/branches/upstream/current/PKG-INFO 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,13 @@
+Metadata-Version: 1.0
+Name: hurry.query
+Version: 0.9
+Summary: hurry.query is a higher level query system built on top of the Zope 3
+catalog. It makes it easy to perform catalog queries in Zope 3 code.
+
+Home-page: UNKNOWN
+Author: Infrae
+Author-email: faassen at infrae.com
+License: BSD
+Description: UNKNOWN
+Keywords: zope zope3
+Platform: UNKNOWN
Added: python-hurry.query/branches/upstream/current/README.txt
===================================================================
--- python-hurry.query/branches/upstream/current/README.txt (rev 0)
+++ python-hurry.query/branches/upstream/current/README.txt 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,4 @@
+hurry.query - higher level query system built on top of the Zope 3
+ catalog. Some inspiration came from Dieter Maurer's
+ AdvancedQuery. See src/hurry/query/query.txt for
+ documentation.
Property changes on: python-hurry.query/branches/upstream/current/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/hurry.query-configure.zcml
===================================================================
--- python-hurry.query/branches/upstream/current/hurry.query-configure.zcml (rev 0)
+++ python-hurry.query/branches/upstream/current/hurry.query-configure.zcml 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,3 @@
+<!-- install this into your Zope 3 instance's etc/package-includes
+ directory -->
+<include package="hurry.query"/>
Property changes on: python-hurry.query/branches/upstream/current/hurry.query-configure.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/setup.py
===================================================================
--- python-hurry.query/branches/upstream/current/setup.py (rev 0)
+++ python-hurry.query/branches/upstream/current/setup.py 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,24 @@
+from setuptools import setup, find_packages
+
+setup(
+ name="hurry.query",
+ version="0.9",
+ packages=find_packages('src', exclude=["*.tests", "*.ftests"]),
+
+ package_dir= {'':'src'},
+
+ namespace_packages=['hurry'],
+ package_data = {
+ '': ['*.txt', '*.zcml'],
+ },
+
+ zip_safe=False,
+ author='Infrae',
+ author_email='faassen at infrae.com',
+ description="""\
+hurry.query is a higher level query system built on top of the Zope 3
+catalog. It makes it easy to perform catalog queries in Zope 3 code.
+""",
+ license='BSD',
+ keywords="zope zope3",
+ )
Property changes on: python-hurry.query/branches/upstream/current/setup.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry/__init__.py
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry/__init__.py (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry/__init__.py 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,5 @@
+# this is a namespace package
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ pass
Property changes on: python-hurry.query/branches/upstream/current/src/hurry/__init__.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry/query/__init__.py
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry/query/__init__.py (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry/query/__init__.py 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1 @@
+from query import And, Or, Eq, NotEq, Between, In, Ge, Le, Text
Property changes on: python-hurry.query/branches/upstream/current/src/hurry/query/__init__.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry/query/configure.zcml
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry/query/configure.zcml (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry/query/configure.zcml 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,9 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope">
+
+ <utility
+ provides=".interfaces.IQuery"
+ factory=".query.Query"
+ />
+
+</configure>
Property changes on: python-hurry.query/branches/upstream/current/src/hurry/query/configure.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry/query/interfaces.py
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry/query/interfaces.py (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry/query/interfaces.py 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,9 @@
+from zope.interface import Interface
+
+class IQuery(Interface):
+ def searchResults(query):
+ """Query indexes.
+
+ Argument is a query composed of terms.
+ """
+
Property changes on: python-hurry.query/branches/upstream/current/src/hurry/query/interfaces.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry/query/query.py
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry/query/query.py (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry/query/query.py 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,198 @@
+from zope.interface import implements
+
+from zope.app import zapi
+from zope.app.intid.interfaces import IIntIds
+from zope.app.catalog.catalog import ResultSet
+from zope.app.catalog.field import IFieldIndex
+from zope.app.catalog.text import ITextIndex
+from zope.app.catalog.interfaces import ICatalog
+
+from BTrees.IFBTree import weightedIntersection, union, difference, IFBTree
+
+from hurry.query import interfaces
+
+# XXX look into using multiunion for performance?
+
+class Query(object):
+ implements(interfaces.IQuery)
+
+ def searchResults(self, query):
+ results = query.apply()
+ if results is not None:
+ uidutil = zapi.getUtility(IIntIds)
+ results = ResultSet(results, uidutil)
+ return results
+
+class Term(object):
+ def __and__(self, other):
+ return And(self, other)
+
+ def __rand__(self, other):
+ return And(other, self)
+
+ def __or__(self, other):
+ return Or(self, other)
+
+ def __ror__(self, other):
+ return Or(other, self)
+
+ def __invert__(self):
+ return Not(self)
+
+class And(Term):
+ def __init__(self, *terms):
+ self.terms = terms
+
+ def apply(self):
+ results = []
+ for term in self.terms:
+ r = term.apply()
+ if not r:
+ # empty results
+ return r
+ results.append((len(r), r))
+
+ if not results:
+ # no applicable terms at all
+ # XXX should this be possible?
+ return IFBTree()
+
+ results.sort()
+
+ _, result = results.pop(0)
+ for _, r in results:
+ _, result = weightedIntersection(result, r)
+ return result
+
+class Or(Term):
+ def __init__(self, *terms):
+ self.terms = terms
+
+ def apply(self):
+ results = []
+ for term in self.terms:
+ r = term.apply()
+ # empty results
+ if not r:
+ continue
+ results.append(r)
+
+ if not results:
+ # no applicable terms at all
+ # XXX should this be possible?
+ return IFBTree()
+
+ result = results.pop(0)
+ for r in results:
+ result = union(result, r)
+ return result
+
+class Not(Term):
+ def __init__(self, term):
+ self.term = term
+
+ def apply(self):
+ return difference(self._all(), self.term.apply())
+
+ def _all(self):
+ # XXX may not work well/be efficient with extentcatalog
+ # XXX not very efficient in general, better to use internal
+ # IntIds datastructure but that would break abstraction..
+ intids = zapi.getUtility(IIntIds)
+ result = IFBTree()
+ for uid in intids:
+ result.insert(uid, 0)
+ return result
+
+class IndexTerm(Term):
+ def __init__(self, (catalog_name, index_name)):
+ self.catalog_name = catalog_name
+ self.index_name = index_name
+
+ def getIndex(self):
+ catalog = zapi.getUtility(ICatalog, self.catalog_name)
+ index = catalog[self.index_name]
+ return index
+
+class Text(IndexTerm):
+ def __init__(self, index_id, text):
+ super(Text, self).__init__(index_id)
+ self.text = text
+
+ def getIndex(self):
+ index = super(Text, self).getIndex()
+ assert ITextIndex.providedBy(index)
+ return index
+
+ def apply(self):
+ index = self.getIndex()
+ return index.apply(self.text)
+
+class FieldTerm(IndexTerm):
+ def getIndex(self):
+ index = super(FieldTerm, self).getIndex()
+ assert IFieldIndex.providedBy(index)
+ return index
+
+class Eq(FieldTerm):
+ def __init__(self, index_id, value):
+ assert value is not None
+ super(Eq, self).__init__(index_id)
+ self.value = value
+
+ def apply(self):
+ return self.getIndex().apply((self.value, self.value))
+
+class NotEq(FieldTerm):
+ def __init__(self, index_id, not_value):
+ super(NotEq, self).__init__(index_id)
+ self.not_value = not_value
+
+ def apply(self):
+ index = self.getIndex()
+ all = index.apply((None, None))
+ r = index.apply((self.not_value, self.not_value))
+ return difference(all, r)
+
+class Between(FieldTerm):
+ def __init__(self, index_id, min_value, max_value):
+ super(Between, self).__init__(index_id)
+ self.min_value = min_value
+ self.max_value = max_value
+
+ def apply(self):
+ return self.getIndex().apply((self.min_value, self.max_value))
+
+class Ge(Between):
+ def __init__(self, index_id, min_value):
+ super(Ge, self).__init__(index_id, min_value, None)
+
+class Le(Between):
+ def __init__(self, index_id, max_value):
+ super(Le, self).__init__(index_id, None, max_value)
+
+class In(FieldTerm):
+ def __init__(self, index_id, values):
+ assert None not in values
+ super(In, self).__init__(index_id)
+ self.values = values
+
+ def apply(self):
+ results = []
+ index = self.getIndex()
+ for value in self.values:
+ r = index.apply((value, value))
+ # empty results
+ if not r:
+ continue
+ results.append(r)
+
+ if not results:
+ # no applicable terms at all
+ return IFBTree()
+
+ result = results.pop(0)
+ for r in results:
+ result = union(result, r)
+ return result
+
Property changes on: python-hurry.query/branches/upstream/current/src/hurry/query/query.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry/query/query.txt
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry/query/query.txt (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry/query/query.txt 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,394 @@
+Hurry Query
+===========
+
+The hurry query system for the Zope 3 catalog builds on catalog
+indexes as defined in Zope 3 core, as well as the indexes in
+zc.catalog. It is in part inspired by AdvancedQuery for Zope 2 by
+Dieter Maurer, though has an independent origin.
+
+Setup
+-----
+
+Let's define a simple content object. First its interface::
+
+ >>> from zope.interface import Interface, Attribute, implements
+ >>> class IContent(Interface):
+ ... f1 = Attribute('f1')
+ ... f2 = Attribute('f2')
+ ... f3 = Attribute('f3')
+ ... f4 = Attribute('f4')
+ ... t1 = Attribute('t1')
+ ... t2 = Attribute('t2')
+
+And its implementation::
+
+ >>> from zope.app.container.contained import Contained
+ >>> class Content(Contained):
+ ... implements(IContent)
+ ... def __init__(self, id, f1='', f2='', f3='', f4='', t1='', t2=''):
+ ... self.id = id
+ ... self.f1 = f1
+ ... self.f2 = f2
+ ... self.f3 = f3
+ ... self.f4 = f4
+ ... self.t1 = t1
+ ... self.t2 = t2
+ ... def __cmp__(self, other):
+ ... return cmp(self.id, other.id)
+
+The id attribute is just so we can identify objects we find again
+easily. By including the __cmp__ method we make sure search results
+can be stably sorted.
+
+We use a fake int id utility here so we can test independent of
+the full-blown zope environment::
+
+ >>> from zope.interface import verify
+ >>> from zope import interface
+ >>> import zope.app.intid.interfaces
+ >>> from zope.app.testing import ztapi
+ >>> class DummyIntId(object):
+ ... interface.implements(zope.app.intid.interfaces.IIntIds)
+ ... MARKER = '__dummy_int_id__'
+ ... def __init__(self):
+ ... self.counter = 0
+ ... self.data = {}
+ ... def register(self, obj):
+ ... intid = getattr(obj, self.MARKER, None)
+ ... if intid is None:
+ ... setattr(obj, self.MARKER, self.counter)
+ ... self.data[self.counter] = obj
+ ... intid = self.counter
+ ... self.counter += 1
+ ... return intid
+ ... def getObject(self, intid):
+ ... return self.data[intid]
+ ... def __iter__(self):
+ ... return iter(self.data)
+ >>> intid = DummyIntId()
+ >>> ztapi.provideUtility(
+ ... zope.app.intid.interfaces.IIntIds, intid)
+
+Now let's register a catalog::
+
+ >>> from zope.app.catalog.interfaces import ICatalog
+ >>> from zope.app.catalog.catalog import Catalog
+ >>> catalog = Catalog()
+ >>> ztapi.provideUtility(ICatalog, catalog, 'catalog1')
+
+And set it up with various indexes::
+
+ >>> from zope.app.catalog.field import FieldIndex
+ >>> from zope.app.catalog.text import TextIndex
+ >>> catalog['f1'] = FieldIndex('f1', IContent)
+ >>> catalog['f2'] = FieldIndex('f2', IContent)
+ >>> catalog['f3'] = FieldIndex('f3', IContent)
+ >>> catalog['f4'] = FieldIndex('f4', IContent)
+ >>> catalog['t1'] = TextIndex('t1', IContent)
+ >>> catalog['t2'] = TextIndex('t2', IContent)
+
+Now let's create some objects so that they'll be cataloged::
+
+ >>> content = [
+ ... Content(1, 'a', 'b', 'd'),
+ ... Content(2, 'a', 'c'),
+ ... Content(3, 'X', 'c'),
+ ... Content(4, 'a', 'b', 'e'),
+ ... Content(5, 'X', 'b', 'e'),
+ ... Content(6, 'Y', 'Z')]
+
+And catalog them now::
+
+ >>> for entry in content:
+ ... catalog.index_doc(intid.register(entry), entry)
+
+Now let's register a query utility::
+
+ >>> from hurry.query.query import Query
+ >>> from hurry.query.interfaces import IQuery
+ >>> ztapi.provideUtility(IQuery, Query())
+
+Set up some code to make querying and display the result
+easy::
+
+ >>> from zope.app import zapi
+ >>> from hurry.query.interfaces import IQuery
+ >>> def displayQuery(q):
+ ... query = zapi.getUtility(IQuery)
+ ... r = query.searchResults(q)
+ ... return [e.id for e in sorted(list(r))]
+
+FieldIndex Queries
+------------------
+
+Now for a query where f1 equals a::
+
+ >>> from hurry.query import Eq
+ >>> f1 = ('catalog1', 'f1')
+ >>> displayQuery(Eq(f1, 'a'))
+ [1, 2, 4]
+
+Not equals (this is more efficient than the generic ~ operator)::
+
+ >>> from hurry.query import NotEq
+ >>> displayQuery(NotEq(f1, 'a'))
+ [3, 5, 6]
+
+Testing whether a field is in a set::
+
+ >>> from hurry.query import In
+ >>> displayQuery(In(f1, ['a', 'X']))
+ [1, 2, 3, 4, 5]
+
+Whether documents are in a specified range::
+
+ >>> from hurry.query import Between
+ >>> displayQuery(Between(f1, 'X', 'Y'))
+ [3, 5, 6]
+
+You can leave out one end of the range::
+
+ >>> displayQuery(Between(f1, 'X', None)) # 'X' < 'a'
+ [1, 2, 3, 4, 5, 6]
+ >>> displayQuery(Between(f1, None, 'X'))
+ [3, 5]
+
+You can also use greater-equals and lesser-equals for the same purpose::
+
+ >>> from hurry.query import Ge, Le
+ >>> displayQuery(Ge(f1, 'X'))
+ [1, 2, 3, 4, 5, 6]
+ >>> displayQuery(Le(f1, 'X'))
+ [3, 5]
+
+It's also possible to use not with the ~ operator::
+
+ >>> displayQuery(~Eq(f1, 'a'))
+ [3, 5, 6]
+
+Using and (&)::
+
+ >>> f2 = ('catalog1', 'f2')
+ >>> displayQuery(Eq(f1, 'a') & Eq(f2, 'b'))
+ [1, 4]
+
+Using or (|)::
+
+ >>> displayQuery(Eq(f1, 'a') | Eq(f2, 'b'))
+ [1, 2, 4, 5]
+
+These can be chained::
+
+ >>> displayQuery(Eq(f1, 'a') & Eq(f2, 'b') & Between(f1, 'a', 'b'))
+ [1, 4]
+ >>> displayQuery(Eq(f1, 'a') | Eq(f1, 'X') | Eq(f2, 'b'))
+ [1, 2, 3, 4, 5]
+
+And nested::
+
+ >>> displayQuery((Eq(f1, 'a') | Eq(f1, 'X')) & (Eq(f2, 'b') | Eq(f2, 'c')))
+ [1, 2, 3, 4, 5]
+
+"and" and "or" can also be spelled differently::
+
+ >>> from hurry.query import And, Or
+ >>> displayQuery(And(Eq(f1, 'a'), Eq(f2, 'b')))
+ [1, 4]
+ >>> displayQuery(Or(Eq(f1, 'a'), Eq(f2, 'b')))
+ [1, 2, 4, 5]
+
+Combination of In and &
+-----------------------
+
+A combination of 'In' and '&'::
+
+ >>> displayQuery(In(f1, ['a', 'X', 'Y', 'Z']))
+ [1, 2, 3, 4, 5, 6]
+ >>> displayQuery(In(f1, ['Z']))
+ []
+ >>> displayQuery(In(f1, ['a', 'X', 'Y', 'Z']) & In(f1, ['Z']))
+ []
+
+
+SetIndex queries
+----------------
+
+The SetIndex is defined in zc.catalog. Let's make a catalog which uses
+it::
+
+ >>> intid = DummyIntId()
+ >>> ztapi.provideUtility(
+ ... zope.app.intid.interfaces.IIntIds, intid)
+ >>> from zope.app.catalog.interfaces import ICatalog
+ >>> from zope.app.catalog.catalog import Catalog
+ >>> catalog = Catalog()
+ >>> ztapi.provideUtility(ICatalog, catalog, 'catalog1')
+ >>> from zc.catalog.catalogindex import SetIndex
+ >>> catalog['f1'] = SetIndex('f1', IContent)
+ >>> catalog['f2'] = FieldIndex('f2', IContent)
+
+First let's set up some new data::
+
+ >>> content = [
+ ... Content(1, ['a', 'b', 'c'], 1),
+ ... Content(2, ['a'], 1),
+ ... Content(3, ['b'], 1),
+ ... Content(4, ['c', 'd'], 2),
+ ... Content(5, ['b', 'c'], 2),
+ ... Content(6, ['a', 'c'], 2)]
+
+And catalog them now::
+
+ >>> for entry in content:
+ ... catalog.index_doc(intid.register(entry), entry)
+
+Now do a a 'any of' query, which returns all documents that
+contain any of the values listed::
+
+ >>> from hurry.query.set import AnyOf
+ >>> displayQuery(AnyOf(f1, ['a', 'c']))
+ [1, 2, 4, 5, 6]
+ >>> displayQuery(AnyOf(f1, ['c', 'b']))
+ [1, 3, 4, 5, 6]
+ >>> displayQuery(AnyOf(f1, ['a']))
+ [1, 2, 6]
+
+Do a 'all of' query, which returns all documents that
+contain all of the values listed::
+
+ >>> from hurry.query.set import AllOf
+ >>> displayQuery(AllOf(f1, ['a']))
+ [1, 2, 6]
+ >>> displayQuery(AllOf(f1, ['a', 'b']))
+ [1]
+ >>> displayQuery(AllOf(f1, ['a', 'c']))
+ [1, 6]
+
+We can combine this with other queries::
+
+ >>> displayQuery(AnyOf(f1, ['a']) & Eq(f2, 1))
+ [1, 2]
+
+
+ValueIndex queries
+------------------
+
+The ``ValueIndex`` is defined in ``zc.catalog`` and provides a generalization
+of the standard field index.
+
+ >>> from hurry.query import value
+
+Let's set up a catalog that uses this index. The ``ValueIndex`` is defined in
+``zc.catalog``. Let's make a catalog which uses it:
+
+ >>> intid = DummyIntId()
+ >>> ztapi.provideUtility(zope.app.intid.interfaces.IIntIds, intid)
+
+ >>> from zope.app.catalog.interfaces import ICatalog
+ >>> from zope.app.catalog.catalog import Catalog
+ >>> catalog = Catalog()
+ >>> ztapi.provideUtility(ICatalog, catalog, 'catalog1')
+
+ >>> from zc.catalog.catalogindex import ValueIndex
+ >>> catalog['f1'] = ValueIndex('f1', IContent)
+
+Next we set up some content data to fill the indices:
+
+ >>> content = [
+ ... Content(1, 'a'),
+ ... Content(2, 'b'),
+ ... Content(3, 'c'),
+ ... Content(4, 'd'),
+ ... Content(5, 'c'),
+ ... Content(6, 'a')]
+
+And catalog them now:
+
+ >>> for entry in content:
+ ... catalog.index_doc(intid.register(entry), entry)
+
+
+Let's now query for all objects where ``f1`` equals 'a':
+
+ >>> f1 = ('catalog1', 'f1')
+ >>> displayQuery(value.Eq(f1, 'a'))
+ [1, 6]
+
+Next, let's find all objects where ``f1`` does not equal 'a'; this is more
+efficient than the generic ``~`` operator:
+
+ >>> displayQuery(value.NotEq(f1, 'a'))
+ [2, 3, 4, 5]
+
+You can also query for all objects where the value of ``f1`` is in a set of
+values:
+
+ >>> displayQuery(value.In(f1, ['a', 'd']))
+ [1, 4, 6]
+
+The next interesting set of queries allows you to make evaluations of the
+values. For example, you can ask for all objects between a certain set of
+values:
+
+ >>> displayQuery(value.Between(f1, 'a', 'c'))
+ [1, 2, 3, 5, 6]
+
+ >>> displayQuery(value.Between(f1, 'a', 'c', exclude_min=True))
+ [2, 3, 5]
+
+ >>> displayQuery(value.Between(f1, 'a', 'c', exclude_max=True))
+ [1, 2, 6]
+
+ >>> displayQuery(value.Between(f1, 'a', 'c',
+ ... exclude_min=True, exclude_max=True))
+ [2]
+
+You can also leave out one end of the range:
+
+ >>> displayQuery(value.Between(f1, 'c', None))
+ [3, 4, 5]
+ >>> displayQuery(value.Between(f1, None, 'c'))
+ [1, 2, 3, 5, 6]
+
+You can also use greater-equals and lesser-equals for the same purpose:
+
+ >>> displayQuery(value.Ge(f1, 'c'))
+ [3, 4, 5]
+ >>> displayQuery(value.Le(f1, 'c'))
+ [1, 2, 3, 5, 6]
+
+Of course, you can chain those queries with the others as demonstrated before.
+
+The ``value`` module also supports ``zc.catalog`` extents. The first query is
+``ExtentAny``, which returns all douments matching the extent. If the the
+extent is ``None``, all document ids are returned:
+
+ >>> displayQuery(value.ExtentAny(f1, None))
+ [1, 2, 3, 4, 5, 6]
+
+If we now create an extent that is only in the scope of the first four
+documents,
+
+ >>> from zc.catalog.extentcatalog import FilterExtent
+ >>> extent = FilterExtent(lambda extent, uid, obj: True)
+ >>> for i in range(4):
+ ... extent.add(i, i)
+
+then only the first four are returned:
+
+ >>> displayQuery(value.ExtentAny(f1, extent))
+ [1, 2, 3, 4]
+
+The opposite query is the ``ExtentNone`` query, which returns all ids in the
+extent that are *not* in the index:
+
+ >>> id = intid.register(Content(7, 'b'))
+ >>> id = intid.register(Content(8, 'c'))
+ >>> id = intid.register(Content(9, 'a'))
+
+ >>> extent = FilterExtent(lambda extent, uid, obj: True)
+ >>> for i in range(9):
+ ... extent.add(i, i)
+
+ >>> displayQuery(value.ExtentNone(f1, extent))
+ [7, 8, 9]
Property changes on: python-hurry.query/branches/upstream/current/src/hurry/query/query.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry/query/set.py
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry/query/set.py (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry/query/set.py 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,54 @@
+from zc.catalog.interfaces import ISetIndex
+from hurry.query import query
+
+class SetTerm(query.IndexTerm):
+ def getIndex(self):
+ index = super(SetTerm, self).getIndex()
+ assert ISetIndex.providedBy(index)
+ return index
+
+class AnyOf(SetTerm):
+ def __init__(self, index_id, values):
+ super(AnyOf, self).__init__(index_id)
+ self.values = values
+
+ def apply(self):
+ return self.getIndex().apply({'any_of': self.values})
+
+class AllOf(SetTerm):
+ def __init__(self, index_id, values):
+ super(AllOf, self).__init__(index_id)
+ self.values = values
+
+ def apply(self):
+ return self.getIndex().apply({'all_of': self.values})
+
+class SetBetween(SetTerm):
+ def __init__(self, index_id,
+ minimum=None, maximum=None,
+ include_minimum=False, include_maximum=False):
+ super(SetBetween, self).__init__(index_id)
+ self.tuple = (minimum, maximum, include_minimum, include_maximum)
+
+ def apply(self):
+ return self.getIndex().apply({'between': self.tuple})
+
+class ExtentAny(SetTerm):
+ """Any ids in the extent that are indexed by this index.
+ """
+ def __init__(self, index_id, extent):
+ super(Any, self).__init__(index_id)
+ self.extent = extent
+
+ def apply(self):
+ return self.getIndex().apply({'any': self.extent})
+
+class ExtentNone(SetTerm):
+ """Any ids in the extent that are not indexed by this index.
+ """
+ def __init__(self, extent):
+ super(None, self).__init__(index_id)
+ self.extent = extent
+
+ def apply(self):
+ return self.getIndex().apply({'none': self.extent})
Property changes on: python-hurry.query/branches/upstream/current/src/hurry/query/set.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry/query/tests.py
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry/query/tests.py (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry/query/tests.py 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,10 @@
+import unittest
+from zope.testing import doctest
+
+def test_suite():
+ return unittest.TestSuite((
+ doctest.DocFileSuite('query.txt'),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Property changes on: python-hurry.query/branches/upstream/current/src/hurry/query/tests.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry/query/value.py
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry/query/value.py (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry/query/value.py 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,79 @@
+from zc.catalog.interfaces import IValueIndex
+from hurry.query import query
+
+class ValueTerm(query.IndexTerm):
+ def getIndex(self):
+ index = super(ValueTerm, self).getIndex()
+ assert IValueIndex.providedBy(index)
+ return index
+
+class Eq(ValueTerm):
+ def __init__(self, index_id, value):
+ assert value is not None
+ super(Eq, self).__init__(index_id)
+ self.value = value
+
+ def apply(self):
+ return self.getIndex().apply({'any_of': (self.value,)})
+
+class NotEq(ValueTerm):
+ def __init__(self, index_id, not_value):
+ super(NotEq, self).__init__(index_id)
+ self.not_value = not_value
+
+ def apply(self):
+ index = self.getIndex()
+ values = list(index.values())
+ values.remove(self.not_value)
+ return index.apply({'any_of': values})
+
+class Between(ValueTerm):
+ def __init__(self, index_id, min_value=None, max_value=None,
+ exclude_min=False, exclude_max=False):
+ super(Between, self).__init__(index_id)
+ self.min_value = min_value
+ self.max_value = max_value
+ self.exclude_min = exclude_min
+ self.exclude_max = exclude_max
+
+ def apply(self):
+ return self.getIndex().apply(
+ {'between': (self.min_value, self.max_value,
+ self.exclude_min, self.exclude_max)})
+
+class Ge(Between):
+ def __init__(self, index_id, min_value):
+ super(Ge, self).__init__(index_id, min_value=min_value)
+
+class Le(Between):
+ def __init__(self, index_id, max_value):
+ super(Le, self).__init__(index_id, max_value=max_value)
+
+class In(ValueTerm):
+ def __init__(self, index_id, values):
+ assert None not in values
+ super(In, self).__init__(index_id)
+ self.values = values
+
+ def apply(self):
+ return self.getIndex().apply({'any_of': self.values})
+
+class ExtentAny(ValueTerm):
+ """Any ids in the extent that are indexed by this index.
+ """
+ def __init__(self, index_id, extent):
+ super(ExtentAny, self).__init__(index_id)
+ self.extent = extent
+
+ def apply(self):
+ return self.getIndex().apply({'any': self.extent})
+
+class ExtentNone(ValueTerm):
+ """Any ids in the extent that are not indexed by this index.
+ """
+ def __init__(self, index_id, extent):
+ super(ExtentNone, self).__init__(index_id)
+ self.extent = extent
+
+ def apply(self):
+ return self.getIndex().apply({'none': self.extent})
Property changes on: python-hurry.query/branches/upstream/current/src/hurry/query/value.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/PKG-INFO
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/PKG-INFO (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/PKG-INFO 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,13 @@
+Metadata-Version: 1.0
+Name: hurry.query
+Version: 0.9
+Summary: hurry.query is a higher level query system built on top of the Zope 3
+catalog. It makes it easy to perform catalog queries in Zope 3 code.
+
+Home-page: UNKNOWN
+Author: Infrae
+Author-email: faassen at infrae.com
+License: BSD
+Description: UNKNOWN
+Keywords: zope zope3
+Platform: UNKNOWN
Added: python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/SOURCES.txt
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/SOURCES.txt (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/SOURCES.txt 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,22 @@
+CHANGES.txt
+CREDITS.txt
+INSTALL.txt
+LICENSE.txt
+README.txt
+hurry.query-configure.zcml
+setup.py
+zc.catalog-configure.zcml
+src/hurry/__init__.py
+src/hurry.query.egg-info/PKG-INFO
+src/hurry.query.egg-info/SOURCES.txt
+src/hurry.query.egg-info/namespace_packages.txt
+src/hurry.query.egg-info/not-zip-safe
+src/hurry.query.egg-info/top_level.txt
+src/hurry/query/__init__.py
+src/hurry/query/configure.zcml
+src/hurry/query/interfaces.py
+src/hurry/query/query.py
+src/hurry/query/query.txt
+src/hurry/query/set.py
+src/hurry/query/tests.py
+src/hurry/query/value.py
Property changes on: python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/SOURCES.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/namespace_packages.txt
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/namespace_packages.txt (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/namespace_packages.txt 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1 @@
+hurry
Property changes on: python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/namespace_packages.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/not-zip-safe
===================================================================
Added: python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/top_level.txt
===================================================================
--- python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/top_level.txt (rev 0)
+++ python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/top_level.txt 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1 @@
+hurry
Property changes on: python-hurry.query/branches/upstream/current/src/hurry.query.egg-info/top_level.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: python-hurry.query/branches/upstream/current/zc.catalog-configure.zcml
===================================================================
--- python-hurry.query/branches/upstream/current/zc.catalog-configure.zcml (rev 0)
+++ python-hurry.query/branches/upstream/current/zc.catalog-configure.zcml 2006-10-25 11:23:38 UTC (rev 347)
@@ -0,0 +1,5 @@
+<!-- install this into your Zope 3 instance's etc/package-includes
+ directory. You need zc.catalog installed in your Zope 3 installation.
+ Right now you can get it from Zope 3 svn in Sandbox/zc/catalog/)
+-->
+<include package="zc.catalog"/>
Property changes on: python-hurry.query/branches/upstream/current/zc.catalog-configure.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the pkg-zope-commits
mailing list