commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

r5785 - in trunk: gnue-appserver/samples gnue-appserver/src gnue-appserv


From: johannes
Subject: r5785 - in trunk: gnue-appserver/samples gnue-appserver/src gnue-appserver/src/classrep gnue-appserver/src/language gnue-common/src/datasources gnue-common/src/datasources/drivers/appserver/appserver gnue-common/src/schema/importer
Date: Fri, 7 May 2004 04:11:23 -0500 (CDT)

Author: johannes
Date: 2004-05-07 04:11:21 -0500 (Fri, 07 May 2004)
New Revision: 5785

Modified:
   trunk/gnue-appserver/samples/sample.gfd
   trunk/gnue-appserver/src/classrep/Base.py
   trunk/gnue-appserver/src/classrep/Class.py
   trunk/gnue-appserver/src/classrep/Module.py
   trunk/gnue-appserver/src/classrep/Parameter.py
   trunk/gnue-appserver/src/classrep/Procedure.py
   trunk/gnue-appserver/src/classrep/Property.py
   trunk/gnue-appserver/src/classrep/SchemaSupport.py
   trunk/gnue-appserver/src/classrep/__init__.py
   trunk/gnue-appserver/src/data.py
   trunk/gnue-appserver/src/geasAuthentication.py
   trunk/gnue-appserver/src/geasGsdGen.py
   trunk/gnue-appserver/src/geasInstance.py
   trunk/gnue-appserver/src/geasList.py
   trunk/gnue-appserver/src/geasSession.py
   trunk/gnue-appserver/src/geasSessionManager.py
   trunk/gnue-appserver/src/language/ObjectList.py
   trunk/gnue-common/src/datasources/GConditions.py
   trunk/gnue-common/src/datasources/drivers/appserver/appserver/DataObject.py
   trunk/gnue-common/src/schema/importer/Importer.py
Log:
GConditions are implemented a bit cleaner now :) Added prefix notation support,
and evaluation/validation of condition trees. Appserver now specifies
conditions in the prefix notation.


Modified: trunk/gnue-appserver/samples/sample.gfd
===================================================================
--- trunk/gnue-appserver/samples/sample.gfd     2004-05-07 05:02:37 UTC (rev 
5784)
+++ trunk/gnue-appserver/samples/sample.gfd     2004-05-07 09:11:21 UTC (rev 
5785)
@@ -1,22 +1,32 @@
 <?xml version="1.0" encoding="iso8859-1"?>
 
 <form title="GNUe Application Server test">
-  <parameter name="von" default="2270-07-15 09:00"/>
-  <parameter name="bis" default="2270-09-15 20:00"/>
+  <parameter name="von" default="2270-05-20 09:00"/>
+  <parameter name="bis" default="2270-06-25 20:00"/>
   <datasource name="dtsPerson" connection="appserver" table="address_person">
-    <!--
     <condition>
       <and>
-        <between>
-          <cfield name="address_nextmeeting"/>
-          <cparam name="von"/>
-          <cparam name="bis"/>
-        </between>
         <or>
-          <like>
-            <cfield name="address_street"/>
-            <cconst value="%street"/>
-          </like>
+          <between>
+            <cfield name="address_nextmeeting"/>
+            <cparam name="von"/>
+            <cparam name="bis"/>
+          </between>
+          <null>
+            <cfield name="address_zip"/>
+          </null>
+        </or>
+
+        <ne>
+          <cfield name="address_name"/>
+          <cconst value="foo"/>
+        </ne>
+
+        <or>
+          <gt>
+            <cfield name="address_weight"/>
+            <cconst value="70"/>
+          </gt>
           <or>
             <eq>
               <cfield name="address_zip"/>
@@ -28,13 +38,8 @@
             </eq>
           </or>
         </or>
-        <ne>
-          <cfield name="address_name"/>
-          <cconst value="foo"/>
-        </ne>
       </and>
     </condition>
-      -->
   </datasource>
   <datasource name="dtsCountry" connection="appserver" table="address_country"
     cache="250"/>

Modified: trunk/gnue-appserver/src/classrep/Base.py
===================================================================
--- trunk/gnue-appserver/src/classrep/Base.py   2004-05-07 05:02:37 UTC (rev 
5784)
+++ trunk/gnue-appserver/src/classrep/Base.py   2004-05-07 09:11:21 UTC (rev 
5785)
@@ -303,7 +303,7 @@
     self.classname    = classname
     self._session     = session
 
-    self.__object     = aObject 
+    self.__object     = aObject
     self.__predefined = {}
 
     if pDefs is not None:

Modified: trunk/gnue-appserver/src/classrep/Class.py
===================================================================
--- trunk/gnue-appserver/src/classrep/Class.py  2004-05-07 05:02:37 UTC (rev 
5784)
+++ trunk/gnue-appserver/src/classrep/Class.py  2004-05-07 09:11:21 UTC (rev 
5785)
@@ -127,8 +127,8 @@
     all classes of the bound module, otherwise no condition is given.
     """
     if self.__module is not None:
-      return [["eq", ""], ["field", u"gnue_module"], 
-             ["const", self.__module.gnue_id]]
+      return ['eq', ['field', u'gnue_module'],
+                    ['const', self.__module.gnue_id]]
     else:
       return []
 
@@ -144,8 +144,8 @@
     (moduleName, className) = splitName (key)
     module = self.modules [moduleName]
 
-    return [["eq", ""], ["field", u"gnue_module"], ["const", module.gnue_id],
-            ["eq", ""], ["field", u"gnue_name"], ["const", className]]
+    return ['and', ['eq', ['field', u'gnue_module'], ['const', 
module.gnue_id]],
+                   ['eq', ['field', u'gnue_name'], ['const', classname]]]
 
 
   # ---------------------------------------------------------------------------
@@ -180,7 +180,7 @@
   # Wrapping a business object class
   # ---------------------------------------------------------------------------
 
-  def __init__ (self, session, classDict, module, object, predefs = None, 
+  def __init__ (self, session, classDict, module, object, predefs = None,
                 propDefList = None):
     BaseObject.__init__ (self, session, 'gnue_class', object, predefs)
 
@@ -213,8 +213,8 @@
     Find a procedure @name.
     """
     return self.procedures [name]
-           
 
+
   # ---------------------------------------------------------------------------
   # Validate a class definition
   # ---------------------------------------------------------------------------
@@ -226,7 +226,7 @@
 
       except ValidationError:
         del self.properties [p.fullName]
