Home | History | Annotate | Download | only in tko
      1 """
      2 This library provides a bunch of miscellaneous parameter parsing,
      3 sql generating and list cleanup library functions that are used
      4 by both the reporting cli and web interface.
      5 """
      6 
      7 import sys, os, re
      8 
      9 tko = os.path.dirname(__file__)
     10 sys.path.insert(0, tko)
     11 
     12 import display, frontend, db
     13 
     14 db = db.db()
     15 
     16 def dprint(str):
     17     pass
     18     #print "! %s<br>" % str
     19 
     20 def parse_scrub_and_gen_condition(condition, valid_field_dict):
     21     me = parse_scrub_and_gen_condition   # shorten the name
     22     compare_ops = {'=':'=', '<>':'<>', '==':'=', '!=':'<>', '>':'>',
     23                    '<':'<', '>=':'>=', '<=':'<=', '~':'LIKE', '#':'REGEXP'}
     24 
     25     # strip white space
     26     condition = condition.strip()
     27 
     28     # ()'s
     29     #match = re.match(r'^[(](.+)[)]$', condition)
     30     #if match:
     31     #       dprint("Matched () on %s" % condition)
     32     #       depth = 0
     33     #       for c in match.group(1):
     34     #               if c == '(':    depth += 1
     35     #               if c == ')':    depth -= 1
     36     #               if depth < 0:   break
     37     #       dprint("Depth is %d" % depth)
     38     #       if depth == 0:
     39     #               dprint("Match...stripping ()'s")
     40     #               return me(match.group(1), valid_field_dict)
     41 
     42     # OR
     43     match = re.match(r'^(.+)[|](.+)$', condition)
     44     if match:
     45         dprint("Matched | on %s" % condition)
     46         (a_sql, a_values) = me(match.group(1), valid_field_dict)
     47         (b_sql, b_values) = me(match.group(2), valid_field_dict)
     48         return (" (%s) OR (%s) " % (a_sql, b_sql),
     49                 a_values + b_values)
     50 
     51     # AND
     52     match = re.match(r'^(.+)[&](.+)$', condition)
     53     if match:
     54         dprint("Matched & on %s" % condition)
     55         (a_sql, a_values) = me(match.group(1), valid_field_dict)
     56         (b_sql, b_values) = me(match.group(2), valid_field_dict)
     57         return (" (%s) AND (%s) " % (a_sql, b_sql),
     58                 a_values + b_values)
     59 
     60     # NOT
     61     #match = re.match(r'^[!](.+)$', condition)
     62     #if match:
     63     #       dprint("Matched ! on %s" % condition)
     64     #       (sql, values) = me(match.group(1), valid_field_dict)
     65     #       return (" NOT (%s) " % (sql,), values)
     66 
     67     # '<field> <op> <value>' where value can be quoted
     68     # double quotes are escaped....i.e.  '''' is the same as "'"
     69     regex = r'^(%s)[ \t]*(%s)[ \t]*' + \
     70             r'(\'((\'\'|[^\'])*)\'|"((""|[^"])*)"|([^\'"].*))$'
     71     regex = regex % ('|'.join(valid_field_dict.keys()),
     72                      '|'.join(compare_ops.keys()))
     73     match = re.match(regex, condition)
     74     if match:
     75         field = valid_field_dict[match.group(1)]
     76         op = compare_ops[match.group(2)]
     77         if match.group(5):
     78             val = match.group(4).replace("''", "'")
     79         elif match.group(7):
     80             val = match.group(6).replace('""', '"')
     81         elif match.group(8):
     82             val = match.group(8)
     83         else:
     84             raise "Internal error"
     85         return ("%s %s %%s" % (field, op), [val])
     86 
     87 
     88     raise "Could not parse '%s' (%s)" % (condition, regex)
     89