[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