/[papo]/gnue/common/src/GConditions.py
ViewVC logotype

Diff of /gnue/common/src/GConditions.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by charlie, Tue Aug 27 18:15:51 2002 UTC revision 1.5 by styxman, Fri Nov 15 15:32:54 2002 UTC
# Line 39  class ConditionError (StandardError): Line 39  class ConditionError (StandardError):
39  class ConditionNotSupported (ConditionError):  class ConditionNotSupported (ConditionError):
40    pass    pass
41    
 #  
 # Build a condition tree using a dict  
 # as a source.  Assumes keys are field  
 # names and values are constants.  
 #  
 def buildConditionFromDict (dict, comparison=None):  
   cond = GCondition()  
   lastParent = cond  
   
   if len(dict.keys()):  
     lastParent = GCand(lastParent)  
   
   for key in dict.keys():  
     eq = (comparison or GCeq)(lastParent)  
     GCField(eq, key)  
     GCConst(eq, dict[key])  
   
   return cond  
   
 #  
 # Combine two conditions with an and clause.  
 # NOTE: This modifies cond1 (and also returns it)  
 #  
 def 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({}):  
     cond1 = 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  
   
   
 # 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:  
     raise ConditionError, "No valid condition tree"  
   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 == 'param':  
       return [('param', 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]:  
         raise GConditions.ConditionError, \  
               _('Condition element "%s" expects at least %s arguments; found %s') % \  
               (otype, conditionElements[otype][0], len(conditionTree._children))              
         
       if len(conditionTree._children) > conditionElements[otype][1]:  
         raise GConditions.ConditionError, \  
               _('Condition element "%s" expects at most %s arguments; found %s') % \  
               (otype, conditionElements[otype][1], len(conditionTree._children))  
               
                           
       # return combination  
       return result;  
               
     else:  
       raise GConditions.ConditionNotSupported, \  
             _('Condition clause "%s" is not supported '+  
             'by the condition to prefix table conversion.') % otype  
     
   
42    
43  class GCondition(GObj):  class GCondition(GObj):
44    def __init__(self, parent=None, type="GCCondition"):    def __init__(self, parent=None, type="GCCondition"):
# Line 319  GCConst(_h,2) Line 162  GCConst(_h,2)
162    
163  def getXMLelements(updates={}):  def getXMLelements(updates={}):
164    xmlElements = {    xmlElements = {
165    ##      'conditions':       {
166    ##         'BaseClass': GConditions,
167    ##         'SingleInstance': 1,
168    ##         'ParentTags':  None },
169    
170        'conditions':       {        'conditions':       {
171           'BaseClass': GConditions,           'BaseClass': GCondition,
172           'SingleInstance': 1,           'ParentTags':  ('conditions','and','or','not','negate'),
173           'ParentTags':  None },           'Deprecated': 'Use the <condition> tag instead.',
174            },
175        'condition':       {        'condition':       {
176           'BaseClass': GCondition,           'BaseClass': GCondition,
177           'ParentTags':  ('conditions','and','or','not','negate') },           'ParentTags':  ('conditions','and','or','not','negate') },
# Line 332  def getXMLelements(updates={}): Line 181  def getXMLelements(updates={}):
181              'name':     {              'name':     {
182                 'Required': 1,                 'Required': 1,
183                 'Typecast': GTypecast.name } },                 'Typecast': GTypecast.name } },
184           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('eq','ne','lt','le','gt','ge','add','sub','mul',
185                           'like','notlike','between','notbetween') },                           'div','like','notlike','between','notbetween') },
186        'cparam':       {        'cparam':       {
187           'BaseClass': GCParam,           'BaseClass': GCParam,
188           'Attributes': {           'Attributes': {
# Line 341  def getXMLelements(updates={}): Line 190  def getXMLelements(updates={}):
190                 'Required': 1,                 'Required': 1,
191                 'Unique':   1,                 'Unique':   1,
192                 'Typecast': GTypecast.name } },                 'Typecast': GTypecast.name } },
193           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('eq','ne','lt','le','gt','ge','add','sub','mul',
194                           'like','notlike','between','notbetween') },                           'div','like','notlike','between','notbetween') },
195        'cconst':       {        'cconst':       {
196           'BaseClass': GCConst,           'BaseClass': GCConst,
197           'Attributes': {           'Attributes': {
198              'value':     {              'value':     {
199                 'Required': 1,                 'Required': 1,
200                 'Typecast': GTypecast.text } },                 'Typecast': GTypecast.text } },
201           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('eq','ne','lt','le','gt','ge','add','sub','mul',
202                           'like','notlike','between','notbetween') },                           'div','like','notlike','between','notbetween') },
203          'add':       {
204             'BaseClass': GCadd,
205             'ParentTags':  ('eq','ne','lt','le','gt','ge','add','sub','mul',
206                             'div','like','notlike','between','notbetween') },
207          'sub':       {
208             'BaseClass': GCsub,
209             'ParentTags':  ('eq','ne','lt','le','gt','ge','add','sub','mul',
210                             'div','like','notlike','between','notbetween') },
211          'mul':       {
212             'BaseClass': GCmul,
213             'ParentTags':  ('eq','ne','lt','le','gt','ge','add','sub','mul',
214                             'div','like','notlike','between','notbetween') },
215          'div':       {
216             'BaseClass': GCdiv,
217             'ParentTags':  ('eq','ne','lt','le','gt','ge','add','sub','mul',
218                             'div','like','notlike','between','notbetween') },
219        'and':       {        'and':       {
220           'BaseClass': GCand,           'BaseClass': GCand,
221           'ParentTags':  ('condition','and','or','not','negate') },           'ParentTags':  ('condition','and','or','not','negate') },
# Line 365  def getXMLelements(updates={}): Line 230  def getXMLelements(updates={}):
230           'ParentTags':  ('condition','and','or','not','negate') },           'ParentTags':  ('condition','and','or','not','negate') },
231        'eq':       {        'eq':       {
232           'BaseClass': GCeq,           'BaseClass': GCeq,
233           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('condition','and','or','not','negate') },
                          'like','notlike','between','notbetween') },  
