[Checkins] SVN: Sandbox/adamg/ocql/trunk/s moving code from old repo

Adam Groszer agroszer at gmail.com
Sun Jun 15 10:35:59 EDT 2008


Log message for revision 87410:
  moving code from old repo
  made a lot of refactoring... still a lot of TODOs
  paving the way for Charith

Changed:
  U   Sandbox/adamg/ocql/trunk/setup.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.txt
  A   Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/tests.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.txt
  A   Sandbox/adamg/ocql/trunk/src/ocql/compiler/runnablequery.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/compiler/tests.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/database/
  A   Sandbox/adamg/ocql/trunk/src/ocql/database/__init__.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/database/metadata.py
  U   Sandbox/adamg/ocql/trunk/src/ocql/engine.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/parser/parser.txt
  A   Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/parser/tests.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/qoptimizer.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/qoptimizer.txt
  A   Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/tests.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/queryobject/
  A   Sandbox/adamg/ocql/trunk/src/ocql/queryobject/__init__.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/queryobject/queryobject.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.txt
  A   Sandbox/adamg/ocql/trunk/src/ocql/rewriter/tests.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/testing/database.py
  U   Sandbox/adamg/ocql/trunk/src/ocql/testing/stubs.py
  A   Sandbox/adamg/ocql/trunk/src/ocql/tests/run.txt
  U   Sandbox/adamg/ocql/trunk/src/ocql/tests/test_skeleton.py

-=-
Modified: Sandbox/adamg/ocql/trunk/setup.py
===================================================================
--- Sandbox/adamg/ocql/trunk/setup.py	2008-06-15 12:38:04 UTC (rev 87409)
+++ Sandbox/adamg/ocql/trunk/setup.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -27,9 +27,10 @@
     url = '',
     packages = find_packages('src'),
     package_dir = {'':'src'},
