[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