234        'ne':       {        'ne':       {
235           'BaseClass': GCne,           'BaseClass': GCne,
236           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('condition','and','or','not','negate') },
                          'like','notlike','between','notbetween') },  
237        'gt':       {        'gt':       {
238           'BaseClass': GCgt,           'BaseClass': GCgt,
239           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('condition','and','or','not','negate') },
                          'like','notlike','between','notbetween') },  
240        'ge':       {        'ge':       {
241           'BaseClass': GCge,           'BaseClass': GCge,
242           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('condition','and','or','not','negate') },
                          'like','notlike','between','notbetween') },  
243        'lt':       {        'lt':       {
244           'BaseClass': GClt,           'BaseClass': GClt,
245           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('condition','and','or','not','negate') },
                          'like','notlike','between','notbetween') },  
246        'le':       {        'le':       {
247           'BaseClass': GCle,           'BaseClass': GCle,
248           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('condition','and','or','not','negate') },
                          'like','notlike','between','notbetween') },  
249        'like':       {        'like':       {
250           'BaseClass': GClike,           'BaseClass': GClike,
251           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('condition','and','or','not','negate') },
                          'like','notlike','between','notbetween') },  
252        'notlike':       {        'notlike':       {
253           'BaseClass': GCnotlike,           'BaseClass': GCnotlike,
254           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('condition','and','or','not','negate') },
                          'like','notlike','between','notbetween') },  
255        'between':       {        'between':       {
256           'BaseClass': GCbetween,           'BaseClass': GCbetween,
257           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('condition','and','or','not','negate') },
                          'like','notlike','between','notbetween') },  
258        'notbetween':       {        'notbetween':       {
259           'BaseClass': GCnotbetween,           'BaseClass': GCnotbetween,
260           'ParentTags':  ('eq','ne','lt','le','gt','ge',           'ParentTags':  ('condition','and','or','not','negate') },
                          'like','notlike','between','notbetween') },  
261        'null':      {        'null':      {
262            'BaseClass': GCnull,            'BaseClass': GCnull,
263            'ParentTags': ('FIXME') },            'ParentTags': ('FIXME') },
# Line 430  conditionElements = { Line 285  conditionElements = {
285    'or':              (2, 999, GCor  ),    'or':              (2, 999, GCor  ),
286    'not':             (1,   1, GCnot ),    'not':             (1,   1, GCnot ),
287    'negate':          (1,   1, GCnegate ),    'negate':          (1,   1, GCnegate ),
   'null':            (1,   1, GCnull ),  
   'notnull':         (1,   1, GCnotnull ),  
288    'eq':              (2,   2, GCeq  ),    'eq':              (2,   2, GCeq  ),
289    'ne':              (2,   2, GCne  ),    'ne':              (2,   2, GCne  ),
290    'gt':              (2,   2, GCgt  ),    'gt':              (2,   2, GCgt  ),
# Line 440  conditionElements = { Line 293  conditionElements = {
293    'le':              (2,   2, GCle  ),    'le':              (2,   2, GCle  ),
294    'like':            (2,   2, GClike ),    'like':            (2,   2, GClike ),
295    'notlike':         (2,   2, GCnotlike ),    'notlike':         (2,   2, GCnotlike ),
296    'between':         (3,   3, GCbetween ),    'between':         (3,   3, GCbetween )
   'notbetween':      (3,   3, GCnotbetween ),  