-    namespace_packages = ['ocql'],
+    namespace_packages = [],
     extras_require = dict(
         test = [
+            'zope.testing',
             ],
         ),
     install_requires = [

Added: Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,35 @@
+# -*- coding: UTF-8 -*-
+
+""" Optimizing will be done later,
+at the moment this is just a stub returning it's input
+
+$Id$
+"""
+
+from zope.component import adapts
+from zope.interface import implements
+from zope.security.proxy import removeSecurityProxy
+from zope.interface import directlyProvidedBy
+from zope.interface import directlyProvides
+
+from ocql.interfaces import IAlgebraOptimizer
+
+from ocql.interfaces import IAlgebraObject
+from ocql.interfaces import IOptimizedAlgebraObject
+
+def addMarkerIF(obj, marker):
+    obj = removeSecurityProxy(obj)
+    if not marker.providedBy(obj):
+        directlyProvides(obj, directlyProvidedBy(obj), marker)
+
+class AlgebraOptimizer(object):
+    implements(IAlgebraOptimizer)
+    adapts(IAlgebraObject)
+
+    def __init__(self, context):
+        self.context = context
+        #self.db = db
+
+    def __call__(self):
+        addMarkerIF(self.context, IOptimizedAlgebraObject)
+        return self.context


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.txt
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.txt	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.txt	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,25 @@
+
+
+    >>> from ocql.aoptimizer.aoptimizer import AlgebraOptimizer
+    >>> from ocql.interfaces import IOptimizedAlgebraObject
+
+Currently the optimizer is doing NOTHING, it just returns what it gets.
+(And adds the interface IOptimizedAlgebraObject)
+
+    >>> class Dummy(object):
+    ...     def __init__(self, value):
+    ...          self.value = value
+
+    >>> in_=Dummy('foo-bar')
+    >>> in_.value
+    'foo-bar'
+
+    >>> out = AlgebraOptimizer(in_)()
+
+    >>> print out
+    <Dummy object at ...>
+    >>> out.value
+    'foo-bar'
+
+    >>> IOptimizedAlgebraObject.providedBy(out)
+    True
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.txt
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/tests.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/tests.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/tests.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,14 @@
+import unittest
+import doctest
+from zope.testing.doctestunit import DocTestSuite,DocFileSuite
+
+def test_suite():
+    flags =  doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
+    return unittest.TestSuite((
+        DocFileSuite('aoptimizer.txt',
+            optionflags=flags),
+        ))
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/tests.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,31 @@
+# -*- coding: UTF-8 -*-
+
+"""Compiles Algebra Object to python code
+
+$Id$
+"""
+
+#BIG-BIG-BIG TODO:
+# move all class.compile to here, using the adapter pattern
+
+from zope.component import adapts
+from zope.interface import implements
+
+from ocql.interfaces import IAlgebraCompiler
+from ocql.interfaces import IOptimizedAlgebraObject
+
+from ocql.compiler.runnablequery import RunnableQuery
+
+class AlgebraCompiler(object):
+    implements(IAlgebraCompiler)
+    adapts(IOptimizedAlgebraObject)
+
+    def __init__(self, context):
+        self.context = context
+        #self.db = db
+
+    def __call__(self, metadata, algebra):
+        algebra = self.context
+        code = algebra.compile()
+        run = RunnableQuery(metadata, algebra, code)
+        return run
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.txt
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.txt	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.txt	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,67 @@
+
+I'm sorry, but I'm lazy here, in reality we would have to create
+stubs for all ocql.rewriter.algebra classes and use those...
+But it's a lot faster to reuse the parser and the existing classes.
+
+    >>> from ocql.parser.queryparser import QueryParser
+    >>> from ocql.qoptimizer.qoptimizer import QueryOptimizer
+    >>> from ocql.rewriter.rewriter import Rewriter
+    >>> from ocql.aoptimizer.aoptimizer import AlgebraOptimizer
+    >>> from ocql.compiler.compiler import AlgebraCompiler
+
+    >>> from ocql.testing.database import TestMetadata
+
+    >>> metadata = TestMetadata()
+    >>> qo = QueryParser("set [ | 1 ]")(metadata)
+    >>> opt = QueryOptimizer(qo)()
+    >>> alg = Rewriter(opt)()
+    >>> aopt = AlgebraOptimizer(alg)()
+    >>> run = AlgebraCompiler(aopt)(metadata, alg)
+    >>> print str(run)
+    RunnableQuery: set([1])
+
+
+    >>> metadata = TestMetadata()
+    >>> qo = QueryParser("set [ | 1 ] union set [|2]")(TestMetadata())
+    >>> opt = QueryOptimizer(qo)()
+    >>> alg = Rewriter(opt)()
+    >>> aopt = AlgebraOptimizer(alg)()
+    >>> run = AlgebraCompiler(aopt)(metadata, alg)
+    >>> print str(run)
+    RunnableQuery: set.union(set([1]),set([2]))
+
+
+    ##Differ not implemented
+    ##>>> qo = QueryParser("set [ | 1 ] differ set [|2]")(TestMetadata())
+    ##>>> opt = QueryOptimizer(qo)()
+    ##>>> alg = Rewriter(opt)()
+    ##>>> print str(alg)
+    ##Union(<type 'set'>,Single(<type 'set'>,`1`),Single(<type 'set'>,`2`))
+
+
+
+    >>> metadata = TestMetadata()
+    >>> qo = QueryParser("set [ i in ICourse | i ]")(TestMetadata())
+    >>> opt = QueryOptimizer(qo)()
+    >>> alg = Rewriter(opt)()
+    >>> aopt = AlgebraOptimizer(alg)()
+    >>> run = AlgebraCompiler(aopt)(metadata, alg)
+    >>> print str(run)
+    RunnableQuery: reduce(set.union, map(lambda i: set([i]),set(metadata.getAll("ICourse"))) , set())
+
+
+    ##bag not implemented
+    ##>>> qo = QueryParser("size set [ i in ICourse | i ]")(TestMetadata())
+    ##>>> opt = QueryOptimizer(qo)()
+    ##>>> alg = Rewriter(opt)()
+    ##>>> print str(alg)
+    ##Iter(<type 'set'>,Lambda i: Single(<type 'set'>,i),Make(<type 'set'>,<type 'set'>,ICourse))
+
+    >>> metadata = TestMetadata()
+    >>> qo = QueryParser("set [ c in ICourse | c.code ]")(TestMetadata())
+    >>> opt = QueryOptimizer(qo)()
+    >>> alg = Rewriter(opt)()
+    >>> aopt = AlgebraOptimizer(alg)()
+    >>> run = AlgebraCompiler(aopt)(metadata, alg)
+    >>> print str(run)
+    RunnableQuery: reduce(set.union, map(lambda c: set([c.code]),set(metadata.getAll("ICourse"))) , set())
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.txt
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/compiler/runnablequery.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/compiler/runnablequery.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/compiler/runnablequery.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,78 @@
+# -*- coding: UTF-8 -*-
+
+"""Runnable query object
+This will return the resultset
+
+$Id$
+"""
+
+import operator
+
+from ocql.interfaces import IAlgebraOptimizer
+from ocql.interfaces import IAlgebraCompiler
+
+_marker = object()
+
+def d_reduce(function, sequence, initializer=_marker):
+    if initializer is _marker:
+        rv = reduce(function, sequence)
+    else:
+        rv = reduce(function, sequence, initializer)
+    return rv
+
+def d_map(function, *sequences):
+    #print "Mapping from", [i for i in sequences[0]]
+    rv = map(function, *sequences)
+    return rv
+
+def d_range(start, stop):
+    rv = range(start, stop)
+    return rv
+
+class d_set(set):
+    def union(self, other):
+        rv = set.union(self, other)
+        return rv
+
+    def __call__(self):
+        rv = set.__call__(self)
+        return rv
+
+    def __init__(self, list=[]):
+        #print "creating set with values", list
+        rv = set.__init__(self, list)
+        return rv
+
+
+
+class RunnableQuery:
+    """
+        metadata: ocql.metadata instance
+        alg: algebra object
+    """
+    def __init__(self, metadata, alg, code):
+        self.metadata = metadata
+        self.alg = alg
+        self.code =code
+
+    def __repr__(self):
+        return "%s: %s" % (self.__class__.__name__,
+                           self.code)
+
+    def reanalyze(self):
+        optimizedalgebra = IAlgebraOptimizer(self.alg)()
+        runnable = IAlgebraCompiler(optimizedalgebra)(self.metadata, self.alg)
+        return runnable
+
+    def execute(self, debug=False):
+        #TODO: why is the metadata not working in locals?
+
+        mapping = {'metadata': self.metadata,
+                   'operator': operator}
+        if debug:
+            mapping['reduce'] = d_reduce
+            mapping['map'] = d_map
+            mapping['range'] = d_range
+            mapping['set'] = d_set
+
+        return eval(self.code, mapping, mapping)


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/compiler/runnablequery.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/compiler/tests.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/compiler/tests.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/compiler/tests.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,14 @@
+import unittest
+import doctest
+from zope.testing.doctestunit import DocTestSuite,DocFileSuite
+
+def test_suite():
+    flags =  doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
+    return unittest.TestSuite((
+        DocFileSuite('compiler.txt',
+            optionflags=flags),
+        ))
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/compiler/tests.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/database/__init__.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/database/__init__.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/database/__init__.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1 @@
+#
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/database/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/database/metadata.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/database/metadata.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/database/metadata.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,28 @@
+class MetaType:
+    def get_property(self, name):
+        """
+            Get type information and metadata for property.
+            Returns a MetaType
+        """
+
+    def is_collection(self):
+        """Returns True if the represented type is a collection."""
+
+    def get_collection_type(self):
+        """Returns the represented type"""
+
+    def get_contained(self):
+        """
+            Throws an exception if represented type is not a collection, or
+            the contained type if a collection
+        """
+
+    def get_size(self):
+        """Returns the size of the collection or class if known"""
+
+class Metadata:
+    def __init__(self):
+        pass
+
+    def get_class(self, classname):
+        """Returns a MetaType instance for the class."""
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/database/metadata.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Modified: Sandbox/adamg/ocql/trunk/src/ocql/engine.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/engine.py	2008-06-15 12:38:04 UTC (rev 87409)
+++ Sandbox/adamg/ocql/trunk/src/ocql/engine.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -31,12 +31,12 @@
 
     def compile(self, query):
         #TODO: later use maybe named adapters
-        db = IDB(None)
+        metadata = IDB(None)
 
-        objectquery = IQueryParser(query)()
+        objectquery = IQueryParser(query)(metadata)
         optimizedoq = IQueryOptimizer(objectquery)()
         algebra = IRewriter(optimizedoq)()
         optimizedalgebra = IAlgebraOptimizer(algebra)()
-        runnable = IAlgebraCompiler(optimizedalgebra)()
+        runnable = IAlgebraCompiler(optimizedalgebra)(metadata, algebra)
 
         return runnable
\ No newline at end of file

Added: Sandbox/adamg/ocql/trunk/src/ocql/parser/parser.txt
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/parser/parser.txt	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/parser/parser.txt	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,36 @@
+
+
+    >>> from ocql.parser.queryparser import QueryParser
+
+
+
+    #FAILS, why?
+    #>>> QueryParser("set [ ]")(None)
+    #Query(<type 'set'>, , Constant(1))
+
+    >>> QueryParser("set [ | 1 ]")(None)
+    Query(<type 'set'>, , Constant(1))
+
+    #FAILS, why?
+    #>>> QueryParser("list [ | 1 ]")(None)
+    #Query(<type 'set'>, , Constant(1))
+
+    >>> QueryParser("set [ | 1 ] union set [|2]")(None)
+    Union(Query(<type 'set'>, , Constant(1)), Query(<type 'set'>, , Constant(2)))
+
+    >>> QueryParser("set [ | 1 ] differ set [|2]")(None)
+    Differ(Query(<type 'set'>, , Constant(1)), Query(<type 'set'>, , Constant(2)))
+
+    >>> QueryParser("set [ i in ICourse | i ]")(None)
+    Query(<type 'set'>, In(Identifier(i), Identifier(ICourse)), Identifier(i))
+
+    >>> QueryParser("size set [ i in ICourse | i ]")(None)
+    Count(Query(<type 'set'>, In(Identifier(i), Identifier(ICourse)), Identifier(i)))
+
+    #FAILS, see raise "Help"
+    #>>> QueryParser("set [ d in IDepartments; every set [ c in ICourse; some c.runBy == d | c.credits ] == 2 | d.name ]")(None)
+
+    #>>> QueryParser("set [ c in ICourse; c.credits>3 | c.code ]")(None)
+
+    >>> QueryParser("set [ c in ICourse | c.code ]")(None)
+    Query(<type 'set'>, In(Identifier(c), Identifier(ICourse)), Property(Identifier(c), Identifier(code)))
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/parser/parser.txt
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,465 @@
+# -*- coding: UTF-8 -*-
+
+"""Parse a string to Query Object
+
+$Id$
+"""
+
+#TODOs:
+#add metadata into the picture!!!
+#remove shift/reduce conflicts, when possible
+#look after raise "Help"
+#revise according to new grammar
+
+from ply import lex, yacc
+from collections import deque
+from threading import local
+
+from zope.component import adapts
+from zope.component import provideAdapter
+from zope.interface import implements
+import zope.thread
+
+from ocql.queryobject.queryobject import *
+from ocql.interfaces import IQueryParser
+
+DEBUG = 0
+
+class SymbolContainer:
+    def __init__(self):
+        self.stack = deque()
+        self.stack.append(dict())
+
+    def addlevel(self):
+        top = self.current()
+        new = dict(top)
+        self.stack.append(new)
+
+        #print 'add'
+        #print self.stack
+
+    def dellevel(self):
+        self.stack.pop()
+
+        #print 'del'
+        #print self.stack
+
+    def current(self):
+        return self.stack[-1]
+
+tokens = ('TYPE', 'UNION', 'DIFFER', 'AND', 'OR', 'NOT', 'ELLIPSIS', 'IN',
+        'AS', 'SIZE', 'COND_OP', 'MODIFIER', 'QUANTOR', 'CONSTANT',
+        'IDENTIFIER', 'PLUS', 'MINUS', 'MUL', 'DIV', 'BRACEL', 'BRACER',
+        'SQUAREL', 'SQUARER', 'CURLYL', 'CURLYR',
+        'PIPE', 'DOT', 'SEMICOL', 'COMMA'
+        )
+
+precedence = (
+    ('left', 'UNION'),
+    ('left', 'DIFFER'),
+#   ('token', 'SQUAREL'),
+#   ('token', 'PIPE'),
+#   ('token', 'SQUARER'),
+    ('left', 'AND'),
+    ('left', 'OR'),
+    ('right', 'NOT'),
+    ('left', 'COND_OP'),
+    ('left', 'PLUS', 'MINUS'),
+    ('left', 'MUL', 'DIV'),
+#   ('token', 'IDENTIFIER'),
+#   ('token', 'BRACEL'),
+#   ('token', 'BRACER'),
+#   ('token', 'CONSTANT'),
+#   ('token', 'TYPE'),
+#   ('token', 'CURLYL'),
+#   ('token', 'CURLYR'),
+#   ('token', 'ELLIPSIS'),
+    ('left', 'DOT'),
+#   ('token', 'COMMA'),
+    ('left', 'SEMICOL'),
+
+    ('left', 'IN'),
+    ('left', 'AS'),
+
+#   ('token', 'MODIFIER'),
+#   ('token', 'QUANTOR'),
+
+    ('left', 'SIZE'),
+)
+
+class Lexer(object):
+    tokens = tokens
+    t_ignore = ' \t\n\r'
+
+    def t_error(self, t):
+        print "Illegal character '%s'" % t.value[0]
+        t.lexer.skip(1)
+
+    # Tokens
+    def t_TYPE(self, t):
+        r'(set|bag|map)'
+        return t
+
+    def t_UNION(self, t):
+        r'union'
+        return t
+
+    def t_DIFFER(self, t):
+        r'differ'
+        return t
+
+    def t_AND(self, t):
+        r'and'
+        return t
+
+    def t_OR(self, t):
+        r'or'
+        return t
+
+    def t_NOT(self, t):
+        r'not'
+        return t
+
+    def t_ELLIPSIS(self, t):
+        r'\.\.\.'
+        return t
+
+    def t_IN(self, t):
+        r'in'
+        return t
+
+    def t_AS(self, t):
+        r'as'
+        return t
+
+    def t_SIZE(self, t):
+        r'size'
+        return t
+
+    def t_COND_OP(self, t):
+        r'(<|>|<=|>=|==|!=)'
+        return t
+
+    def t_MODIFIER(self, t):
+        r'(atleast|atmost|just)'
+        return t
+
+    def t_QUANTOR(self, t):
+        r'(every|some)'
+        return t
+
+    def t_CONSTANT(self, t):
+        r'(\'(\\.|[^\'])*\'|"(\\.|[^"])*"|[0-9]+)'
+        return t
+
+    def t_IDENTIFIER(self, t):
+        r'[a-zA-Z][0-9a-zA-Z_]*'
+        if DEBUG: print "IDEN", t
+        return t
+
+    def t_PLUS(self, t):
+        r'\+'
+        return t
+
+    def t_MINUS(self, t):
+        r'-'
+        return t
+
+    def t_MUL(self, t):
+        r'\*'
+        return t
+
+    def t_DIV(self, t):
+        r'/'
+        return t
+
+    def t_BRACEL(self, t):
+        r'\('
+        return t
+
+    def t_BRACER(self, t):
+        r'\)'
+        return t
+
+    def t_SQUAREL(self, t):
+        r'\['
+        return t
+
+    def t_SQUARER(self, t):
+        r'\]'
+        return t
+
+    def t_CURLYL(self, t):
+        r'{'
+        return t
+
+    def t_CURLYR(self, t):
+        r'}'
+        return t
+
+    def t_PIPE(self, t):
+        r'\|'
+        return t
+
+    def t_DOT(self, t):
+        r'\.'
+        return t
+
+    def t_SEMICOL(self, t):
+        r';'
+        return t
+
+    def t_COMMA(self, t):
+        r','
+        return t
+
+class Parser(object):
+    tokens = tokens
+    precedence = precedence
+    metadata = None
+    symbols = None
+    types = { 'set' : set, 'list': list }
+    start = 'expr'
+
+    def __init__(self, metadata):
+        self.metadata = metadata
+        self.symbols = SymbolContainer()
+
+    def p_error(self, t):
+        print "Syntax error at '%s' (%s)" % (t.value, t.lexpos)
+
+    def p_expr_cond(self, t):
+        r'''expr : modifier nexpr COND_OP omodifier nexpr
+                 | expr COND_OP omodifier nexpr'''
+        raise "Help"
+
+    def p_expr_union(self, t):
+        r'''expr : expr UNION expr
+            nexpr : nexpr UNION nexpr
+        '''
+        t[0] = Union(self.metadata, self.symbols, t[1], t[3])
+        if DEBUG: print t[0]
+
+    def p_expr_differ(self, t):
+        r'''expr : expr DIFFER expr
+            nexpr : nexpr DIFFER nexpr
+        '''
+        t[0] = Differ(self.metadata, self.symbols, t[1], t[3])
+        if DEBUG: print t[0]
+
+    def p_expr_query(self, t):
+        r'''expr : TYPE SQUAREL xprs PIPE expr SQUARER
+            nexpr : TYPE SQUAREL xprs PIPE expr SQUARER
+        '''
+        t[0] = Query(self.metadata, self.symbols, self.types[t[1]], t[3], t[5])
+        if DEBUG: print "p_expr_query", t[0]
+
+    def p_expr_and(self, t):
+        r'''expr : expr AND expr
+            nexpr : nexpr AND nexpr
+        '''
+        t[0] = And(self.metadata, self.symbols, t[1], t[3])
+        if DEBUG: print t[0]
+
+    def p_expr_or(self, t):
+        r'''expr : expr OR expr
+            nexpr : nexpr OR nexpr
+        '''
+        t[0] = Or(self.metadata, self.symbols, t[1], t[3])
+        if DEBUG: print t[0]
+
+    def p_expr_plus(self, t):
+        r'''expr : expr PLUS expr
+            nexpr : nexpr PLUS nexpr
+        '''
+        t[0] = Add(self.metadata, self.symbols, t[1], t[3])
+        if DEBUG: print t[0]
+
+    def p_expr_minus(self, t):
+        r'''expr : expr MINUS expr
+            nexpr : nexpr MINUS nexpr
+        '''
+        t[0] = Sub(self.metadata, self.symbols, t[1], t[3])
+        if DEBUG: print t[0]
+
+    def p_expr_mul(self, t):
+        r'''expr : expr MUL expr
+            nexpr : nexpr MUL nexpr
+        '''
+        t[0] = Mul(self.metadata, self.symbols, t[1], t[3])
+        if DEBUG: print t[0]
+
+    def p_expr_div(self, t):
+        r'''expr : expr DIV expr
+            nexpr : nexpr DIV nexpr
+        '''
+        t[0] = Div(self.metadata, self.symbols, t[1], t[3])
+        if DEBUG: print t[0]
+
+    def p_expr_not(self, t):
+        r'''expr : NOT expr
+            nexpr : NOT nexpr
+        '''
+        t[0] = Not(self.metadata, self.symbols, t[2])
+        if DEBUG: print t[0]
+
+    def p_expr_dot(self, t):
+        r'''expr : expr DOT expr
+            nexpr : nexpr DOT expr
+        '''
+        t[0] = Property(self.metadata, self.symbols, t[1], t[3])
+        if DEBUG: print t[0]
+
+    def p_expr_id(self, t):
+        r'''expr : IDENTIFIER
+           nexpr : IDENTIFIER
+        '''
+        t[0] = Identifier(self.metadata, self.symbols, t[1])
+        if DEBUG: print "p_expr_id", t[0]
+
+
+    def p_expr_call(self, t):
+        r'''expr : IDENTIFIER BRACEL exprs BRACER
+            nexpr : IDENTIFIER BRACEL exprs BRACER
+        '''
+        raise NotImplementedError("Function call")
+
+    def p_expr_const(self, t):
+        r'''expr : CONSTANT
+            nexpr : CONSTANT
+        '''
+        t[0] = Constant(self.metadata, self.symbols, t[1])
+        if DEBUG: print t[0]
+
+    def p_expr_array(self, t):
+        r'''expr : TYPE '{' exprs '}'
+            nexpr : TYPE '{' exprs '}'
+        '''
+        raise NotImplementedError("array")
+
+    def p_expr_range(self, t):
+        r'''expr : TYPE CURLYL expr ELLIPSIS expr CURLYR
+            nexpr : TYPE CURLYL expr ELLIPSIS expr CURLYR
+        '''
+        raise NotImplementedError("range")
+
+
+    def p_expr_index(self, t):
+        r'''expr : expr DOT SQUAREL expr SQUARER
+            nexpr : nexpr DOT SQUAREL expr SQUARER
+        '''
+        t[0] = Index(self.metadata, self.symbols, t[1], t[4])
+        if DEBUG: print t[0]
+
+    def p_expr_size(self, t):
+        r'''expr : SIZE expr
+            nexpr : SIZE expr
+        '''
+        t[0] = Count(self.metadata, self.symbols, t[2])
+        if DEBUG: print t[0]
+
+    def p_expr_bracket(self, t):
+        r'''expr : BRACEL expr BRACER
+            nexpr : BRACEL expr BRACEL
+        '''
+        t[0] = t[2]
+        if DEBUG: print t[0]
+
+    def p_omodifier(self, t):
+        r'''omodifier : QUANTOR
+                      | MODIFIER
+        '''
+        if DEBUG: print t[0]
+
+    def p_modifier(self, t):
+        r'''modifier : QUANTOR
+                     | MODIFIER
+        '''
+        if DEBUG: print t[0]
+
+    def p_exprs(self, t):
+        r'''exprs : expr
+                  | expr COMMA exprs
+        '''
+        if DEBUG: print t[0]
+
+    def p_in_expr(self, t):
+        r'''in_expr : IDENTIFIER IN expr'''
+        t[0] = In(self.metadata,
+                  self.symbols,
+                  Identifier(self.metadata,
+                             self.symbols,
+                             t[1]),
+                  t[3])
+        if DEBUG: print "p_in_expr", t[0]
+        if DEBUG: print t[1], t[3]
+
+    def p_as_expr(self, t):
+        r'''as_expr : IDENTIFIER AS expr'''
+        if DEBUG: print "p_as_expr", t[0]
+
+    def p_xprs(self, t):
+        r'''xprs :
+                 | xpr SEMICOL xprs
+                 | xpr
+        '''
+        if len(t)==1:
+            t[0] = []
+        elif len(t)==2:
+            t[0] = [ t[1] ]
+        else:
+            t[3].insert(t[0], 0)
+            t[0] = t[3]
+        if DEBUG: print "p_xprs", t[0]
+
+    def p_xpr(self, t):
+        r'''xpr : as_expr
+                | in_expr
+                | expr
+        '''
+        t[0] = t[1]
+        if DEBUG: print "p_xpr", t[0]
+
+#these are here, to keep lexer and parser instantiation to a minimum possible
+#level because they are quite expensive operations
+#parsers must be thread safe on the other hand!
+LEXER = lex.lex(object=Lexer(), debug=0)
+#PARSERS = local()
+
+def parse(str, metadata):
+    lexer = LEXER.clone()
+
+    #global PARSERS
+    #try:
+    #    parser = PARSERS.parser
+    #
+    #    try:
+    #        parser.restart()
+    #    except AttributeError:
+    #        pass
+    #
+    #except AttributeError:
+    #    parser = yacc.yacc(module = Parser(metadata))
+    #    PARSERS.parser = parser
+
+    try:
+        parser = yacc.yacc(module = Parser(metadata))
+
+        retval = parser.parse(str, lexer = lexer)
+    except Exception, e:
+        if DEBUG: print e
+        raise
+    return retval
+
+class QueryParser(object):
+    implements(IQueryParser)
+    adapts(basestring)
+
+    def __init__(self, context):
+        self.context = context
+        #self.db = db
+
+    def __call__(self, metadata):
+        strg = self.context
+        return parse(strg, metadata)
+        #return parse(strg, None)


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/parser/tests.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/parser/tests.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/parser/tests.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,14 @@
+import unittest
+import doctest
+from zope.testing.doctestunit import DocTestSuite,DocFileSuite
+
+def test_suite():
+    flags =  doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
+    return unittest.TestSuite((
+        DocFileSuite('parser.txt',
+            optionflags=flags),
+        ))
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/parser/tests.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/qoptimizer.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/qoptimizer.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/qoptimizer.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,34 @@
+# -*- coding: UTF-8 -*-
+
+""" Optimizing will be done later,
+at the moment this is just a stub returning it's input
+
+$Id$
+"""
+
+from zope.component import adapts
+from zope.interface import implements
+from zope.security.proxy import removeSecurityProxy
+from zope.interface import directlyProvidedBy
+from zope.interface import directlyProvides
+
+from ocql.interfaces import IQueryOptimizer
+
+from ocql.interfaces import IObjectQuery
+from ocql.interfaces import IOptimizedObjectQuery
+
+def addMarkerIF(obj, marker):
+    obj = removeSecurityProxy(obj)
+    if not marker.providedBy(obj):
+        directlyProvides(obj, directlyProvidedBy(obj), marker)
+
+class QueryOptimizer(object):
+    implements(IQueryOptimizer)
+    adapts(IObjectQuery)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self):
+        addMarkerIF(self.context, IOptimizedObjectQuery)
+        return self.context
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/qoptimizer.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/qoptimizer.txt
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/qoptimizer.txt	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/qoptimizer.txt	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,25 @@
+
+
+    >>> from ocql.qoptimizer.qoptimizer import QueryOptimizer
+    >>> from ocql.interfaces import IOptimizedObjectQuery
+
+Currently the optimizer is doing NOTHING, it just returns what it gets.
+(And adds the interface IOptimizedObjectQuery)
+
+    >>> class Dummy(object):
+    ...     def __init__(self, value):
+    ...          self.value = value
+
+    >>> in_=Dummy('foo-bar')
+    >>> in_.value
+    'foo-bar'
+
+    >>> out = QueryOptimizer(in_)()
+
+    >>> print out
+    <Dummy object at ...>
+    >>> out.value
+    'foo-bar'
+
+    >>> IOptimizedObjectQuery.providedBy(out)
+    True
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/qoptimizer.txt
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/tests.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/tests.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/tests.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,14 @@
+import unittest
+import doctest
+from zope.testing.doctestunit import DocTestSuite,DocFileSuite
+
+def test_suite():
+    flags =  doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
+    return unittest.TestSuite((
+        DocFileSuite('qoptimizer.txt',
+            optionflags=flags),
+        ))
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/qoptimizer/tests.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/queryobject/__init__.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/queryobject/__init__.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/queryobject/__init__.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1 @@
+#
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/queryobject/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/queryobject/queryobject.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/queryobject/queryobject.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/queryobject/queryobject.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,539 @@
+# -*- coding: UTF-8 -*-
+
+"""Classes for the Query Object representation
+
+$Id$
+"""
+
+#TODOS:
+#write Interfaces for all classes
+
+#move self.rewrite to ocql.rewriter into adapters
+
+#add self.__repr__ to ALL, see Query class
+
+#implement a traversable tree of queryobjects (parent, child, sibling, ....)
+
+from zope.interface import implements
+
+from ocql.interfaces import IObjectQuery
+
+class QueryObject:
+    #TODO: this is dirty here, at the end we'll need to have a tree of
+    #QueryObject's whose topmost element will only get this IF
+    implements(IObjectQuery)
+
+    metadata = None
+    symbols = None
+
+    def __init__(self, metadata, symbols):
+        self.metadata = metadata
+        self.symbols = symbols
+
+    def addSymbol(self):
+        pass
+
+    def get_class(self):
+        s = self.symbols.current()
+        try:
+            return s[self.name]
+        except KeyError:
+            return self.metadata.get_class(self.name)
+        except AttributeError:
+            from pub.dbgpclient import brk; brk()
+
+
+    def get_collection_type(self, klass=None):
+        if klass is None:
+            klass = self.get_class()
+
+            if klass is None:
+                from pub.dbgpclient import brk; brk()
+
+        rv = klass.get_collection_type()
+        #print self.name,rv
+        return rv
+
+    def rewrite(self, algebra):
+        raise NotImplementedError(self)
+
+class Term:
+    pass
+
+class Expression(Term, QueryObject):
+    pass
+
+#
+# General
+#
+class hasClassWith(Expression):
+    #NotImplementedError
+    expression = None
+    klass = None
+    conditional = None
+
+    def __init__(self, metadata, symbols, expr, klass, conditional):
+        self.metadata = metadata
+        self.symbols = symbols
+        self.expression = expr
+        self.klass = klass
+        self.conditional = conditional
+
+class Identifier(Expression):
+    name = None
+
+    def __init__(self, metadata, symbols, name):
+        self.metadata = metadata
+        self.symbols = symbols
+        self.name = name
+
+    def __repr__(self):
+        return "%s(%s)" % (
+            self.__class__.__name__,
+            str(self.name),
+            )
+
+    def rewrite(self, algebra):
+        return algebra.Identifier(self.name)
+
+class Constant(Expression):
+    #this shall be abstract?
+    value = None
+
+    def __init__(self, metadata, symbols, value):
+        self.metadata = metadata
+        self.symbols = symbols
+        self.value=value
+
+    def __repr__(self):
+        return "%s(%s)" % (
+            self.__class__.__name__, self.value)
+
+    def rewrite(self, algebra):
+        return algebra.Constant(self.value)
+
+class StringConstant(Constant):
+    pass
+
+class NumericConstant(Constant):
+    #TODO: convert value to string?
+    pass
+
+class BooleanConstant(Constant):
+    #TODO: convert value to string?
+    pass
+
+class CollectionConstant(Constant):
+    pass
+
+class Query(Expression):
+    collection_type = None
+    terms = None
+    target = None
+
+    def __init__(self, metadata, symbols, collection_type, terms, target):
+        self.metadata = metadata
+        self.symbols = symbols
+        self.collection_type = collection_type
+        self.terms = terms
+        self.target = target
+
+    def __repr__(self):
+        return "%s(%s, %s, %s)" % (
+            self.__class__.__name__,
+            str(self.collection_type),
+            '; '.join([str(t) for t in self.terms]),
+            str(self.target)
+        )
+
+    def get_collection_type(self, klass=None):
+        return self.collection_type
+
+    def rewrite(self, algebra):
+        self.symbols.addlevel()
+        rv=None
+
+        if len(self.terms):
+            for t in self.terms:
+                t.addSymbol()
+
+            firstTerm = self.terms[0]
+            if isinstance(firstTerm, In):
+
+                ctype = firstTerm.get_collection_type()
+
+                rv = algebra.Iter(
+                    self.collection_type,
+                    algebra.Lambda(
+                        firstTerm.identifier.name,
+                        Query(
+                            self.metadata,
+                            self.symbols,
+                            self.collection_type,
+                            self.terms[1:],
+                            self.target
+                            ).rewrite(algebra)
+                    ), algebra.Make(
+                        self.collection_type,
+                        ctype,
+                        firstTerm.expression.rewrite(algebra)
+                        ) # FIXME: ?set? must be determined by type(firstTerm.expression)
+                )
+            elif isinstance(firstTerm, Alias):
+                rv = Query(
+                    self.metadata,
+                    self.collection_type,
+                    [In(
+                        self.metadata,
+                        firstTerm.identifier,
+                        firstTerm.expression
+                        )]+self.terms[1:],
+                    self.target).rewrite(algebra)
+            else:
+                rv = algebra.If(
+                    firstTerm.rewrite(algebra),
+                    Query(
+                        self.metadata,
+                        self.collection_type,
+                        self.terms[1:],
+                        self.target).rewrite(algebra),
+                    algebra.Empty(self.collection_type, None)
+                )
+        else:
+            rv = algebra.Single(
+                self.collection_type,
+                self.target.rewrite(algebra))
+
+        self.symbols.dellevel()
+        return rv
+
+class In(Term):
+    identifier = None
+    expression = None
+
+    def __init__(self, metadata, symbols, identifier, expression):
+        self.metadata = metadata
+        self.symbols = symbols
+        self.identifier = identifier
+        self.expression = expression
+
+    def __repr__(self):
+        return "%s(%s, %s)" % (
+            self.__class__.__name__,
+            str(self.identifier),
+            str(self.expression)
+            )
+
+    def addSymbol(self):
+        s = self.symbols.current()
+        #s[self.identifier.name] = self.metadata.get_class(
+        #    self.expression.name)
+        s[self.identifier.name] = self.expression.get_class()
+
+    def get_collection_type(self):
+        rv = self.expression.get_collection_type()
+        return rv
+
+class Alias(Term):
+    identifier = None
+    expression = None
+
+    def __init__(self, metadata, symbols, identifier, expression):
+        self.metadata = metadata
+        self.symbols = symbols
+        self.identifier = identifier
+        self.expression = expression
+
+    def __repr__(self):
+        return "%s(%s, %s)" % (
+            self.__class__.__name__,
+            str(self.identifier),
+            str(self.expression)
+            )
+
+    def addSymbol(self):
+        s = self.symbols.current()
+        #TODO: that's not really good
+        r = self.expression.get_collection_type()
+
+        s[self.identifier.name] = r
+
+    def get_collection_type(self):
+        rv = self.expression.get_collection_type()
+        #print self.expression.name,rv
+        return rv
+
+#
+# Binary operators
+#
+class Binary(Expression):
+    left = None
+    right = None
+
+    def __init__(self, metadata, symbols, left, right):
+        self.metadata = metadata
+        self.symbols = symbols
+        self.left = left
+        self.right = right
+
+    def __repr__(self):
+        return "%s(%s, %s)" % (
+            self.__class__.__name__,
+            str(self.left), str(self.right)
+            )
+
+    def rewrite(self, algebra):
+        return algebra.Binary(
+            self.left.rewrite(algebra),
+            self.get_operator(algebra),
+            self.right.rewrite(algebra))
+
+# Sets and properties
+class Union(Binary):
+    def rewrite(self, algebra):
+        return algebra.Union(
+            self.left.get_collection_type(),
+            self.left.rewrite(algebra),
+            self.right.rewrite(algebra))
+
+class Differ(Binary):
+    def rewrite(self, algebra):
+        return algebra.Differ(
+            self.left.get_collection_type(),
+            self.left.rewrite(algebra),
+            self.right.rewrite(algebra))
+
+class And(Binary):
+    def get_operator(self, algebra):
+        return algebra.Operator('and')
+
+class Or(Binary):
+    def get_operator(self, algebra):
+        return algebra.Operator('or')
+
+class Property(Binary):
+    def rewrite(self, algebra): # FIXME: Ezt gondold at...
+        return algebra.Identifier(
+            '.'.join([self.left.name, self.right.name]))
+
+    def get_class(self):
+        t = self.left.get_class()
+
+        return t
+
+    def get_collection_type(self):
+        t = self.left.get_class()
+        try:
+            r = t[self.right.name]
+        except:
+            from pub.dbgpclient import brk; brk()
+
+        #print self.left.name+'.'+self.right.name,r
+
+        return r
+
+class Index(Binary):
+    #NotImplementedError
+    pass
+
+
+# Arithmetic operators
+class Arithmetic(Binary):
+    pass
+
+class Add(Arithmetic):
+    def get_operator(self, algebra):
+        return algebra.Operator('+')
+
+class Mul(Arithmetic):
+    def get_operator(self, algebra):
+        return algebra.Operator('*')
+
+class Sub(Arithmetic):
+    def get_operator(self, algebra):
+        return algebra.Operator('-')
+
+class Div(Arithmetic):
+    def get_operator(self, algebra):
+        return algebra.Operator('/')
+
+#
+# Unary operators
+#
+class Unary(Expression):
+    expression = None
+
+    def __init__(self, metadata, symbols, expression):
+        self.metadata = metadata
+        self.symbols = symbols
+        self.expression = expression
+
+    def __repr__(self):
+        return "%s(%s)" % (
+            self.__class__.__name__,
+            str(self.expression)
+            )
+
+class Not(Unary):
+    def rewrite(self, algebra):
+        return algebra.Not(self.expression.rewrite(algebra))
+
+class Aggregate(Unary):
+    pass
+
+class Count(Aggregate):
+    def rewrite(self, algebra):
+        return algebra.Reduce(
+            bag, # FIXME milyen bag
+            0,
+            algebra.Lambda('i', algebra.Constant(1)),
+            algebra.Operator('+'),
+            make(bag, set, self.expression.rewrite(algebra))
+            # FIXME ?set? must be determined by type(self.expression)
+        )
+
+class Sum(Aggregate):
+    #NotImplementedError
+    pass
+
+#
+# Conditional
+#
+class Quantor(QueryObject):
+    def rewrite(self, algebra, expression, quanter, operator):
+        raise NotImplementedError()
+
+class Quanted:
+    quantor = None
+    expression = None
+
+    def __init__(self, metadata, symbols, quantor, expression):
+        self.metadata = metadata
+        self.symbols = symbols
+        self.quantor = quantor
+        self.expression = expression
+
+    def rewrite(self, algebra, expression, operator):
+        return self.quantor.rewrite(algebra, expression, self.expression, operator)
+
+# Quantors
+class Every(Quantor):
+    def rewrite(self, algebra, expression, quanted, operator):
+        ctype = quanted.get_collection_type()
+
+        return algebra.Reduce(
+            ctype, # FIXME ?set? but which type() to take? quanted.expression?
+            algebra.Identifier('True'),
+            algebra.Lambda('i',
+                operator.__class__(
+                    self.metadata,
+                    Identifier(
+                        self.metadata,
+                        'i'),
+                    expression
+                ).rewrite(algebra)
+            ),
+            algebra.Operator('and'),
+            quanted.rewrite(algebra)
+        )
+
+class Some(Quantor):
+    def rewrite(self, algebra, expression, quanted, operator):
+        ctype = quanted.get_collection_type()
+        return algebra.Reduce(
+            ctype, # FIXME ?set? but which type() to take? quanted.expression?
+            algebra.Identifier('False'),
+            algebra.Lambda('i',
+                operator.__class__(
+                    self.metadata,
+                    Identifier(self.metadata, 'i'),
+                    expression
+                ).rewrite(algebra)
+            ),
+            algebra.Operator('or'),
+            quanted.rewrite(algebra)
+        )
+
+class Atmost(Quantor):
+    expr = None
+
+    def __init__(self, metadata, symbols, expr):
+        raise NotImplementedError(self)
+        self.metadata = metadata
+        self.symbols = symbols
+        self.expr = expr
+
+class Atleast(Quantor):
+    expr = None
+
+    def __init__(self, metadata, symbols, expr):
+        raise NotImplementedError(self)
+        self.metadata = metadata
+        self.symbols = symbols
+        self.expr = expr
+
+class Just(Quantor):
+    expr = None
+
+    def __init__(self, metadata, symbols, expr):
+        raise NotImplementedError(self)
+        self.metadata = metadata
+        self.symbols = symbols
+        self.expr = expr
+
+# Logical operators
+class Condition(Expression):
+    left = None
+    right = None
+
+    def __init__(self, metadata, symbols, left, right):
+        self.metadata = metadata
+        self.symbols = symbols
+        self.left = left
+        self.right = right
+
+    def rewrite(self, algebra):
+        if isinstance(self.left, Quanted):
+            return self.left.rewrite(
+                algebra,
+                self.right,
+                self)
+        if isinstance(self.right, Quanted):
+            return self.right.rewrite(
+                algebra,
+                self.left,
+                self)
+        else:
+            return algebra.Binary(self.left.rewrite(algebra), self.get_operator(algebra), self.right.rewrite(algebra))
+
+class Eq(Condition):
+    def get_operator(self, algebra):
+        return algebra.Operator('==')
+
+class Ne(Condition):
+    def get_operator(self, algebra):
+        return algebra.Operator('!=')
+
+class Lt(Condition):
+    def get_operator(self, algebra):
+        return algebra.Operator('<')
+
+class Gt(Condition):
+    def get_operator(self, algebra):
+        return algebra.Operator('>')
+
+class Le(Condition):
+    def get_operator(self, algebra):
+        return algebra.Operator('<=')
+
+class Ge(Condition):
+    def get_operator(self, algebra):
+        return algebra.Operator('>=')
+
+# TODO: missing:
+    #xi{Es}
+    #xi{E1..E2}
+    #I(Es)
+    #K
+    #==,
+    #~==


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/queryobject/queryobject.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,417 @@
+# -*- coding: UTF-8 -*-
+
+"""Algebra operators
+
+$Id$
+"""
+
+#
+# decided to let these depend on the database
+# so this is the implementation
+#
+
+from zope.interface import implements
+
+from ocql.interfaces import IAlgebraObject
+
+class Algebra:
+    """Signature definition of Algebra operation classes.
+    shall be moved to an IF later
+    """
+    #TODO: this is dirty here, at the end we'll need to have a tree of
+    #Algebra's whose topmost element will only get this IF
+    implements(IAlgebraObject)
+
+    def compile(self):
+        """Return the compiled python code"""
+
+    def walk(self):
+        """Iterate the Algebra object tree"""
+
+class BaseAlgebra(Algebra):
+    pass
+
+class Empty(BaseAlgebra):
+    """
+    >>> Empty(set,None).compile()
+    'set()'
+    >>> Empty(list,None).compile()
+    '[]'
+    """
+    def __init__(self, klass, expr):
+        self.klass = klass
+
+    def compile(self):
+        if self.klass==set:
+            return 'set()'
+        elif self.klass==list:
+            return '[]'
+
+    def __repr__(self):
+        return 'Empty(%s)'%(self.klass)
+
+    def walk(self):
+        yield self
+
+class Single(BaseAlgebra):
+    """
+    >>> Single(set,Constant('c')).compile()
+    'set([c])'
+    >>> Single(list,Constant('c')).compile()
+    '[c]'
+    """
+
+    def __init__(self, klass, expr):
+        self.klass = klass
+        self.expr = expr
+
+    def compile(self):
+        if self.klass==set:
+            return 'set(['+self.expr.compile()+'])'
+        elif self.klass==list:
+            return '['+self.expr.compile()+']'
+
+    def __repr__(self):
+        return 'Single(%s,%s)'%(self.klass, self.expr)
+
+    def walk(self):
+        yield self
+        for t in self.expr.walk():
+            yield t
+
+class Union(BaseAlgebra):
+    """
+    >>> Union(set,Empty(set,None),Single(set,Identifier('c'))).compile()
+    'set.union(set(),set([c]))'
+    >>> Union(list,Empty(list,None),Single(list,Identifier('c'))).compile()
+    '([])+([c])'
+    """
+    def __init__(self, klass, coll1, coll2):
+        self.klass=klass
+        self.coll1=coll1
+        self.coll2=coll2
+
+    def compile(self):
+        if self.klass==set:
+            return 'set.union(%s,%s)' % (
+                self.coll1.compile(),
+                self.coll2.compile())
+        elif self.klass==list:
+            return '(%s)+(%s)'%(
+                self.coll1.compile(),
+                self.coll2.compile())
+
+    def __repr__(self):
+        return 'Union(%s,%s,%s)'%(self.klass, self.coll1, self.coll2)
+
+    def walk(self):
+        yield self
+        for t in self.coll1.walk():
+            yield t
+        for t in self.coll2.walk():
+            yield t
+
+#class Differ:
+#    def __init__(self, klass, start, end):
+#        self.klass = klass
+#        self.start = start
+#        self.end = end
+#
+#    def compile(self):
+#        if self.klass == set:
+#            return 'set(range(%s,%s))' % (self.start.compile(),self.end.compile())
+#        if self.klass == list:
+#            return 'range(%s,%s)' % (self.start.compile(),self.end.compile())
+
+
+class Iter(BaseAlgebra):
+    def __init__(self, klass, func, coll):
+        self.klass = klass
+        self.func = func
+        self.coll = coll
+
+    def compile(self):
+        if self.func is Lambda and \
+            self.coll is Collection and \
+            self.func.expr is If:
+
+            # You can place here some specialized code...
+            if self.klass == set:
+                return 'reduce(set.union, map(%s,%s) , set())' % \
+                    (self.func.compile(), self.coll.compile())
+            if self.klass == list:
+                return 'reduce(operator.add, map(%s,%s) , [])' % \
+                    (self.func.compile(), self.coll.compile())
+        else:
+            if self.klass == set:
+                return 'reduce(set.union, map(%s,%s) , set())' % \
+                    (self.func.compile(), self.coll.compile())
+            if self.klass == list:
+                return 'reduce(operator.add, map(%s,%s) , [])' % \
+                    (self.func.compile(), self.coll.compile())
+
+    def __repr__(self):
+        return "Iter(%s,%s,%s)"%(self.klass, self.func, self.coll)
+
+    def walk(self):
+        yield self
+        for t in self.func.walk():
+            yield t
+        for t in self.coll.walk():
+            yield t
+
+class Select(BaseAlgebra):
+    def __init__(self, klass, func, coll):
+        self.klass = klass
+        self.func = func
+        self.coll = coll
+
+    def compile(self):
+        if self.klass == set:
+            return 'set(filter(%s,%s))' % (
+                self.func.compile(),
+                self.coll.compile())
+        if self.klass == list:
+            return 'filter(%s,%s)' % (
+                self.func.compile(),
+                self.coll.compile())
+
+    def __repr__(self):
+        return "Select(%s,%s,%s)"%(self.klass, self.func, self.coll)
+
+    def walk(self):
+        yield self
+        for t in self.func.walk():
+            yield t
+        for t in self.coll.walk():
+            yield t
+
+class Reduce(BaseAlgebra):
+    def __init__(self, klass, expr, func, aggreg, coll):
+        self.klass = klass
+        self.expr = expr
+        self.func = func
+        self.aggreg = aggreg
+        self.coll = coll
+
+    def compile(self):
+        if self.klass == set:
+            return 'reduce(%s,map(%s,%s),%s)' % (
+                self.aggreg.compile(),
+                self.func.compile(),
+                self.coll.compile(),
+                self.expr.compile())
+        if self.klass == list:
+            return 'reduce(%s,map(%s,%s),%s)' % (
+                self.aggreg.compile(),
+                self.func.compile(),
+                self.coll.compile(),
+                self.expr.compile())
+
+    def __repr__(self):
+        return "Reduce(%s,%s,%s,%s,%s)"%(self.klass, self.expr, self.func, self.aggreg, self.coll)
+
+    def walk(self):
+        yield self
+        for t in self.expr.walk():
+            yield t
+        for t in self.func.walk():
+            yield t
+        for t in self.aggreg.walk():
+            yield t
+        for t in self.coll.walk():
+            yield t
+
+#class Equal:
+#    def __init__(self, klass, coll1, coll2):
+#        self.klass = klass
+#        self.coll1 = coll1
+#        self.coll2 = coll2
+#
+#    def compile(self):
+#        if self.klass == set:
+#            return 'set(filter(%s,%s))' % (self.coll1.compile(),self.coll1.compile())
+#        if self.klass == list:
+#            return 'filter(%s,%s)' % (self.coll1.compile(),self.coll2.compile())
+#
+class Range(BaseAlgebra):
+    def __init__(self, klass, start, enf):
+        self.klass = klass
+        self.start = start
+        self.end = end
+
+    def compile(self):
+        if self.klass == set:
+            return 'set(range(%s,%s))' % (
+                self.start.compile(),
+                self.end.compile())
+        if self.klass == list:
+            return 'range(%s,%s)' % (
+                self.start.compile(),
+                self.end.compile())
+
+    def walk(self):
+        yield self
+        for t in self.start.walk():
+            yield t
+        for t in self.end.walk():
+            yield t
+
+
+#class Index
+
+class Make(BaseAlgebra):
+    def __init__(self, coll1, coll2, expr):
+        self.expr = expr
+        self.coll1 = coll1
+        self.coll2 = coll2
+
+    def compile(self):
+        #TODO: no conversion??? or you just didn't know the from-to?
+        return '%s(metadata.getAll("%s"))' % (
+            self.coll1.__name__,
+            self.expr.compile())
+
+    def __repr__(self):
+        return "Make(%s,%s,%s)" %(self.coll1, self.coll2, self.expr)
+
+    def walk(self):
+        yield self
+        for t in self.expr.walk():
+            yield t
+
+#class And:
+#class Being:
+
+class If(BaseAlgebra):
+    def __init__(self, cond, expr1, expr2):
+        self.cond = cond
+        self.expr1 = expr1
+        self.expr2 = expr2
+
+    def compile(self):
+        #TODO: is this 100%?
+        return '((%s) and (%s) or (%s))' % (
+            self.cond.compile(),
+            self.expr1.compile(),
+            self.expr2.compile())
+
+    def __repr__(self):
+        return "If(%s,%s,%s)" % (self.cond, self.expr1, self.expr2)
+
+    def walk(self):
+        yield self
+        for t in self.cond.walk():
+            yield t
+        for t in self.expr1.walk():
+            yield t
+        for t in self.expr2.walk():
+            yield t
+
+#
+#
+#
+class Lambda(BaseAlgebra):
+    def __init__(self, var, expr):
+        self.var = var
+        self.expr = expr
+
+    def compile(self):
+        return 'lambda %s: %s'%(
+            self.var,
+            self.expr.compile())
+
+    def __repr__(self):
+        return "Lambda %s: %s" %(self.var, self.expr)
+
+    def walk(self):
+        yield self
+        for t in self.expr.walk():
+            yield t
+
+class Constant(BaseAlgebra):
+    def __init__(self, value):
+        self.value = value
+
+    def compile(self):
+        return '%s'%(self.value)
+
+    def __repr__(self):
+        return "`%s`" %(self.value)
+
+    def walk(self):
+        yield self
+
+class Identifier(BaseAlgebra):
+    def __init__(self, name):
+        self.name=name
+
+    def compile(self):
+        return self.name
+
+    def __repr__(self):
+        return "%s" % self.name
+
+    def walk(self):
+        yield self
+
+class Binary(BaseAlgebra):
+    def __init__(self, left, op, right):
+        self.left = left
+        self.op = op
+        self.right = right
+
+    def compile(self):
+        return '%s%s%s' % (self.left.compile(),
+                           self.op.op,
+                           self.right.compile())
+
+    def __repr__(self):
+        return "%s%s%s" % (self.left, self.op.op, self.right)
+
+    def walk(self):
+        yield self
+        for t in self.left.walk():
+            yield t
+        for t in self.right.walk():
+            yield t
+
+class Operator(BaseAlgebra):
+    ops = {
+            'or': 'operator.or_',
+            'and': 'operator.and_',
+            'not': 'operator.not_',
+            '+': 'operator.add', '-': 'operator.sub',
+            '*': 'operator.mul', '/': 'operator.div',
+            '<': 'operator.lt', '>': 'operator.gt',
+            '<=': 'operator.le', '>=': 'operator.ge',
+            '==': 'operator.eq', '~=': 'operator.ne',
+            }
+    def __init__(self, op):
+        self.op = op
+
+    def compile(self):
+        return self.ops[self.op]
+
+    def __repr__(self):
+        return self.op
+
+    def walk(self):
+        yield self
+#class Property:
+#   def __init__(self, left, right):
+#        self.left = left
+#        self.right = right
+#
+#    def compile(self):
+#        return '%s.%s' (self.left.compile(),self.right.compile())
+#
+#    def __repr__(self):
+#        return '%s.%s' (self.left,self.right)
+
+def _test():
+    import doctest
+    doctest.testmod()
+
+if __name__ == "__main__":
+    _test()


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,29 @@
+# -*- coding: UTF-8 -*-
+
+"""Rewrites the Query Object to Algebra Object
+
+$Id$
+"""
+
+#BIG-BIG-BIG TODO:
+# move all queryobject.rewrite to this package
+# using adapters to do the rewrite
+
+from zope.component import adapts
+from zope.interface import implements
+
+from ocql.interfaces import IRewriter
+from ocql.interfaces import IOptimizedObjectQuery
+
+from ocql.rewriter import algebra as target_algebra
+
+class Rewriter(object):
+    implements(IRewriter)
+    adapts(IOptimizedObjectQuery)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self):
+        query = self.context
+        return query.rewrite(target_algebra)


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.txt
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.txt	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.txt	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,50 @@
+
+I'm sorry, but I'm lazy here, in reality we would have to create
+stubs for all ocql.queryobject classes and use those...
+But it's a lot faster to reuse the parser and the existing classes.
+
+Add queries first to parser.txt doctest, after they pass there they can be
+added here.
+
+    >>> from ocql.parser.queryparser import QueryParser
+    >>> from ocql.qoptimizer.qoptimizer import QueryOptimizer
+    >>> from ocql.rewriter.rewriter import Rewriter
+
+    >>> from ocql.testing.database import TestMetadata
+
+
+    >>> qo = QueryParser("set [ | 1 ]")(TestMetadata())
+    >>> opt = QueryOptimizer(qo)()
+    >>> alg = Rewriter(opt)()
+    >>> print str(alg)
+    Single(<type 'set'>,`1`)
+
+
+    >>> qo = QueryParser("set [ | 1 ] union set [|2]")(TestMetadata())
+    >>> opt = QueryOptimizer(qo)()
+    >>> alg = Rewriter(opt)()
+    >>> print str(alg)
+    Union(<type 'set'>,Single(<type 'set'>,`1`),Single(<type 'set'>,`2`))
+
+
+    #Differ not implemented
+    #>>> qo = QueryParser("set [ | 1 ] differ set [|2]")(TestMetadata())
+    #>>> opt = QueryOptimizer(qo)()
+    #>>> alg = Rewriter(opt)()
+    #>>> print str(alg)
+    #Union(<type 'set'>,Single(<type 'set'>,`1`),Single(<type 'set'>,`2`))
+
+
+    >>> qo = QueryParser("set [ i in ICourse | i ]")(TestMetadata())
+    >>> opt = QueryOptimizer(qo)()
+    >>> alg = Rewriter(opt)()
+    >>> print str(alg)
+    Iter(<type 'set'>,Lambda i: Single(<type 'set'>,i),Make(<type 'set'>,<type 'set'>,ICourse))
+
+
+    #bag not implemented
+    #>>> qo = QueryParser("size set [ i in ICourse | i ]")(TestMetadata())
+    #>>> opt = QueryOptimizer(qo)()
+    #>>> alg = Rewriter(opt)()
+    #>>> print str(alg)
+    #Iter(<type 'set'>,Lambda i: Single(<type 'set'>,i),Make(<type 'set'>,<type 'set'>,ICourse))
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.txt
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/tests.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/rewriter/tests.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/rewriter/tests.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,15 @@
+import unittest
+import doctest
+from zope.testing.doctestunit import DocTestSuite,DocFileSuite
+
+def test_suite():
+    flags =  doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
+    return unittest.TestSuite((
+        DocFileSuite('rewriter.txt',
+            optionflags=flags),
+        DocTestSuite('ocql.rewriter.algebra')
+        ))
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/tests.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: Sandbox/adamg/ocql/trunk/src/ocql/testing/database.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/testing/database.py	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/testing/database.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,136 @@
+from zope.component import adapts
+from zope.component import provideAdapter
+from zope.interface import implements
+
+from zope.interface import Interface, implements
+from zope.schema import TextLine, Set, Choice, Int, List
+
+from ocql.interfaces import IDB
+from ocql.database import metadata
+
+# schema
+class ICourse(Interface):
+    code = TextLine(
+        title=u"Course code",
+        required=True
+        )
+    runBy = List(
+        title=u"Run by",
+        value_type = Choice(
+            title=u"Department",
+            vocabulary="vocab_of_IDepartment",
+            )
+        )
+    credits = Int(
+        title=u"Credits",
+        )
+
+class IDepartments(Interface):
+    name = TextLine(
+        title=u"name",
+        required=True
+        )
+    address = Choice(
+        title=u"Street address",
+        vocabulary="vocab_of_IAddress",
+        required=True
+        )
+
+class MClass(metadata.MetaType):
+    #interface suspect thing
+    def __init__(self, klass):
+        self.klass = klass
+
+    def is_collection(self):
+        return True
+
+    def get_collection_type(self):
+        return set
+
+    def get_contained(self):
+        return self.klass
+
+    def __getitem__(self, name):
+        x = self.klass[name]._type
+        try:
+            return x[-1]
+        except TypeError:
+            return x
+
+class MType(metadata.MetaType):
+    def __init__(self, klass, collection_type=None):
+        self.klass = klass
+        self.collection_type = collection_type
+
+    def is_collection(self):
+        return (self.collection_type is not None)
+
+    def get_collection_type(self):
+        return self.collection_type
+
+    def get_contained(self):
+        return self.klass
+
+class Department(object):
+    implements(IDepartments)
+
+    def __init__(self, name):
+        self.name = name
+
+    def __repr__(self):
+        return "%s <%s>" % (
+            self.__class__.__name__,
+            self.name
+        )
+
+class Course(object):
+    implements(ICourse)
+
+    def __init__(self, code, runBy, credits):
+        self.code = code
+        self.runBy = runBy
+        self.credits = credits
+
+    def __repr__(self):
+        return "%s <%s>" % (
+            self.__class__.__name__,
+            self.code
+        )
+
+D1 = Department("Computing Science")
+D2 = Department("Other department")
+D3 = Department("Department without curse")
+
+C1 = Course("C1", runBy = set([D1, D2]), credits=2)
+C2 = Course("C2", runBy = set(), credits=3)
+C3 = Course("C3", runBy = set([D1]), credits=3)
+
+
+# metadata
+class TestMetadata(metadata.Metadata):
+    implements(IDB)
+    adapts(None)
+
+    db = {
+            'IDepartments': [D1, D2],
+            'ICourse': [C1, C2, C3]
+        }
+    classes = {
+            'IDepartments': MClass(IDepartments),
+            'ICourse': MClass(ICourse),
+            }
+
+    def __init__(self, context=None):
+        pass
+
+    def getAll(self, klass):
+        x=self.db[klass]
+        return x
+
+    def get_class(self, name):
+        return self.classes[name]
+
+    def get_collection_type(self, name):
+        klass = self.get_class(name)
+        rv = klass.get_collection_type()
+        return rv
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/testing/database.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Modified: Sandbox/adamg/ocql/trunk/src/ocql/testing/stubs.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/testing/stubs.py	2008-06-15 12:38:04 UTC (rev 87409)
+++ Sandbox/adamg/ocql/trunk/src/ocql/testing/stubs.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -45,7 +45,7 @@
         self.context = context
         #self.db = db
 
