[Zope-CVS] CVS: Packages/pypes/pypes - exceptions.py:1.5
interfaces.py:1.20 query.py:1.9
Casey Duncan
casey at zope.com
Wed Apr 21 01:32:40 EDT 2004
Update of /cvs-repository/Packages/pypes/pypes
In directory cvs.zope.org:/tmp/cvs-serv12167
Modified Files:
exceptions.py interfaces.py query.py
Log Message:
Define IPartialResult interface for intermediate query result objects. Begin changing CartProduct class to implement it. Add supporting functions and tests.
Test pass, but CartProduct implementation needs finishing
=== Packages/pypes/pypes/exceptions.py 1.4 => 1.5 ===
--- Packages/pypes/pypes/exceptions.py:1.4 Tue Mar 30 23:58:08 2004
+++ Packages/pypes/pypes/exceptions.py Wed Apr 21 01:32:09 2004
@@ -52,3 +52,6 @@
class PypesQueryInputError(PypesQueryError):
"""Invalid input to pypes query"""
+
+class IndexRejects(Exception):
+ """Index cannot process requested operation"""
=== Packages/pypes/pypes/interfaces.py 1.19 => 1.20 ===
--- Packages/pypes/pypes/interfaces.py:1.19 Mon Apr 19 01:12:45 2004
+++ Packages/pypes/pypes/interfaces.py Wed Apr 21 01:32:09 2004
@@ -313,6 +313,11 @@
"""Return an extent containing all identified objects except those
in self.
"""
+
+ def sameTypeAs(other):
+ """Return true if the extent is the same type as other, that is it
+ originates from the same extent map
+ """
class ICanonicalExtent(IExtent):
"""An extent of a single interface or class provided directly by the
@@ -474,7 +479,7 @@
target is specified, only paths to target are returned. Both are
specifed to compute all paths connecting source to target
"""
-
+
class IQuery(Interface):
"""Query definition
@@ -623,15 +628,95 @@
i.e. "and" expressions where one operand optimizes to False.
"""
+ def ast():
+ """Return the root node of the expression's abstract syntax tree"""
+
def __call__(namespace={}):
"""Execute the expression using the names provided in namespace as
locals. Bound variables and builtins are used as globals. Return the
result of expression execution
"""
+ def __eq__(other):
+ """Return true if two expressions are equivilant. They must have
+ the same expression and bindings to be considered equal.
+ """
+
+ def __or__(other):
+ """Return a new expression which combines two expressions with a
+ logical OR operator. The bindings of the two expressions are combined.
+ Raise PypesError if any names in bindings are bound to different
+ values, such expressions cannot be logically combined
+ """
+
+ def __and__(other):
+ """Return a new expression which combines two expressions with a
+ logical AND operator. The bindings of the two expressions are
+ combined. Raise PypesError if any names in bindings are bound to
+ different values, such expressions cannot be logically combined
+ """
+
class IOrderExpression(IExpression):
"""Expression with order information"""
order = Attribute('order', """1 == ascending, -1 == descending""")
+class IPartialResult(Interface):
+ """Intermediate query result"""
+
+ def __init__(input_map, criteria):
+ """Construct a partial result object
+
+ input_map -- a mapping object mapping names => inputs.
+
+ criteria -- Criteria expression, an IExpression object used to determine
+ the input items that appear in the result.
+ """
+
+ def inputMap():
+ """Return a dict containing the input names and input objects for its
+ respective keys and values.
+ """
+
+ def criteriaExpr():
+ """Return the criteria IExpression object"""
+
+ def namesUsed():
+ """Return a sequence of the names used in the criteria for the result
+ """
+
+ def union(other):
+ """Returns a new partial result which is the union of the members of
+ both results. Other must have the same input names or raise
+ PypesQueryError.
+ """
+
+ def intersection(other):
+ """Returns a new partial result which contains the member in both self
+ and other. Other must have the same input names or raise
+ PypesQueryError.
+ """
+
+ def magnitude(*names):
+ """Return an integer which is the approximate length of the result
+ with the names specified. If no names are specified then the magnitude
+ for iterating all inputs is returned. Implementations should strive for
+ efficiency over accuracy, although accuracy can help the query engine
+ determine a more efficient plan.
+ """
+
+ def iterResult(*names):
+ """Yield the items for the specified input names where the criteria
+ is true. If a single name is specified, yield each matching item from
+ the input. If multiple names are specified, yield tuples of the
+ matching items from the cooresponding named inputs.
+ """
+
+ def resultSet(*names):
+ """Return an ISet object containing the items from the inputs named.
+ If a single name is specified, then return a set of matching objects
+ from the input. If multiple names are specified, return a set of
+ tuples of the matching items from the cooresponding named inputs.
+ """
+
=== Packages/pypes/pypes/query.py 1.8 => 1.9 ===
--- Packages/pypes/pypes/query.py:1.8 Mon Apr 19 01:14:27 2004
+++ Packages/pypes/pypes/query.py Wed Apr 21 01:32:09 2004
@@ -46,8 +46,10 @@
$Id$"""
from operator import mul
+from sets import Set
from zope.interface import implements
from BTrees.OOBTree import OOBTree
+from pypes.interfaces import IPartialResult, IExtent
from pypes.exceptions import PypesLookupError, PypesQueryInputError
## Exported constants ##
@@ -57,10 +59,31 @@
## Query Primitives ##
+def applyCriteria(input_map, criteria):
+ pass
+
+
+def union_input_maps(input1, input2):
+ """Create an input map dict whose values are the union of the cooresponding
+ values of input1 and input2 which are mappings of name => input set. Both
+ input1 and input2 should have the same name keys
+ """
+ inmap = {}
+ for name, set1 in input1.items():
+ set2 = input2[name]
+ if set1 is not set2:
+ inmap[name] = set1.union(set2)
+ else:
+ inmap[name] = set1
+ return inmap
+
+
class CartProduct:
"""Cartesian product of one or more inputs to a query. Allows lazy
evaluation, and efficient combinatorial operations
"""
+
+ implements(IPartialResult)
def __init__(self, input_map, criteria=None):
"""Construct the product
@@ -71,29 +94,51 @@
Used to select the input items to create a partial filtered product.
If omitted then a full product is generated.
"""
- self.inputs = input_map
- self.criteria = criteria
+ self._inputs = input_map
+ self._criteria = criteria
+
+ def inputMap(self):
+ return self._inputs.copy()
- def maxLen(self):
+ def criteriaExpr(self):
+ return self._criteria
+
+ def namesUsed(self):
+ if self._criteria is not None:
+ return self._criteria.freeNames(self._inputs.keys())
+ else:
+ return Set()
+
+ def magnitude(self, *names):
"""Return the maximum integer length of the product. This value
is calculated by multiplying the lengths of the inputs together.
This value matches the actual length for a full product.
This method assumes all the inputs support __len__
"""
- return reduce(mul, [len(ipt) for ipt in self.inputs.values()])
+ if not names:
+ names = self._inputs.keys()
+ return reduce(mul, [len(self._inputs[nm]) for nm in names])
+
+ def union(self, other):
+ assert Set(self.inputMap()) == Set(other.inputMap()), \
+ 'cannot union partial results with different inputs'
+ pass
- def iterProduct(self, *names):
+ def intersection(self, other):
+ pass
+
+ def iterResult(self, *names):
"""Iterate the cartesian product yielding items from the inputs named
where the criteria is satisfied. If a single name is specified, yield
each matching item from the input. If multiple names are specified,
yield tuples of the matching items from the cooresponding named inputs.
"""
- criteria = self.criteria
+ criteria = self._criteria
# Prime the input iterators and get the first row
row = {}
input_iters = []
- for name, ipt in self.inputs.items():
+ for name, ipt in self._inputs.items():
obj_iter = iter(ipt) # XXX won't work with input iters
input_iters.append((name, obj_iter))
row[name] = obj_iter.next()
@@ -119,7 +164,7 @@
try:
row[name] = obj_iter.next()
except StopIteration:
- obj_iter = iter(self.inputs[name])
+ obj_iter = iter(self._inputs[name])
input_iters[i] = name, obj_iter
row[name] = obj_iter.next()
i += 1
@@ -129,6 +174,12 @@
if i > 0:
i = 0
break
+
+ def resultSet(self, *names):
+ """Return a unique set of results from the named inputs where the
+ criteria is satisfied
+ """
+
def sort(iterable, expression, order=ascending, limit=None):
"""Return a sequence containing the elements of iterable sorted in order
More information about the Zope-CVS
mailing list