-        gDebug (2, "%s.%s: %s: %s" % (self.fullName, p.fullName, 
+        gDebug (2, "%s.%s: %s: %s" % (self.fullName, p.fullName,
                                sys.exc_info () [0], sys.exc_info () [1]))
 
     for p in self.procedures.values ():

Modified: trunk/gnue-appserver/src/classrep/Module.py
===================================================================
--- trunk/gnue-appserver/src/classrep/Module.py 2004-05-07 05:02:37 UTC (rev 
5784)
+++ trunk/gnue-appserver/src/classrep/Module.py 2004-05-07 09:11:21 UTC (rev 
5785)
@@ -82,7 +82,7 @@
     """
     Match a single module by it's name.
     """
-    return [["eq", ""], ["field", "gnue_name"], ["const", key]]
+    return ['eq', ['field', u'gnue_name'], ['const', key]]
 
 
   # ---------------------------------------------------------------------------

Modified: trunk/gnue-appserver/src/classrep/Parameter.py
===================================================================
--- trunk/gnue-appserver/src/classrep/Parameter.py      2004-05-07 05:02:37 UTC 
(rev 5784)
+++ trunk/gnue-appserver/src/classrep/Parameter.py      2004-05-07 09:11:21 UTC 
(rev 5785)
@@ -56,7 +56,7 @@
   # ---------------------------------------------------------------------------
 
   def _getNewItem (self, aObject):
-    return Parameter (self._session, aObject, 
+    return Parameter (self._session, aObject,
                       {"gnue_id": aObject.objectId})
 
 
@@ -65,8 +65,7 @@
   # ---------------------------------------------------------------------------
 
   def _getReloadCondition (self):
-    return [["eq", ""], ["field", "gnue_procedure"], 
-            ["const", self.__proc.gnue_id]]
+    return ['eq', ['field', u'gnue_procedure'], ['const', self.__proc.gnue_id]]
 
 
   # ---------------------------------------------------------------------------
@@ -74,9 +73,8 @@
   # ---------------------------------------------------------------------------
 
   def _getSingleCondition (self, key):
-    res = self._getReloadCondition ()
-    res.extend ([["eq", ""], ["field", "gnue_name"], ["const", key]])
-    return res
+    return ['and', self._getReloadCondition (),
+                   ['eq', ['field', u'gnue_name'], ['const', key]]]
 
 
   # ---------------------------------------------------------------------------

Modified: trunk/gnue-appserver/src/classrep/Procedure.py
===================================================================
--- trunk/gnue-appserver/src/classrep/Procedure.py      2004-05-07 05:02:37 UTC 
(rev 5784)
+++ trunk/gnue-appserver/src/classrep/Procedure.py      2004-05-07 09:11:21 UTC 
(rev 5785)
@@ -71,7 +71,7 @@
   # ---------------------------------------------------------------------------
   def _getNewItem (self, aObject):
     pMod = self.__module.modules.find (aObject.gnue_module.objectId)
-    aProc = Procedure (self._session, pMod, aObject, 
+    aProc = Procedure (self._session, pMod, aObject,
                       {"gnue_id": aObject.objectId})
     aProc.parameters.reload ()
     return aProc
@@ -81,8 +81,7 @@
   # A reload () returns only the procedures of the class
   # ---------------------------------------------------------------------------
   def _getReloadCondition (self):
-    return [["eq", ""], ["field", "gnue_class"], 
-            ["const", self.__class.gnue_id]]
+    return ['eq', ['field', u'gnue_class'], ['const', self.__class.gnue_id]]
 
 
   # ---------------------------------------------------------------------------
@@ -91,9 +90,8 @@
   def _getSingleCondition (self, key):
     procName = splitName (key) [1]
 
-    return [["eq", ""], ["field", "gnue_class"], 
-            ["const", self.__class.gnue_id],
-            ["eq", ""], ["field", "gnue_name"], ["const", procName]]
+    return ['and', self._getReloadCondition (),
+                   ['eq', ['field', u'gnue_name'], ['const', procName]]]
 
 
   # ---------------------------------------------------------------------------
@@ -148,7 +146,7 @@
                         len (self.parameters.keys ()) == 0 and \
                         self.gnue_name [:3].lower () == 'get'
     if self.isCalculated:
-      self.calcFullName = createName (self.module.gnue_name, 
+      self.calcFullName = createName (self.module.gnue_name,
                                       self.gnue_name [3:])
     else:
       self.calcFullName = None

Modified: trunk/gnue-appserver/src/classrep/Property.py
===================================================================
--- trunk/gnue-appserver/src/classrep/Property.py       2004-05-07 05:02:37 UTC 
(rev 5784)
+++ trunk/gnue-appserver/src/classrep/Property.py       2004-05-07 09:11:21 UTC 
(rev 5785)
@@ -72,7 +72,7 @@
   # ---------------------------------------------------------------------------
   def _getNewItem (self, aObject):
     pMod = self.__module.modules.find (aObject.gnue_module.objectId)
-    return Property (self._session, pMod, aObject, 
+    return Property (self._session, pMod, aObject,
                      {"gnue_id": aObject.objectId})
 
 
@@ -80,8 +80,7 @@
   # Restrict a reload () to the classes properties 
   # ---------------------------------------------------------------------------
   def _getReloadCondition (self):
-    return [["eq", ""], ["field", u"gnue_class"], 
-            ["const", self.__class.gnue_id]]
+    return ['eq', ['field', u'gnue_class'], ['const', self.__class.gnue_id]]
 
 
   # ---------------------------------------------------------------------------
@@ -89,9 +88,8 @@
   # ---------------------------------------------------------------------------
   def _getSingleCondition (self, key):
     propName = splitName (key) [1]
-    return [["eq", ""], ["field", u"gnue_class"], 
-            ["const", self.__class.gnue_id],
-            ["eq", ""], ["field", u"gnue_name"], ["const", propName]]
+    return ['and', self._getReloadCondition (),
+                  ['eq', ['field', u'gnue_name'], ['const', propName]]]
 
 
   # ---------------------------------------------------------------------------
@@ -223,7 +221,7 @@
     referenced class definition.
     """
 
-    res = helpers.verifyType (self.gnue_type, self.gnue_length, 
+    res = helpers.verifyType (self.gnue_type, self.gnue_length,
                               self.gnue_scale, self.module.classes)
     self.isReference     = res is not None
     self.referencedClass = res

Modified: trunk/gnue-appserver/src/classrep/SchemaSupport.py
===================================================================
--- trunk/gnue-appserver/src/classrep/SchemaSupport.py  2004-05-07 05:02:37 UTC 
(rev 5784)
+++ trunk/gnue-appserver/src/classrep/SchemaSupport.py  2004-05-07 09:11:21 UTC 
(rev 5785)
@@ -161,7 +161,7 @@
         xModules = [p.module.fullName for p in aClass.properties.values () + \
                                                aClass.procedures.values ()]
         for module in xModules:
-          if module == 'gnue': 
+          if module == 'gnue':
             continue
           if self.__exportModules.has_key (module):
             self.__export (aClass, False, self.__exportModules.keys ())

Modified: trunk/gnue-appserver/src/classrep/__init__.py
===================================================================
--- trunk/gnue-appserver/src/classrep/__init__.py       2004-05-07 05:02:37 UTC 
(rev 5784)
+++ trunk/gnue-appserver/src/classrep/__init__.py       2004-05-07 09:11:21 UTC 
(rev 5785)
@@ -40,7 +40,7 @@
   try:
     basedir  = os.path.dirname 
(sys.modules["gnue.appserver.classrep"].__file__)
   except:
-    basedir  = os.path.dirname (__file__)    
+    basedir  = os.path.dirname (__file__)
     
   if not os.path.isfile (os.path.join (basedir, "repository.ini")):
     basedir = os.path.join (paths.data, "share", "gnue", "appserver")

Modified: trunk/gnue-appserver/src/data.py
===================================================================
--- trunk/gnue-appserver/src/data.py    2004-05-07 05:02:37 UTC (rev 5784)
+++ trunk/gnue-appserver/src/data.py    2004-05-07 09:11:21 UTC (rev 5785)
@@ -247,10 +247,9 @@
       tables.append (table)
       fields.extend (fieldlist)
     if fk_alias:
-      c = GConditions.buildTreeFromPrefix (
-            [['eq', ''],
-             ['field', alias + u'.gnue_id'],
-             ['field', fk_alias + u'.' + fk_field]])
+      c = GConditions.buildTreeFromList (
+          ['eq', ['field', alias + u'.gnue_id'],
+                 ['field', fk_alias + u'.' + fk_field]])
       if conditions:
         conditions = GConditions.combineConditions (conditions, c)
       else:
@@ -826,8 +825,8 @@
   print 'connection.query for previously inserted record ...',
   content = {None: (u'address_person', None, None, [u'address_name'])}
   rs = c.query (content,
-                [['eq', ''], ['field', u'address_name'],
-                             ['const', u'New Person']], None)
+                ['eq', ['field', u'address_name'],
+                       ['const', u'New Person']], None)
   print 'Ok'
 
   print 'recordset.firstRecord ...',
@@ -879,8 +878,8 @@
   print 'check if the record is really gone now ...',
   content = {None: (u'address_person', None, None, [u'address_name'])}
   rs = c.query (content,
-                [['eq', ''], ['field', u'address_city'],
-                             ['const', u'New City']],
+                ['eq', ['field', u'address_city'],
+                       ['const', u'New City']],
                 None)
   if rs.firstRecord () != None:
     raise Exception

Modified: trunk/gnue-appserver/src/geasAuthentication.py
===================================================================
--- trunk/gnue-appserver/src/geasAuthentication.py      2004-05-07 05:02:37 UTC 
(rev 5784)
+++ trunk/gnue-appserver/src/geasAuthentication.py      2004-05-07 09:11:21 UTC 
(rev 5785)
@@ -90,9 +90,7 @@
 
   def authenticate (self, session, user, auth):
     authList = self._intSess.request ("gnue_useraccess",
-                                     [['eq', ''],
-                                      ['field', 'gnue_username'],
-                                      ['const', user ]],
+                   ['eq', ['field', 'gnue_username'], ['const', user]],
                                      [],
                                      ["gnue_username", "gnue_password",
                                       "gnue_accesslist"])

Modified: trunk/gnue-appserver/src/geasGsdGen.py
===================================================================
--- trunk/gnue-appserver/src/geasGsdGen.py      2004-05-07 05:02:37 UTC (rev 
5784)
+++ trunk/gnue-appserver/src/geasGsdGen.py      2004-05-07 09:11:21 UTC (rev 
5785)
@@ -27,7 +27,7 @@
 from gnue.common.apps.GClientApp import *
 
 from gnue.appserver import VERSION
-from gnue.appserver.geasSessionManager import geasSessionManager 
+from gnue.appserver.geasSessionManager import geasSessionManager
 from gnue.appserver.classrep.SchemaSupport import *
 from gnue.appserver.classrep.Namespace import *
 

Modified: trunk/gnue-appserver/src/geasInstance.py
===================================================================
--- trunk/gnue-appserver/src/geasInstance.py    2004-05-07 05:02:37 UTC (rev 
5784)
+++ trunk/gnue-appserver/src/geasInstance.py    2004-05-07 09:11:21 UTC (rev 
5785)
@@ -255,7 +255,7 @@
     sess = Session.Session (self.__session.sm, self.__session.id)
 
     # Create an object representing the current business object
-    obj = Object.Object (sess, self.__classdef.fullName, 
+    obj = Object.Object (sess, self.__classdef.fullName,
                          self.__getValue (u'gnue_id'))
 
     # check the parameters

Modified: trunk/gnue-appserver/src/geasList.py
===================================================================
--- trunk/gnue-appserver/src/geasList.py        2004-05-07 05:02:37 UTC (rev 
5784)
+++ trunk/gnue-appserver/src/geasList.py        2004-05-07 09:11:21 UTC (rev 
5785)
@@ -85,7 +85,7 @@
       instance = geasInstance.geasInstance (self.__session, self.__connection,
                                             record, self.__classdef)
       if self.__condition is not None:
-        if not self.__condition.eval (instance):
+        if not self.__condition.evaluate (instance):
           return self.__getInstance ()
 
       self.__instances.append (instance)
@@ -103,8 +103,11 @@
     """
     This function returns the number of instances available in this list.
     """
-    self.__fillup (0)
-    return len (self.__instances)
+    if self.__condition is not None:
+      self.__fillup (0)
+      return len (self.__instances)
+    else:
+      return self.__recordset.count ()
 
 
   # ---------------------------------------------------------------------------

Modified: trunk/gnue-appserver/src/geasSession.py
===================================================================
--- trunk/gnue-appserver/src/geasSession.py     2004-05-07 05:02:37 UTC (rev 
5784)
+++ trunk/gnue-appserver/src/geasSession.py     2004-05-07 09:11:21 UTC (rev 
5785)
@@ -216,7 +216,8 @@
     if asCond is not None:
       self.__addConditionToContent (classdef, content, asCond)
 
-    self.__convertCondition (classdef, dsCond, content)
+    if dsCond is not None:
+      self.__convertCondition (classdef, dsCond, content)
 
     sortlist = []
     for p in sortorder:
@@ -375,8 +376,11 @@
     by the datasource, and another one which has to be processed by appserver.
     """
 
+    if condition is None:
+      return (None, None)
+
     if isinstance (condition, ListType):
-      cTree = GConditions.buildTreeFromPrefix (condition)
+      cTree = GConditions.buildTreeFromList (condition)
     else:
       cTree = condition
 
@@ -386,7 +390,8 @@
 
     if len (cTree._children):
       # NOTE: the first element of a condition tree is a GCondition object
-      self.__splitIntoAnd (cTree._children [0], forest)
+      # self.__splitIntoAnd (cTree._children [0], forest)
+      self.__splitIntoAnd (cTree, forest)
 
     for tree in forest:
       if self.__dbHandlesTree (tree, classdef):
@@ -402,19 +407,28 @@
     # will do that later
     if len (dbTrees):
       dbCond = GConditions.GCondition ()
-      comb = GConditions.GCand (dbCond)
 
-      for tree in dbTrees:
-        comb._children.append (tree)
-        tree.parent = comb
+      if len (dbTrees) == 1:
+        dbCond._children.append (dbTrees [0])
+        dbTrees [0]._parent = dbCond
+      else:
+        comb = GConditions.GCand (dbCond)
+        for tree in dbTrees:
+          comb = GConditions.combineConditions (comb, tree)
 
+
     if len (asTrees):
       asCond = GConditions.GCondition ()
-      comb = GConditions.GCand (asCond)
-      for tree in asTrees:
-        comb._children.append (tree)
-        tree.parent = comb
 
+      if len (asTrees) == 1:
+        asCond._children.append (asTrees [0])
+        asTrees [0]._parent = asCond
+
+      else:
+        comb = GConditions.GCand (asCond)
+        for tree in asTrees:
+          comb = GConditions.combineConditions (comb, tree)
+
     return (dbCond, asCond)
 
 
@@ -427,11 +441,15 @@
     This function splits a condition tree into several independant subtrees
     which can be re-combined via AND.
     """
-    if isinstance (tree, GConditions.GCand):
+    if isinstance (tree, GConditions.GConditionElement):
+      if isinstance (tree, GConditions.GCand):
+        for child in tree._children:
+          self.__splitIntoAnd (child, forest)
+      else:
+        forest.append (tree)
+    else:
       for child in tree._children:
         self.__splitIntoAnd (child, forest)
-    else:
-      forest.append (tree)
 
 
   # ---------------------------------------------------------------------------

Modified: trunk/gnue-appserver/src/geasSessionManager.py
===================================================================
--- trunk/gnue-appserver/src/geasSessionManager.py      2004-05-07 05:02:37 UTC 
(rev 5784)
+++ trunk/gnue-appserver/src/geasSessionManager.py      2004-05-07 09:11:21 UTC 
(rev 5785)
@@ -48,7 +48,7 @@
 
     # TODO: load default authagent depending on config setting
     self._authAdapter = geasAuthentication.geasDBAuthAgent 
(self._internalSession)
-    self._langRuntimes = {} 
+    self._langRuntimes = {}
 
   # ---------------------------------------------------------------------------
   # Build an internal session

Modified: trunk/gnue-appserver/src/language/ObjectList.py
===================================================================
--- trunk/gnue-appserver/src/language/ObjectList.py     2004-05-07 05:02:37 UTC 
(rev 5784)
+++ trunk/gnue-appserver/src/language/ObjectList.py     2004-05-07 09:11:21 UTC 
(rev 5785)
@@ -80,7 +80,7 @@
     sm  = self.__session.getSessionManager ()
     sid = self.__session.getSessionId ()
 
-    self.__list_id = sm.request (sid, self.classname, self.conditions, 
+    self.__list_id = sm.request (sid, self.classname, self.conditions,
                                       self.sortOrder, self.properties)
     self.__list = []
     self.__populateList ()

Modified: trunk/gnue-common/src/datasources/GConditions.py
===================================================================
--- trunk/gnue-common/src/datasources/GConditions.py    2004-05-07 05:02:37 UTC 
(rev 5784)
+++ trunk/gnue-common/src/datasources/GConditions.py    2004-05-07 09:11:21 UTC 
(rev 5785)
@@ -23,13 +23,16 @@
 #
 # DESCRIPTION:
 #
-# $Id: $
+# $Id$
 #
 
 from gnue.common.definitions.GObjects import GObj
 from gnue.common.formatting import GTypecast
 import mx.DateTime
-import types, string
+import types
+import string
+import sys
+import re
 
 class ConditionError (gException):
   pass
@@ -77,49 +80,140 @@
     UnificationError.__init__ (self, msg)
 
 
-class GCondition(GObj):
-  def __init__(self, parent=None, type="GCCondition"):
-    GObj.__init__(self, parent, type=type)
 
+# =============================================================================
+# Base condition class; this is class is acts as root node of condition trees
+# =============================================================================
+
+class GCondition (GObj):
+  """
+  A GCondition instance is allways the root node of a condition tree. All
+  children of a GCondition node are evaluated and combined using an AND
+  condition if not otherwise stated.
+  """
+  def __init__(self, parent = None, type = "GCCondition"):
+    GObj.__init__ (self, parent, type = type)
+    self._maxChildren = None
+
+
   # ---------------------------------------------------------------------------
+  # Make sure an element of the tree has the requested number of children
+  # ---------------------------------------------------------------------------
+
+  def _needChildren (self, number):
+    """
+    This function verifies if a condition element has a given number of
+    children. If not an ArgumentCountError will be raised.
+    """
+    if number is not None and len (self._children) != number:
+      raise ArgumentCountError, (self, number)
+
+
+  # ---------------------------------------------------------------------------
   # Evaluate a condition tree using the given lookup dictionary
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
+  def evaluate (self, lookup):
     """
     This function evaluates the condition tree using the dictionary @lookup for
-    retrieving field values.
+    retrieving field values. All children must evaluate to TRUE; evaluation
+    stops on the first false result.
     """
-    self._needChildren (1)
-    return self._children [0].eval (lookup)
+    self.validate ()
 
+    for child in self._children:
+      if not child.evaluate (lookup):
+        return False
 
+    return True
+
+
   # ---------------------------------------------------------------------------
-  # Make sure an element of the tree has the requested number of children
+  # Validate an element of a condition tree
   # ---------------------------------------------------------------------------
 
-  def _needChildren (self, number):
+  def validate (self):
     """
-    This function verifies if a condition element has a given number of
-    children. If not an ArgumentCountError will be raised.
+    This function calls validate () on all it's children. Descendants might
+    override this function to do integrity checks and things like that.
     """
-    if len (self._children) != number:
-      raise ArgumentCountError, (self, number)
+    self._needChildren (self._maxChildren)
 
+    for child in self._children:
+      child.validate ()
 
 
+  # ---------------------------------------------------------------------------
+  # Convert an element into prefix notation
+  # ---------------------------------------------------------------------------
+
+  def prefixNotation (self):
+    """
+    This function returns the prefix notation of an element and all it's
+    children.
+    """
+    result = []
+    append = result.extend
+
+    if isinstance (self, GConditionElement):
+      result.append (self._type [2:])
+      append = result.append
+    
+    for child in self._children:
+      append (child.prefixNotation ())
+
+    return result
+
+
+  # ---------------------------------------------------------------------------
+  # Build an element and all it's children from a prefix notation list
+  # ---------------------------------------------------------------------------
+
+  def buildFromList (self, prefixList):
+    """
+    This function creates a (partial) condition tree from a prefix notation
+    list.
+    """
+    checktype (prefixList, types.ListType)
+
+    if len (prefixList):
+      item = prefixList [0]
+
+      # be nice if there's a condition part missing
+      if isinstance (item, types.ListType):
+        self.buildFromList (item)
+        element = self
+      else:
+        # automatically map 'field' to 'Field' and 'const' to 'Const'
+        if item in ['field', 'const']:
+          item = item.title ()
+
+        element = getattr (sys.modules [__name__], "GC%s" % item) (self)
+
+      for subitem in prefixList [1:]:
+        element.buildFromList (subitem)
+
+
+# =============================================================================
+# Top level classes 
+# =============================================================================
+
 class GConditions(GCondition):
   def __init__(self, parent=None, type="GCConditions"):
-    GCondition.__init__(self, parent, type=type)
+    GCondition.__init__(self, parent, type = type)
 
 class GConditionElement (GCondition) :
   def __init__(self, parent=None, type="GConditionElement"):
-    GCondition.__init__(self, parent, type=type)
+    GCondition.__init__ (self, parent, type = type)
 
 
+# -----------------------------------------------------------------------------
+# A Field element in the condition tree
+# -----------------------------------------------------------------------------
+
 class GCField (GConditionElement):
-  def __init__(self, parent, name=None, datatype="char"):
-    GConditionElement.__init__(self, parent, 'GCCField')
+  def __init__(self, parent, name = None, datatype = "char"):
+    GConditionElement.__init__ (self, parent, 'GCCField')
     self.type = datatype
     self.name = name
 
@@ -127,7 +221,7 @@
   # Evaluate a field element
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
+  def evaluate (self, lookup):
     """
     This function returns the fields value in the given lookup dictionary. If
     this dictionary has no key for the field a MissingFieldError will be
@@ -139,304 +233,552 @@
     return lookup [self.name]
 
 
+  # ---------------------------------------------------------------------------
+  # A field in prefix notation is a tuple of 'field' and fieldname
+  # ---------------------------------------------------------------------------
 
-class GCParam (GConditionElement):
-  def __init__(self, parent, name=None, datatype="char"):
-    GConditionElement.__init__(self, parent, 'GCCParam')
-    self.type = datatype
-    self.name = name
+  def prefixNotation (self):
+    """
+    The prefix notation of a field element is a tuple of the identifier 'field'
+    (acting as operator) and the field's name.
+    """
+    return ['Field', self.name]
 
-  def getValue(self):
-    return ""
 
-  def eval (self, lookup):
-    raise ConditionError, u_("Object can't evaluate!")
-    
+  # ---------------------------------------------------------------------------
+  # to complete a field element from a prefix notation set the fieldname
+  # ---------------------------------------------------------------------------
 
+  def buildFromList (self, prefixList):
+    """
+    The single argument to a field 'operator' could be it's name, so this
+    method set's the fieldname.
+    """
+    checktype (prefixList, (types.StringType, types.UnicodeType))
+    self.name = prefixList
+
+
+# -----------------------------------------------------------------------------
+# A constant definition in a condition tree
+# -----------------------------------------------------------------------------
+
 class GCConst (GConditionElement):
-  def __init__(self, parent, value=None, datatype="char"):
-    GConditionElement.__init__(self, parent, 'GCCConst')
-    self.type = datatype
+  def __init__ (self, parent, value = None, datatype = "char"):
+    GConditionElement.__init__ (self, parent, 'GCCConst')
+    self.type  = datatype
     self.value = value
 
+
   # ---------------------------------------------------------------------------
   # Evaluate a constant
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
+  def evaluate (self, lookup):
     """
     This function returns the constants value
     """
     return self.value
 
 
-class GCadd(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCadd')
+  # ---------------------------------------------------------------------------
+  # The prefix notation of a constant is a tuple of identifier and value
+  # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
+  def prefixNotation (self):
     """
-    This function creates the sum of all it's children. A unify is used to
-    ensure all children evaluate to a numeric type.
+    The prefix notation of a constant is a tuple of the identifier 'Const' and
+    the constant's value.
     """
-    result = 0
-    for child in self._children:
-      values = []
-      unify ([child.eval (lookup), 0], values)
-      result += values [0]
-    return result
+    return ['Const', self.value]
 
 
-class GCsub(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCsub')
+  # ---------------------------------------------------------------------------
+  # Recreate a constant from a prefix notation
+  # ---------------------------------------------------------------------------
 
-class GCmul(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCmul')
+  def buildFromList (self, prefixList):
+    """
+    The single argument of a constant 'operator' could be it's value, so this
+    function set the constant's value.
+    """
+    self.value = prefixList
 
-class GCdiv(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCdiv')
 
+# -----------------------------------------------------------------------------
+# Base class for parameter elements in a condition tree
+# -----------------------------------------------------------------------------
 
+class GCParam (GConditionElement):
+  def __init__ (self, parent, name = None, datatype = "char"):
+    GConditionElement.__init__ (self, parent, 'GCCParam')
+    self.type = datatype
+    self.name = name
 
-class GCand(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCand')
+  # ---------------------------------------------------------------------------
+  # Return the value of a parameter
+  # ---------------------------------------------------------------------------
 
+  def getValue(self):
+    """
+    Descendants override this function to return the value of the parameter.
+    """
+    return ""
+
+
   # ---------------------------------------------------------------------------
-  # Evaluate an 'AND' condition
+  # Evaluate the parameter object
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
+  def evaluate (self, lookup):
     """
-    This function concatenates all children of this element by a logical AND.
-    The iteration stops on the first 'false' result.
+    A parameter element evaluates to it's value.
     """
-    for child in self._children:
-      if not child.eval (lookup):
-        return False
+    return self.getValue ()
 
-    return True
 
+  # ---------------------------------------------------------------------------
+  # Return a parameter object in prefix notation
+  # ---------------------------------------------------------------------------
 
-class GCor(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCor')
+  def prefixNotation (self):
+    """
+    The prefix notation of a parameter object is a 'constant' with the
+    parameters' value
+    """
+    return ['Const', self.getValue ()]
 
+
+# =============================================================================
+# Base classes for unary and binary operations
+# =============================================================================
+
+class GUnaryConditionElement (GConditionElement):
+  def __init__ (self, parent = None, elementType = ''):
+    self._maxChildren = 1
+    GConditionElement.__init__ (self, parent, elementType)
+
+class GBinaryConditionElement (GConditionElement):
+  def __init__ (self, parent = None, elementType = ''):
+    GConditionElement.__init__ (self, parent, elementType)
+    self._maxChildren = 2
+    self.values       = []
+
   # ---------------------------------------------------------------------------
+  # Evaluating a binary element means evaluation of both children
+  # ---------------------------------------------------------------------------
+
+  def evaluate (self, lookup):
+    """
+    This function evaluates both children of a binary element storing their
+    values in the property 'values'. Descendants can use these values for
+    further evaluations.
+    """
+    self._needChildren (self._maxChildren)
+    self.values = unify ([child.evaluate (lookup) for child in self._children])
+
+
+# =============================================================================
+# Logical operators
+# =============================================================================
+
+# -----------------------------------------------------------------------------
+# n-ary operation: AND
+# -----------------------------------------------------------------------------
+
+class GCand (GConditionElement):
+  def __init__ (self, parent = None):
+    GConditionElement.__init__ (self, parent, 'GCand')
+
+
+# -----------------------------------------------------------------------------
+# n-ary operation: OR
+# -----------------------------------------------------------------------------
+
+class GCor (GConditionElement):
+  def __init__ (self, parent = None):
+    GConditionElement.__init__ (self, parent, 'GCor')
+
+  # ---------------------------------------------------------------------------
   # Evaluate an OR tree
   # ---------------------------------------------------------------------------
-  def eval (self, lookup):
+
+  def evaluate (self, lookup):
     """
     This function concatenates all children of this element by a logical OR.
     The iteration stops on the first 'true' result.
     """
     for child in self._children:
-      if child.eval (lookup):
+      if child.evaluate (lookup):
         return True
 
     return False
-    
 
-class GCnot(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCnot')
+# -----------------------------------------------------------------------------
+# unary operation: NOT
+# -----------------------------------------------------------------------------
 
+class GCnot (GUnaryConditionElement):
+  def __init__ (self, parent = None):
+    GUnaryConditionElement.__init__ (self, parent, 'GCnot')
+
   # ---------------------------------------------------------------------------
-  # Evaluate the element
+  # logically Invert the childs result
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
+  def evaluate (self, lookup):
     """
     This function logically inverts the child's evaluation
     """
-    self._needChildren (1)
-    return not self._children [0].eval (lookup)
+    self._needChildren (self._maxChildren)
+    return not self._children [0].evaluate (lookup)
 
 
-class GCnegate(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCnegate')
 
-  def eval (self, lookup):
-    self._needChildren (1)
-    values = []
-    unify ([self._children [0].eval (lookup), 0], values)
-    return -values [0]
+# =============================================================================
+# Numeric operations
+# =============================================================================
 
+# ---------------------------------------------------------------------------
+# n-ary operation: Addition
+# ---------------------------------------------------------------------------
 
-class GCeq(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCeq')
+class GCadd (GConditionElement):
+  def __init__ (self, parent = None):
+    GConditionElement.__init__ (self, parent, 'GCadd')
 
   # ---------------------------------------------------------------------------
+  # Evaluate the addition element
+  # ---------------------------------------------------------------------------
+  def evaluate (self, lookup):
+    """
+    This function creates the sum of all it's children. A unify is used to
+    ensure all children evaluate to a numeric type.
+    """
+    result = 0
+    for child in self._children:
+      result += unify ([child.evaluation (lookup), 0]) [0]
+    return result
+
+
+# -----------------------------------------------------------------------------
+# n-ary operation: Subtraction
+# -----------------------------------------------------------------------------
+
+class GCsub (GConditionElement):
+  def __init__ (self, parent = None):
+    GConditionElement.__init__ (self, parent, 'GCsub')
+
+  # ---------------------------------------------------------------------------
+  # Evaluate the subtraction element
+  # ---------------------------------------------------------------------------
+
+  def evaluate (self, lookup):
+    result = None
+
+    for child in self._children:
+      value = unify ([child.evaluation (lookup), 0]) [0]
+      if result is None:
+        result = value
+      else:
+        result -= value
+
+    return result
+
+
+# -----------------------------------------------------------------------------
+# n-ary operation: Multiplication
+# -----------------------------------------------------------------------------
+
+class GCmul (GConditionElement):
+  def __init__ (self, parent = None):
+    GConditionElement.__init__ (self, parent, 'GCmul')
+
+  # ---------------------------------------------------------------------------
+  # Evaluate the multiplication
+  # ---------------------------------------------------------------------------
+
+  def evaluate (self, lookup):
+    result = None
+
+    for child in self._children:
+      value = unify ([child.evaluate (lookup), 0]) [0]
+      if result is None:
+        result = value
+      else:
+        result *= value
+
+    return result
+
+
+# -----------------------------------------------------------------------------
+# n-ary operation: Division
+# -----------------------------------------------------------------------------
+
+class GCdiv (GConditionElement):
+  def __init__ (self, parent = None):
+    GConditionElement.__init__ (self, parent, 'GCdiv')
+
+  # ---------------------------------------------------------------------------
+  # Evaluate the division element
+  # ---------------------------------------------------------------------------
+
+  def evaluate (self, lookup):
+    result = None
+
+    for child in self._children:
+      value = unify ([child.evaluate (lookup), 0]) [0]
+      if result is None:
+        result = value
+      else:
+        result /= value
+
+    return result
+
+# -----------------------------------------------------------------------------
+# unary operation: numeric negation
+# -----------------------------------------------------------------------------
+
+class GCnegate (GUnaryConditionElement):
+  def __init__ (self, parent = None):
+    GUnaryConditionElement.__init__ (self, parent, 'GCnegate')
+
+  # ---------------------------------------------------------------------------
+  # Evaluation of the numeric negation
+  # ---------------------------------------------------------------------------
+
+  def evaluate (self, lookup):
+    """
+    This function does a numeric negation on the child's evaluation result.
+    """
+    self._needChildren (self._maxChildren)
+    return -unify ([self._children [0].evaluate (lookup), 0]) [0]
+    
+
+# =============================================================================
+# Relational operations
+# =============================================================================
+
+# -----------------------------------------------------------------------------
+# Equality
+# -----------------------------------------------------------------------------
+
+class GCeq (GBinaryConditionElement):
+  def __init__ (self, parent = None):
+    GBinaryConditionElement.__init__ (self, parent, 'GCeq')
+
+  # ---------------------------------------------------------------------------
   # evaluate EQ relation
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
-    self._needChildren (2)
-    result = []
-    unify ([v.eval (lookup) for v in self._children], result)
-    return result [0] == result [1]
+  def evaluate (self, lookup):
+    GBinaryConditionElement.evaluate (self, lookup)
+    return self.values [0] == self.values [1]
 
 
-class GCne(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCne')
+# -----------------------------------------------------------------------------
+# Inequality
+# -----------------------------------------------------------------------------
 
+class GCne (GBinaryConditionElement):
+  def __init__ (self, parent = None):
+    GBinaryConditionElement.__init__ (self, parent, 'GCne')
+
   # ---------------------------------------------------------------------------
   # evaluate NE relation
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
-    self._needChildren (2)
-    result = []
-    unify ([v.eval (lookup) for v in self._children], result)
-    return result [0] != result [1]
+  def evaluate (self, lookup):
+    GBinaryConditionElement.evaluate (self, lookup)
+    return self.values [0] != self.values [1]
 
 
-class GCgt(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCgt')
+# -----------------------------------------------------------------------------
+# Greater Than
+# -----------------------------------------------------------------------------
 
+class GCgt (GBinaryConditionElement):
+  def __init__ (self, parent = None):
+    GBinaryConditionElement.__init__ (self, parent, 'GCgt')
+
   # ---------------------------------------------------------------------------
   # evaluate GT relation
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
-    self._needChildren (2)
-    result = []
-    unify ([v.eval (lookup) for v in self._children], result)
-    return result [0] > result [1]
+  def evaluate (self, lookup):
+    GBinaryConditionElement.evaluate (self, lookup)
+    return self.values [0] > self.values [1]
 
 
+# -----------------------------------------------------------------------------
+# Greater or Equal
+# -----------------------------------------------------------------------------
 
-class GCge(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCge')
+class GCge (GBinaryConditionElement):
+  def __init__ (self, parent = None):
+    GBinaryConditionElement.__init__ (self, parent, 'GCge')
 
   # ---------------------------------------------------------------------------
-  # evaluate NE relation
+  # evaluate GE relation
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
-    self._needChildren (2)
-    result = []
-    unify ([v.eval (lookup) for v in self._children], result)
-    return result [0] >= result [1]
+  def evaluate (self, lookup):
+    GBinaryConditionElement.evaluate (self, lookup)
+    return self.values [0] >= self.values [1]
 
 
 
-class GClt(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GClt')
+# -----------------------------------------------------------------------------
+# Less Than
+# -----------------------------------------------------------------------------
 
+class GClt (GBinaryConditionElement):
+  def __init__ (self, parent = None):
+    GBinaryConditionElement.__init__ (self, parent, 'GClt')
+
   # ---------------------------------------------------------------------------
   # evaluate LT relation
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
-    self._needChildren (2)
-    result = []
-    unify ([v.eval (lookup) for v in self._children], result)
-    return result [0] < result [1]
+  def evaluate (self, lookup):
+    GBinaryConditionElement.evaluate (self, lookup)
+    return self.values [0] < self.values [1]
 
 
+# -----------------------------------------------------------------------------
+# Less or Equal
+# -----------------------------------------------------------------------------
 
-class GCle(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCle')
+class GCle (GBinaryConditionElement):
+  def __init__ (self, parent = None):
+    GBinaryConditionElement.__init__ (self, parent, 'GCle')
 
   # ---------------------------------------------------------------------------
   # evaluate LE relation
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
-    self._needChildren (2)
-    result = []
-    unify ([v.eval (lookup) for v in self._children], result)
-    return result [0] <= result [1]
+  def evaluate (self, lookup):
+    GBinaryConditionElement.evaluate (self, lookup)
+    return self.values [0] <= self.values [1]
 
 
+# -----------------------------------------------------------------------------
+# Like
+# -----------------------------------------------------------------------------
 
-class GClike(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GClike')
+class GClike (GBinaryConditionElement):
+  def __init__ (self, parent = None):
+    GBinaryConditionElement.__init__ (self, parent, 'GClike')
 
-  def eval (self, lookup):
-    self._needChildren (2)
-    return True
+  # ---------------------------------------------------------------------------
+  # Evaluate a like condition
+  # ---------------------------------------------------------------------------
 
-class GCnotlike(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCnotlike')
+  def evaluate (self, lookup):
+    GBinaryConditionElement.evaluate (self, lookup)
+    strpat = "^%s" % self.values [1]
+    strpat = strpat.replace ('?', '.').replace ('%', '.*')
+    pattern = re.compile (strpat)
+    return pattern.match (self.values [0]) is not None
 
-  def eval (self, lookup):
-    self._needChildren (2)
-    return True
 
+# -----------------------------------------------------------------------------
+# Not Like
+# -----------------------------------------------------------------------------
 
-class GCbetween(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCbetween')
+class GCnotlike (GBinaryConditionElement):
+  def __init__ (self, parent = None):
+    GBinaryConditionElement.__init__ (self, parent, 'GCnotlike')
 
   # ---------------------------------------------------------------------------
+  # Evaluate an inverted like condition
+  # ---------------------------------------------------------------------------
+
+  def evaluate (self, lookup):
+    GBinaryConditionElement.evaluate (self, lookup)
+    strpat = "^%s" % self.values [1]
+    strpat = strpat.replace ('?', '.').replace ('%', '.*')
+    pattern = re.compile (strpat)
+    return pattern.match (self.values [0]) is None
+
+
+# -----------------------------------------------------------------------------
+# Between
+# -----------------------------------------------------------------------------
+
+class GCbetween (GConditionElement):
+  def __init__ (self, parent = None):
+    self._maxChildren = 3
+    GConditionElement.__init__ (self, parent, 'GCbetween')
+
+  # ---------------------------------------------------------------------------
   # evaluate beetween relation
   # ---------------------------------------------------------------------------
 
-  def eval (self, lookup):
-    self._needChildren (3)
-    result = []
-    unify ([v.eval (lookup) for v in self._children], result)
-    return result [1] <= result [0] <= result [2]
+  def evaluate (self, lookup):
+    self._needChildren (self._maxChildren)
+    values = unify ([v.evaluate (lookup) for v in self._children])
+    return values [1] <= values [0] <= values [2]
 
 
-class GCnotbetween(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCnotbetween')
+# -----------------------------------------------------------------------------
+# Not Between
+# -----------------------------------------------------------------------------
 
-  def eval (self, lookup):
-    self._needChildren (3)
-    result = []
-    unify ([v.eval (lookup) for v in self._children], result)
-    return not (result [1] <= result [0] <= result [2])
+class GCnotbetween (GConditionElement):
+  def __init__ (self, parent = None):
+    self._maxChildren = 3
+    GConditionElement.__init__ (self, parent, 'GCnotbetween')
 
+  # ---------------------------------------------------------------------------
+  # evaluate an inverted beetween relation
+  # ---------------------------------------------------------------------------
 
-class GCnull(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCnull')
+  def evaluate (self, lookup):
+    self._needChildren (self._maxChildren)
+    values = unify ([v.evaluate (lookup) for v in self._children])
+    return not (values [1] <= values [0] <= values [2])
 
-  def eval (self, lookup):
-    self._needChildren (1)
-    return self._children [0].eval (lookup) is None
 
+# -----------------------------------------------------------------------------
+# is NULL
+# -----------------------------------------------------------------------------
 
-class GCnotnull(GConditionElement):
-  def __init__(self, parent=None):
-    GConditionElement.__init__(self, parent, 'GCnotnull')
+class GCnull (GUnaryConditionElement):
+  def __init__ (self, parent = None):
+    GUnaryConditionElement.__init__ (self, parent, 'GCnull')
 
-  def eval (self, lookup):
-    self._needChildren (1)
-    return not self._children [0].eval (lookup) is None
+  # ---------------------------------------------------------------------------
+  # evaluate if a child is NULL
+  # ---------------------------------------------------------------------------
 
+  def evaluate (self, lookup):
+    self._needChildren (self._maxChildren)
+    return self._children [0].evaluate (lookup) is None
 
 
-# build an impossible condition  GCondition={0=1}
-GCimpossible=GCondition()
-_h=GCeq(GCimpossible)
-GCConst(_h,1)
-GCConst(_h,2)
+# -----------------------------------------------------------------------------
+# is Not NULL
+# -----------------------------------------------------------------------------
 
+class GCnotnull (GUnaryConditionElement):
+  def __init__ (self, parent = None):
+    GUnaryConditionElement.__init__ (self, parent, 'GCnotnull')
 
-def getXMLelements(updates={}):
+  # ---------------------------------------------------------------------------
+  # evaluate if a child is not NULL
+  # ---------------------------------------------------------------------------
+
+  def evaluate (self, lookup):
+    self._needChildren (self._maxChildren)
+    return self._children [0].evaluate (lookup) is not None
+
+
+# =============================================================================
+# Return a dictionary of all XML elements available
+# =============================================================================
+
+def getXMLelements (updates = {}):
   xmlElements = {
-##      'conditions':       {
-##         'BaseClass': GConditions,
-##         'SingleInstance': 1,
-##         'ParentTags':  None },
-
       'conditions':       {
          'BaseClass': GCondition,
          'ParentTags':  ('conditions','and','or','not','negate'),
@@ -543,213 +885,143 @@
 
   return xmlElements
 
+###############################################################################
+###############################################################################
+####                        Convenience Methods                              ##
+###############################################################################
+###############################################################################
 
-#
-# a table with extra information about the different condition types
-#  (needed for condition tree <-> prefix table conversion)
-#
-conditionElements = {
-  'add':             (2, 999, GCadd ),
-  'sub':             (2, 999, GCsub ),
-  'mul':             (2, 999, GCmul ),
-  'div':             (2, 999, GCdiv ),
-  'and':             (1, 999, GCand ),
-  'or':              (2, 999, GCor  ),
-  'not':             (1,   1, GCnot ),
-  'negate':          (1,   1, GCnegate ),
-  'eq':              (2,   2, GCeq  ),
-  'ne':              (2,   2, GCne  ),
-  'gt':              (2,   2, GCgt  ),
-  'ge':              (2,   2, GCge  ),
-  'lt':              (2,   2, GClt  ),
-  'le':              (2,   2, GCle  ),
-  'like':            (2,   2, GClike ),
-  'notlike':         (2,   2, GCnotlike ),
-  'between':         (3,   3, GCbetween ),
-  'null':            (1,   1, GCnull)
-  }
+# =============================================================================
+# Create a condition tree from an element sequence in prefix notation
+# =============================================================================
 
+def buildTreeFromList (prefixList):
+  """
+  This function creates a new condition tree from the given element sequence,
+  which must be in prefix notation.
+  """
+  checktype (prefixList, types.ListType)
 
-#############################################################################
-#############################################################################
-####                       Convenience Methods                             ##
-#############################################################################
-#############################################################################
+  result = GCondition ()
+  result.buildFromList (prefixList)
+  return result
 
 
-#
-# Build a condition tree using a dict
-# as a source.  Assumes keys are field
-# names and values are constants.
-#
-def buildConditionFromDict (dict, comparison=GCeq, logic=GCand):
-  cond = GCondition()
-  lastParent = cond
+# =============================================================================
+# Create a condition tree from a dictionary
+# =============================================================================
 
-  if len(dict.keys()):
-    lastParent = logic(lastParent)
+def buildConditionFromDict (dictionary, comparison = GCeq, logic = GCand):
+  """
+  This function creates a new condition tree using @comparison as operation
+  between keys and values and @logic as concatenation for all keys.
+  """
+  result = GCondition ()
+  lastParent = result
 
-  for key in dict.keys():
-    eq = comparison(lastParent)
-    GCField(eq, key)
+  if len (dictionary.keys ()):
+    lastParent = logic (lastParent)
 
-##    if string.split(str(type(dict[key])),"'")[1] in ('int', 'float'):
-    if type(dict[key]) in (types.IntType, types.FloatType):
-        consttype="number"
+  for key, value in dictionary.items ():
+    operation = comparison (lastParent)
+    GCField (operation, key)
+
+    if type (value) in [types.IntType, types.FloatType, types.LongType]:
+      consttype = 'number'
     else:
-        consttype="char"
-    GCConst(eq, dict[key], consttype)
+      consttype = 'char'
 
-  return cond
+    GCConst (operation, value, consttype)
 
-#
-# Combine two conditions with an and clause.
-# NOTE: This modifies cond1 (and also returns it)
-#
+  return result
+
+
+# =============================================================================
+# Combine two conditions with an AND clause. Side-effect: cond1 will be changed
+# =============================================================================
+
 def combineConditions (cond1, cond2):
-  if cond1 == None or cond1 == {}:
+  """
+  This function combines the two condition trees @cond1 and @cond2 using an AND
+  clause. Both arguments can be given as conditiontrees or as dictionaries. In
+  the latter case they would be converted using buildConditionFromDict (). As a
+  side effect of this function, @cond1 would be changed (if neccessary). If
+  neither of the conditions has a single top-level element of type GCand a new
+  element would be created.
+  """
+  # check for the trivial cases
+  if cond1 is None or cond1 == {}:
     return cond2
-  elif cond2 == None or cond2 == {}:
-    return cond1
 
-  if type(cond1) == type({}):
-    cond1 = buildConditionFromDict(cond1)
-  if type(cond2) == type({}):
-    cond2 = buildConditionFromDict(cond2)
-
-  if not len(cond1._children):
-    cond1._children = cond2._children
+  elif cond2 is None or cond2 == {}:
     return cond1
-  elif len(cond2._children):
-    children = cond1._children[:]
-    cond1._children = []
-    _and = GCand(cond1)
-    _and._children = children
-    if len(cond2._children) > 1:
-      _and2 = GCand(cond1)
-      _and2._children = cond2._children[:]
-    else:
-      cond1._children.append(cond2._children[0])
 
-  return cond1
+  # make sure both parts are condition trees
+  if isinstance (cond1, types.DictType):
+    cond1 = buildConditionFromDict (cond1)
 
+  if isinstance (cond2, types.DictType):
+    cond2 = buildConditionFromDict (cond2)
 
-# creates an GCondition Tree out of an list of tokens in a prefix
-# order.
+  # if the master condition has no elements, assign the second condition's
+  # children
+  if not len (cond1._children):
+    cond1._children = cond2._children
+    update = cond1
 
-def buildTreeFromPrefix(term):
+  elif len (cond2._children):
+    # First normalize the master condition. This means we make sure to have a
+    # valid logical operator as single top element
+    if len (cond1._children) > 1 or not isinstance (cond1._children [0], 
GCand):
+      oldChildren = cond1._children [:]
+      cond1._children = []
+      parent = GCand (cond1)
+      parent._children = oldChildren
 
-  # create a GCondition object as top object in the object stack
-  parent={0:(GCondition())}
+    else:
+      parent = cond1._children [0]
 
-  # GCondition will have only one parameter
-  # add paramcount=1 to the parameter count stack
-  paramcount={0:1}
+    # determine where to start in the second condition tree
+    buddy = cond2
+    while len (buddy._children) == 1 and \
+          isinstance (buddy._children [0], GCand):
+      buddy = buddy._children [0]
 
-  # set start level for stack to zero
-  level=0
-  for i in term:
+    # and append all of the buddy's children to the top-level-and
+    parent._children.extend (buddy._children)
 
-    # convert type into an object
-    if conditionElements.has_key(i[0]):
-      e=conditionElements[i[0]][2](parent[level])
-      level=level+1
-      # get parameter count
-      paramcount[level]=conditionElements[i[0]][0]
-      parent[level]=e
-    elif i[0]=="field":
-      e=GCField(parent[level], i[1])
-      paramcount[level]=paramcount[level]-1
-      if paramcount[level]==0:
-        level=level-1
-    elif i[0]=="const":
-      e=GCConst(parent[level], i[1])
-      paramcount.update({level:(paramcount[level]-1)})
-      if paramcount[level]==0:
-        level=level-1
-#    print "NAME: %s  VALUE: %s  LEVEL: %s PCOUNT: %s" % \
-#          (i[0],i[1],level,paramcount[level])
-
-  return parent[0];
-
-def buildPrefixFromTree(conditionTree):
-  if type(conditionTree) != types.InstanceType:
-    tmsg = u_("No valid condition tree")
-    raise ConditionError, tmsg
+    update = parent
   else:
-    otype = string.lower(conditionTree._type[2:])
+    update = None
 
-    #
-    #  care for objects without children
-    #
-    if otype == 'cfield':
-      return [('field',"%s" % conditionTree.name)]
+  if update is not None:
+    for child in update._children:
+      child._parent = update
 
-    elif otype == 'cconst':
-      return [('const',conditionTree.value)]
+  return cond1
 
-    elif otype == 'cparam':
-      return [('const', conditionTree.getValue())]
 
-    #
-    #  if its an conditional object, then process it's children
-    #
-    elif conditionElements.has_key(otype):
-      result=[]
-
-      # first add operator to the list
-      result.append((otype,''));  #  ,None));
-
-
-      # change operations with more than there minimal element no into
-      # multiple operations with minimal elements
-      # reason: to prevent a b c d AND OR being not well defined
-      # because it can be a"a b c d AND AND OR" or "a b c d AND OR OR"
-      paramcount=len(conditionTree._children)
-      while (paramcount > \
-             conditionElements[otype][0]):
-        paramcount=paramcount-1
-        result.append((otype,''));
-
-
-      # then add children
-      for i in range(0, len(conditionTree._children)):
-        result = result + \
-                 buildPrefixFromTree(conditionTree._children[i])
-
-      #
-      #  check for integrity of condition
-      #
-      if len(conditionTree._children) < conditionElements[otype][0]:
-        tmsg = u_('Condition element "%s" expects at least %s arguments; found 
%s') % \
-                 (otype, conditionElements[otype][0], 
len(conditionTree._children))
-        raise ConditionError, tmsg
-
-      if len(conditionTree._children) > conditionElements[otype][1]:
-        tmsg = u_('Condition element "%s" expects at most %s arguments; found 
%s') % \
-                (otype, conditionElements[otype][1], 
len(conditionTree._children))
-        raise ConditionError, tmsg
-
-
-      # return combination
-      return result;
-
-    else:
-      tmsg = u_('Condition clause "%s" is not supported '
-                'by the condition to prefix table conversion.') % otype
-      raise ConditionNotSupported, tmsg
-
-
-# -----------------------------------------------------------------------------
+# =============================================================================
 # Unify all elements in values to the same type
-# -----------------------------------------------------------------------------
+# =============================================================================
 
-def unify (values, result):
+def unify (values):
   """
   This function converts all values in the sequence @values to the same types
   pushing the results into the sequence @result.
   """
+  result = []
+  __unify (values, result)
+  return result
 
+# -----------------------------------------------------------------------------
+# Actual working method for unification
+# -----------------------------------------------------------------------------
+def __unify (values, result):
+  """
+  This function does the dirty work of 'unify ()'.
+  """
+
   checktype (values, types.ListType)
 
   if not len (values):
@@ -770,7 +1042,7 @@
   if type (v1) == type (v2):
     result.append (v1)
     values.remove (v1)
-    unify (values, result)
+    __unify (values, result)
 
   else:
     # String-Conversions
@@ -853,10 +1125,189 @@
       raise ConversionRuleError, (v1, v2)
   
     values [oldValue == v2] = newValue
-    unify (values, result)
+    __unify (values, result)
 
 
 # =============================================================================
+# Definition of an impossible condition
+# =============================================================================
+
+GCimpossible = buildTreeFromList (['eq', ['const', 1], ['const', 2]])
+
+
+
+###############################################################################
+###############################################################################
+####                        Depreciated Methods                              ##
+###############################################################################
+###############################################################################
+
+#
+# a table with extra information about the different condition types
+#  (needed for condition tree <-> prefix table conversion)
+#
+conditionElements = {
+  'add':             (2, 999, GCadd ),
+  'sub':             (2, 999, GCsub ),
+  'mul':             (2, 999, GCmul ),
+  'div':             (2, 999, GCdiv ),
+  'and':             (1, 999, GCand ),
+  'or':              (2, 999, GCor  ),
+  'not':             (1,   1, GCnot ),
+  'negate':          (1,   1, GCnegate ),
+  'eq':              (2,   2, GCeq  ),
+  'ne':              (2,   2, GCne  ),
+  'gt':              (2,   2, GCgt  ),
+  'ge':              (2,   2, GCge  ),
+  'lt':              (2,   2, GClt  ),
+  'le':              (2,   2, GCle  ),
+  'like':            (2,   2, GClike ),
+  'notlike':         (2,   2, GCnotlike ),
+  'between':         (3,   3, GCbetween ),
+  'null':            (1,   1, GCnull)
+  }
+
+# creates an GCondition Tree out of an list of tokens in a prefix
+# order.
+
+def buildTreeFromPrefix(term):
+
+  # create a GCondition object as top object in the object stack
+  parent={0:(GCondition())}
+
+  # GCondition will have only one parameter
+  # add paramcount=1 to the parameter count stack
+  paramcount={0:1}
+
+  # set start level for stack to zero
+  level=0
+  for i in term:
+
+    # convert type into an object
+    if conditionElements.has_key(i[0]):
+      e=conditionElements[i[0]][2](parent[level])
+      level=level+1
+      # get parameter count
+      paramcount[level]=conditionElements[i[0]][0]
+      parent[level]=e
+    elif i[0]=="field":
+      e=GCField(parent[level], i[1])
+      paramcount[level]=paramcount[level]-1
+      if paramcount[level]==0:
+        level=level-1
+    elif i[0]=="const":
+      e=GCConst(parent[level], i[1])
+      paramcount.update({level:(paramcount[level]-1)})
+      if paramcount[level]==0:
+        level=level-1
+#    print "NAME: %s  VALUE: %s  LEVEL: %s PCOUNT: %s" % \
+#          (i[0],i[1],level,paramcount[level])
+
+  return parent[0];
+
+
+
+def buildPrefixFromTree(conditionTree):
+  if type(conditionTree) != types.InstanceType:
+    tmsg = u_("No valid condition tree")
+    raise ConditionError, tmsg
+  else:
+    otype = string.lower(conditionTree._type[2:])
+
+    #
+    #  care for objects without children
+    #
+    if otype == 'cfield':
+      return [('field',"%s" % conditionTree.name)]
+
+    elif otype == 'cconst':
+      return [('const',conditionTree.value)]
+
+    elif otype == 'cparam':
+      return [('const', conditionTree.getValue())]
+
+    #
+    #  if its an conditional object, then process it's children
+    #
+    elif conditionElements.has_key(otype):
+      result=[]
+
+      # first add operator to the list
+      result.append((otype,''));  #  ,None));
+
+
+      # change operations with more than there minimal element no into
+      # multiple operations with minimal elements
+      # reason: to prevent a b c d AND OR being not well defined
+      # because it can be a"a b c d AND AND OR" or "a b c d AND OR OR"
+      paramcount=len(conditionTree._children)
+      while (paramcount > \
+             conditionElements[otype][0]):
+        paramcount=paramcount-1
+        result.append((otype,''));
+
+
+      # then add children
+      for i in range(0, len(conditionTree._children)):
+        result = result + \
+                 buildPrefixFromTree(conditionTree._children[i])
+
+      #
+      #  check for integrity of condition
+      #
+      if len(conditionTree._children) < conditionElements[otype][0]:
+        tmsg = u_('Condition element "%s" expects at least %s arguments; found 
%s') % \
+                 (otype, conditionElements[otype][0], 
len(conditionTree._children))
+        raise ConditionError, tmsg
+
+      if len(conditionTree._children) > conditionElements[otype][1]:
+        tmsg = u_('Condition element "%s" expects at most %s arguments; found 
%s') % \
+                (otype, conditionElements[otype][1], 
len(conditionTree._children))
+        raise ConditionError, tmsg
+
+
+      # return combination
+      return result;
+
+    else:
+      tmsg = u_('Condition clause "%s" is not supported '
+                'by the condition to prefix table conversion.') % otype
+      raise ConditionNotSupported, tmsg
+
+#
+# Combine two conditions with an and clause.
+# NOTE: This modifies cond1 (and also returns it)
+#
+def __Original__combineConditions (cond1, cond2):
+  if cond1 == None or cond1 == {}:
+    return cond2
+  elif cond2 == None or cond2 == {}:
+    return cond1
+
+  if type(cond1) == type({}):
+    cond1 = buildConditionFromDict(cond1)
+  if type(cond2) == type({}):
+    cond2 = buildConditionFromDict(cond2)
+
+  if not len(cond1._children):
+    cond1._children = cond2._children
+    return cond1
+  elif len(cond2._children):
+    children = cond1._children[:]
+    cond1._children = []
+    _and = GCand(cond1)
+    _and._children = children
+    if len(cond2._children) > 1:
+      _and2 = GCand(cond1)
+      _and2._children = cond2._children[:]
+    else:
+      cond1._children.append(cond2._children[0])
+
+  return cond1
+
+
+
+# =============================================================================
 # Module self test code
 # =============================================================================
 
@@ -864,28 +1315,157 @@
   import sys
   from mx.DateTime import *
 
-  def check (x, y):
-    print "unify: %s (%s) vs %s (%s)" % (x, type (x), y, type (y))
-    res  = []
-    vals = []
-    if x != 0: vals.append (x)
-    if y != 0: vals.append (y)
+  # ---------------------------------------------------------------------------
+  # self-test-function: unify two arguments
+  # ---------------------------------------------------------------------------
 
+  def _check_unify (values):
+    args = string.join (["%s (%s)" % (v, type (v).__name__) for v in values])
+    print "\nUnify:", args
+
     try:
-      unify (vals, res)
-      print "result:", ["%s (%s)" % (r, type (r).__name__) for r in res], "\n"
+      res = string.join (["%s (%s)" % (r, type (r).__name__) \
+                          for r in unify (values)])
+      print "  RES=", res
 
     except:
       print sys.exc_info () [0], sys.exc_info () [1]
 
-  check (u'17', 5)
-  check (5, '18')
-  check (now (), '2004-08-15 14:00')
-  check ('13.0', 12)
-  check ('15', '')
-  check (7L, '12')
-  check (7L, '12.2')
-  check (1, 'True')
-  check (0, 0)
-  check (1, 0)
-  check (None, 0)
+
+  _check_unify ([u'17', 5])
+  _check_unify ([5, '18'])
+  _check_unify ([now (), '2004-08-15 14:00'])
+  _check_unify (['13.0', 12])
+  _check_unify (['15', ''])
+  _check_unify ([7L, '12'])
+  _check_unify ([7L, '12.2'])
+  _check_unify ([1, 'True'])
+  _check_unify ([])
+  _check_unify ([1])
+  _check_unify ([None])
+  _check_unify (['5.43', 12, 18L])
+
+  print "unification sequence complete"
+  raw_input ()
+
+
+  # ---------------------------------------------------------------------------
+  # Self-test-function: Construct conditions and evaluate them
+  # ---------------------------------------------------------------------------
+
+  def _check_construction (source, lookup):
+    if isinstance (source, types.DictType):
+      cond = buildConditionFromDict (source)
+    else:
+      cond = buildTreeFromList (source)
+
+    print
+    print "Source:", source
+    print "Prefix:", cond.prefixNotation ()
+    print "Lookup:", lookup
+    print "Eval  :", cond.evaluate (lookup)
+
+
+  print "Condition tree transformation test"
+
+  prefix = ['and', ['eq', ['field', u'foo'], ['const', 'bar']],
+                   ['ne', ['field', u'bar'], ['const', 'foobar']]]
+
+  lookup = {'foo': 'bar',
+            'bar': 'foobarX'}
+  _check_construction (prefix, lookup)
+
+
+  prefix = ['or', ['between', ['field', u'foo'],
+                        ['const', 'bar'], ['const', 'char']],
+            ['not', ['null', ['field', u'price']]]]
+
+  lookup = {'foo': 'capo', 'price': None}
+  _check_construction (prefix, lookup)
+
+  prefix = ['like', ['field', u'foo'], ['const', 'bar%']]
+  cond = buildTreeFromList (prefix)
+  lookup = {'foo': 'Barrel'}
+  _check_construction (prefix, lookup)
+
+  lookup = {'foo': 'bar is running'}
+  _check_construction (prefix, lookup)
+
+  source = {'foo': 'bar', 'bar': 'trash'}
+  lookup = {'foo': 'bar', 'bar': 'trash'}
+  _check_construction (source, lookup)
+
+  prefix = [['eq', ['field', 'foo'], ['const', 'bar']],
+            ['lt', ['field', 'bar'], ['const', 10]]]
+  lookup = {'foo': 'bar', 'bar': 5.6}
+  _check_construction (prefix, lookup)
+
+  print "end of construction test sequence"
+  raw_input ()
+
+  # ---------------------------------------------------------------------------
+  # Self-test-function: Combine and evaluate condition trees
+  # ---------------------------------------------------------------------------
+
+  def _check_combineConditions (cond1, cond2):
+    rc1 = cond1
+    rc2 = cond2
+    if not isinstance (cond1, types.DictType):
+      rc1 = cond1.prefixNotation ()
+    if not isinstance (cond2, types.DictType):
+      rc2 = cond2.prefixNotation ()
+
+    print "\nCombination of:"
+    print "     a:", rc1
+    print "     b:", rc2
+    res = combineConditions (cond1, cond2)
+    print "   RES=", res.prefixNotation ()
+
+
+  cond1 = GCondition ()
+  cond2 = GCondition ()
+
+  _check_combineConditions (cond1, cond2)
+
+  prefix = ['eq', ['field', 'foo'], ['const', 'bar']]
+  cond2 = buildTreeFromList (prefix)
+
+  _check_combineConditions (cond1, cond2)
+
+  cond1 = buildTreeFromList (prefix)
+  cond2 = GCondition ()
+  _check_combineConditions (cond1, cond2)
+
+  prefix2 = ['and', ['null', ['field', 'nfoo']],
+                    ['notnull', ['field', 'nbar']]]
+  cond2 = buildTreeFromList (prefix2)
+  _check_combineConditions (cond1, cond2)
+
+  cond1 = cond2
+  cond2 = buildTreeFromList (prefix)
+  _check_combineConditions (cond1, cond2)
+
+  prefix3 = ['null', ['field', 'nfoo']]
+  cond1 = buildTreeFromList (prefix)
+  cond2 = buildTreeFromList (prefix3)
+  _check_combineConditions (cond1, cond2)
+
+  prefix4 = [['ne', ['field', 'foo'], ['const', 'bar']],
+             ['lt', ['field', 'price'], ['const', 150.0]]]
+  cond2 = buildTreeFromList (prefix4)
+  _check_combineConditions (cond1, cond2)
+
+  cond1 = buildTreeFromList (prefix)
+  _check_combineConditions (cond2, cond1)
+
+  prefix  = ['or', ['null', ['field', 'nfoo']], ['eq', ['field', 'bar']]]
+  prefix2 = ['or', ['notnull', ['field', 'nbar']], ['gt', ['field', 'foo']]]
+  cond1 = buildTreeFromList (prefix)
+  cond2 = buildTreeFromList (prefix2)
+  _check_combineConditions (cond1, cond2)
+
+  cond1 = buildTreeFromList (['and'])
+  cond2 = buildTreeFromList (prefix)
+  _check_combineConditions (cond1, cond2)
+  
+  print "\n\nImpossible condition:", GCimpossible.prefixNotation ()


Property changes on: trunk/gnue-common/src/datasources/GConditions.py
___________________________________________________________________
Name: svn:keywords
   - +svn:Id
   + Id

Modified: 
trunk/gnue-common/src/datasources/drivers/appserver/appserver/DataObject.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/appserver/appserver/DataObject.py 
2004-05-07 05:02:37 UTC (rev 5784)
+++ trunk/gnue-common/src/datasources/drivers/appserver/appserver/DataObject.py 
2004-05-07 09:11:21 UTC (rev 5785)
@@ -53,7 +53,7 @@
     else:
       cond = conditions
 
-    query = GConditions.buildPrefixFromTree (cond._children [0])
+    query = cond.prefixNotation ()
 
     return query
 

Modified: trunk/gnue-common/src/schema/importer/Importer.py
===================================================================
--- trunk/gnue-common/src/schema/importer/Importer.py   2004-05-07 05:02:37 UTC 
(rev 5784)
+++ trunk/gnue-common/src/schema/importer/Importer.py   2004-05-07 09:11:21 UTC 
(rev 5785)
@@ -145,13 +145,12 @@
           else:
             fvalue = item.value
 
-          cond.extend ([["eq", ""], ["field", fieldname], 
-                       ["const", fvalue]])
+          cond.append (['eq', ['field', fieldname], ['const', fvalue]])
 
       if len (cond) == 0:
         raise ENoCondition (data.name, rowIndex)
 
-      condition_tree = GConditions.buildTreeFromPrefix (cond)
+      condition_tree = GConditions.buildTreeFromList (cond)
       resultset = datasource.createResultSet (condition_tree)
 
       if resultset.firstRecord () is None:





reply via email to

[Prev in Thread] Current Thread [Next in Thread]