-    def __call__(self):
+    def __call__(self, metadata):
         strg = self.context
         return ObjectQueryTree()
 
@@ -88,7 +88,7 @@
         self.context = context
         #self.db = db
 
-    def __call__(self):
+    def __call__(self, metadata, algebra):
         return RunnableQuery()
 
 class DB(object):

Added: Sandbox/adamg/ocql/trunk/src/ocql/tests/run.txt
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/tests/run.txt	                        (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/tests/run.txt	2008-06-15 14:35:58 UTC (rev 87410)
@@ -0,0 +1,79 @@
+
+Now we'll see how a query runs
+
+    >>> from zope.component import provideAdapter
+
+    >>> from ocql.parser.queryparser import QueryParser
+    >>> from ocql.qoptimizer.qoptimizer import QueryOptimizer
+    >>> from ocql.rewriter.rewriter import Rewriter
+    >>> from ocql.aoptimizer.aoptimizer import AlgebraOptimizer
+    >>> from ocql.compiler.compiler import AlgebraCompiler
+    >>> from ocql.testing.database import TestMetadata
+
+    >>> provideAdapter(QueryParser)
+    >>> provideAdapter(QueryOptimizer)
+    >>> provideAdapter(Rewriter)
+    >>> provideAdapter(AlgebraOptimizer)
+    >>> provideAdapter(AlgebraCompiler)
+    >>> provideAdapter(TestMetadata)
+
+    >>> from ocql.engine import OCQLEngine
+
+
+    >>> engine = OCQLEngine()
+    >>> run = engine.compile("set [ | 1 ]")
+    >>> run
+    RunnableQuery: set([1])
+
+    >>> result = run.execute()
+    >>> result
+    set([1])
+
+    >>> type(result)
+    <type 'set'>
+
+
+
+    >>> engine = OCQLEngine()
+    >>> run = engine.compile("set [ | 1 ] union set [|2]")
+    >>> run
+    RunnableQuery: set.union(set([1]),set([2]))
+
+    >>> result = run.execute()
+    >>> result
+    set([1, 2])
+
+    >>> type(result)
+    <type 'set'>
+
+
+
+    >>> engine = OCQLEngine()
+    >>> run = engine.compile("set [ i in ICourse | i ]")
+    >>> run
+    RunnableQuery: reduce(set.union, map(lambda i: set([i]),set(metadata.getAll("ICourse"))) , set())
+
+    >>> result = run.execute()
+    >>> result
+    set([Course <C1>, Course <C2>, Course <C3>])
+
+    >>> type(result)
+    <type 'set'>
+
+
+
+    >>> engine = OCQLEngine()
+    >>> run = engine.compile("set [ c in ICourse | c.code ]")
+    >>> run
+    RunnableQuery: reduce(set.union, map(lambda c: set([c.code]),set(metadata.getAll("ICourse"))) , set())
+
+    >>> result = run.execute()
+    >>> result
+    set(['C3', 'C2', 'C1'])
+
+    >>> type(result)
+    <type 'set'>
+
+    >>> run = run.reanalyze()
+    >>> run.execute()
+    set(['C3', 'C2', 'C1'])
\ No newline at end of file


Property changes on: Sandbox/adamg/ocql/trunk/src/ocql/tests/run.txt
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Modified: Sandbox/adamg/ocql/trunk/src/ocql/tests/test_skeleton.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/tests/test_skeleton.py	2008-06-15 12:38:04 UTC (rev 87409)
+++ Sandbox/adamg/ocql/trunk/src/ocql/tests/test_skeleton.py	2008-06-15 14:35:58 UTC (rev 87410)
@@ -6,6 +6,8 @@
 """
 
 import unittest
+import doctest
+from zope.testing.doctestunit import DocTestSuite,DocFileSuite
 
 from ocql.engine import OCQLEngine
 from ocql.testing.stubs import *
@@ -15,14 +17,16 @@
         registerStubs()
 
         e = OCQLEngine()
-        rq = e.compile("[ c in ICurses | c ]")
+        rq = e.compile("[ c in ICourse | c ]")
 
         self.assert_(isinstance(rq, RunnableQuery))
 
 def test_suite():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(testSkeleton))
-    return suite
+    flags =  doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
+    return unittest.TestSuite((
+        unittest.makeSuite(testSkeleton),
+        DocFileSuite('run.txt', optionflags=flags),
+        ))
 
 if __name__ == '__main__':
     unittest.main(defaultTest='test_suite')
\ No newline at end of file



More information about the Checkins mailing list