[Zope-CVS] CVS: Packages/pypes/pypes - query.py:1.12
Casey Duncan
casey at zope.com
Wed May 5 00:07:07 EDT 2004
Update of /cvs-repository/Packages/pypes/pypes
In directory cvs.zope.org:/tmp/cvs-serv8163
Modified Files:
query.py
Log Message:
Begin Join() partial result implementation
=== Packages/pypes/pypes/query.py 1.11 => 1.12 ===
--- Packages/pypes/pypes/query.py:1.11 Thu Apr 29 22:45:06 2004
+++ Packages/pypes/pypes/query.py Wed May 5 00:06:35 2004
@@ -48,9 +48,11 @@
from operator import mul
from sets import Set
from zope.interface import implements
+from compiler import ast
from BTrees.OOBTree import OOBTree
from pypes.interfaces import IPartialResult, IExtent
-from pypes.exceptions import PypesLookupError, PypesQueryInputError
+from pypes.exceptions import PypesLookupError, PypesQueryInputError, CantProcess
+from pypes.expression import Expression
## Exported constants ##
@@ -206,6 +208,57 @@
"""Return a unique set of results from the named inputs where the
criteria is satisfied
"""
+
+class Join:
+ """Join of multiple inputs using a criteria expression.
+
+ This implementation handles joins of two inputs each on a separate side
+ of a comparison operation (i.e., a.foo == b.bar). The following operators
+ are supported: ==, <, >, in.
+ """
+
+ implements(IPartialResult)
+
+ def __init__(self, input_map, criteria):
+ """Construct the joins
+
+ input_map -- a mapping object mapping names => inputs.
+
+ criteria -- criteria expression, an IExpression object. Supported
+ criteria compare two inputs (i.e., a.foo == b.bar). The following
+ operators are supported: ==, <, >, in.
+
+ If an unsupported criteria is specified, a CantProcess exception
+ is raised.
+ """
+ self._inputs = input_map
+ if len(criteria.freeNames()) != 2:
+ raise CantProcess, 'join criteria must have 2 free variables'
+ compare_node = criteria.ast().getChildNodes()[0]
+ if not (isinstance(compare_node, ast.Compare) and
+ len(compare_node.getChildNodes()) == 2):
+ raise CantProcess, ('join criteria must be single comparison '
+ 'between two terms')
+ left, operator, right = compare_node.getChildren()
+ if operator not in ('==', 'in', '<', '>'):
+ raise CantProcess, (
+ 'operator %s not suppported for join' % operator)
+ if operator == '<':
+ # Only greater join is directly supported
+ operator = '>'
+ left, right = right, left
+ bindings = criteria.bindings()
+ self._left = Expression.fromAstNode(left, bindings)
+ self._right = Expression.fromAstNode(right, bindings)
+ self._operator = operator
+ left_names = self._left.freeNames()
+ right_names = self._right.freeNames()
+ if (len(left_names) != 1
+ or iter(left_names).next() not in input_map
+ or len(right_names) != 1
+ or iter(right_names).next() not in input_map):
+ raise CantProcess, ('left and right join criteria operands '
+ 'must contain a single input term')
def sort(iterable, expression, order=ascending, limit=None):
More information about the Zope-CVS
mailing list