297    }    }
298    
299    
300    #############################################################################
301    #############################################################################
302    ####                       Convenience Methods                             ##
303    #############################################################################
304    #############################################################################
305    
306    
307    #
308    # Build a condition tree using a dict
309    # as a source.  Assumes keys are field
310    # names and values are constants.
311    #
312    def buildConditionFromDict (dict, comparison=GCeq, logic=GCand):
313      cond = GCondition()
314      lastParent = cond
315    
316      if len(dict.keys()):
317        lastParent = logic(lastParent)
318    
319      for key in dict.keys():
320        eq = comparison(lastParent)
321        GCField(eq, key)
322        GCConst(eq, dict[key])
323    
324      return cond
325    
326    #
327    # Combine two conditions with an and clause.
328    # NOTE: This modifies cond1 (and also returns it)
329    #
330    def combineConditions (cond1, cond2):
331      if cond1 == None or cond1 == {}:
332        return cond2
333      elif cond2 == None or cond2 == {}:
334        return cond1
335    
336      if type(cond1) == type({}):
337        cond1 = buildConditionFromDict(cond1)
338      if type(cond2) == type({}):
339        cond1 = buildConditionFromDict(cond2)
340    
341      if not len(cond1._children):
342        cond1._children = cond2._children
343        return cond1
344      elif len(cond2._children):
345        children = cond1._children[:]
346        cond1._children = []
347        _and = GCand(cond1)
348        _and._children = children
349        if len(cond2._children) > 1:
350          _and2 = GCand(cond1)
351          _and2._children = cond2._children[:]
352        else:
353          cond1._children.append(cond2._children[0])
354    
355      return cond1
356    
357    
358    # creates an GCondition Tree out of an list of tokens in a prefix
359    # order.  
360    
361    def buildTreeFromPrefix(term):
362    
363      # create a GCondition object as top object in the object stack
364      parent={0:(GCondition())}
365    
366      # GCondition will have only one parameter
367      # add paramcount=1 to the parameter count stack
368      paramcount={0:1}
369    
370      # set start level for stack to zero
371      level=0
372      for i in term:
373            
374        # convert type into an object
375        if conditionElements.has_key(i[0]):
376          e=conditionElements[i[0]][2](parent[level])
377          level=level+1
378          # get parameter count
379          paramcount[level]=conditionElements[i[0]][0]
380          parent[level]=e
381        elif i[0]=="field":      
382          e=GCField(parent[level], i[1])
383          paramcount[level]=paramcount[level]-1
384          if paramcount[level]==0:
385            level=level-1
386        elif i[0]=="const":
387          e=GCConst(parent[level], i[1])
388          paramcount.update({level:(paramcount[level]-1)})
389          if paramcount[level]==0:
390            level=level-1    
391    #    print "NAME: %s  VALUE: %s  LEVEL: %s PCOUNT: %s" % \
392    #          (i[0],i[1],level,paramcount[level])
393        
394      return parent[0];
395    
396    
397    def buildPrefixFromTree(conditionTree):
398      if type(conditionTree) != types.InstanceType:
399        raise ConditionError, "No valid condition tree"
400      else:        
401        otype = string.lower(conditionTree._type[2:])
402    
403        #
404        #  care for objects without children
405        #
406        if otype == 'cfield':
407          return [('field',"%s" % conditionTree.name)]
408    
409        elif otype == 'cconst':
410          return [('const',conditionTree.value)]
411    
412        elif otype == 'param':
413          return [('param', conditionTree.getValue())]
414              
415        #
416        #  if its an conditional object, then process it's children
417        #
418        elif conditionElements.has_key(otype):
419          result=[]
420          
421          # first add operator to the list
422          result.append((otype,''));  #  ,None));
423          
424    
425          # change operations with more than there minimal element no into
426          # multiple operations with minimal elements
427          # reason: to prevent a b c d AND OR being not well defined
428          # because it can be a"a b c d AND AND OR" or "a b c d AND OR OR"
429          paramcount=len(conditionTree._children)
430          while (paramcount > \
431                 conditionElements[otype][0]):
432            paramcount=paramcount-1
433            result.append((otype,''));
434                  
435    
436          # then add children
437          for i in range(0, len(conditionTree._children)):
438            result = result + \
439                     buildPrefixFromTree(conditionTree._children[i])
440    
441          #  
442          #  check for integrity of condition
443          #
444          if len(conditionTree._children) < conditionElements[otype][0]:
445            raise GConditions.ConditionError, \
446                  _('Condition element "%s" expects at least %s arguments; found %s') % \
447                  (otype, conditionElements[otype][0], len(conditionTree._children))            
448          
449          if len(conditionTree._children) > conditionElements[otype][1]:
450            raise GConditions.ConditionError, \
451                  _('Condition element "%s" expects at most %s arguments; found %s') % \
452                  (otype, conditionElements[otype][1], len(conditionTree._children))
453                
454                            
455          # return combination
456          return result;
457                
458        else:
459          raise GConditions.ConditionNotSupported, \
460                _('Condition clause "%s" is not supported '+
461                'by the condition to prefix table conversion.') % otype
462      
463    

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26