helper.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. def query_as_dict(expression, field_type=None):
  2. """Seralizes gluon.dal.Query as dictionary.
  3. Converts a gluon.dal.Query or gluon.dal.Expression
  4. into a dictionary structure that can be pickled and
  5. stored in the session.
  6. Args:
  7. expression: gluon.dal.Query or gluon.dal.Expression
  8. Returns:
  9. Dictionary in the form {op:op, first:expression, second:expression}
  10. op: the query operation (eg, AND, EQ, GT)
  11. expression: either a dictionary (that expands a gluon Table,
  12. Field, Expression or Query object) or a base object such as
  13. a string or list.
  14. For example:
  15. >>>query = (db.comment.id.belongs((1,2,3))) & (db.webpage.title == 'FAQ')
  16. >>>print query_as_dict(query)
  17. "{'second': {'second': 'FAQ', 'first': {'table': 'webpage', 'fieldname': 'title',
  18. 'tablename': 'webpage'}, 'op': 'EQ'}, 'first': {'second': (1, 2, 3), 'first':
  19. {'table': 'comment', 'fieldname': 'id', 'tablename': 'comment'}, 'op': 'BELONGS'},
  20. 'op': 'AND'}"
  21. """
  22. from gluon.dal import Query, Expression, Table, Field
  23. if isinstance(expression, Field):
  24. tablename = expression._tablename
  25. return dict(tablename=expression._tablename,
  26. table = str(expression._table),
  27. fieldname = expression.name)
  28. elif isinstance(expression, (Expression, Query)):
  29. if not expression.second is None:
  30. return dict(op=expression.op.im_func.__name__,
  31. first=query_as_dict(expression.first),
  32. second=query_as_dict(expression.second))
  33. elif not expression.first is None:
  34. if not expression.op is None:
  35. return dict(op=expression.op.im_func.__name__,
  36. first=query_as_dict(expression.first),
  37. second=None) # eg '(person.title IS NULL)'
  38. else:
  39. return expression.first
  40. elif not isinstance(expression.op, str):
  41. return expression.op()
  42. else:
  43. return '(%s)' % expression.op
  44. elif field_type:
  45. return str(represent(expression,field_type))
  46. elif isinstance(expression,(list,tuple)):
  47. return expression
  48. elif isinstance(expression, Table):
  49. return dict(tablename=expression._tablename,
  50. table = str(expression))
  51. elif expression==None:
  52. return None
  53. else:
  54. return str(expression)
  55. def query_from_dict(db, query, out='Query'):
  56. """Builds gluon.dal.Query from dictionary structure.
  57. Args:
  58. db: gluon.dal.db object
  59. query: A dictionary in the form {op:op, first:expression, second:expression}
  60. as returned by query_as_dict()
  61. out: Set to 'Expression' for gluon.dal.Expression
  62. rather than Query.
  63. Returns:
  64. gluon.dal.Query or gluon.dal.Expression object
  65. """
  66. from gluon.dal import Expression, Query
  67. if out == 'Expression':
  68. out_class = Expression
  69. else:
  70. out_class = Query
  71. if type(query) == dict:
  72. if 'op' in query.keys():
  73. first = query_from_dict(db, query['first'], out=out)
  74. second = query_from_dict(db, query['second'], out=out)
  75. op = getattr(db._adapter, query['op'])
  76. return out_class(db, op, first=first, second=second)
  77. elif 'fieldname' in query.keys():
  78. if query['tablename'] == query['table']:
  79. return db[query['tablename']][query['fieldname']]
  80. else: # a table.field with alias
  81. return db[query['table']].with_alias(query['tablename'])[query['fieldname']]
  82. elif 'tablename' in query.keys():
  83. if query['tablename'] == query['table']:
  84. return db[query['tablename']]
  85. elif ' AS ' in query['table']: # a table with alias
  86. t = query['table'].split(' ')[0]
  87. return db[t].with_alias(query['tablename'])
  88. else:
  89. raise ValueError
  90. else:
  91. return query
  92. def process_views(views):
  93. import re
  94. from itertools import groupby
  95. pattern = re.compile('(\w+).(\w+)')
  96. keyfunc = lambda x: x[0]
  97. grouped_views = {}
  98. for view_name, sensors in views.iteritems():
  99. slist = []
  100. for sensor in sensors:
  101. m = pattern.match(sensor)
  102. slist.append((m.group(1), m.group(2)))
  103. sgroups = []
  104. for table, sgroup in groupby(slist, keyfunc):
  105. sgroups.append((table, [s[1] for s in sgroup]))
  106. grouped_views[view_name] = sgroups
  107. return grouped_views