analyze_subqueries
[unfold.git] / engine / manifoldquery.py
1 import json
2
3 # xxx php has uniqid, need to find a module for that
4 counter=1
5 def uniqid (): global counter; counter += 1; return counter
6
7 class ManifoldQuery:
8
9     def __init__ (self, action=None, method=None, timestamp='now',
10                   filters=[], params=[], fields=[],
11                   sort=None, limit=None, offset=None,
12                   ):
13         self.uuid=uniqid()
14         # settable
15         self.action=action
16         self.method=method
17         self.timestamp=timestamp
18         self.filters=filters
19         self.params=params
20         self.fields=fields
21         self.sort=sort
22         self.limit=limit
23         self.offset=offset
24         # internal data
25         self.analyzed_query=None
26         self.subqueries = {}
27
28     def to_json (self):
29         uuid=self.uuid
30         a=self.action
31         m=self.method
32         t=self.timestamp
33         f=json.dumps (self.filters)
34         p=json.dumps (self.params)
35         c=json.dumps (self.fields)
36         # xxx unique can be removed, but for now we pad the js structure
37         unique=0
38
39         aq = self.analyzed_query.to_json() if self.analyzed_query else 'null'
40         # subqueries is a dictionary method:query
41         if not self.subqueries: 
42             sq="{}"
43         else:
44             sq=", ".join ( [ "'%s':%s" % (method, subquery.to_json())
45                       for (method, subquery) in self.subqueries.iteritems()])
46             sq="{%s}"%sq
47         
48         return """ new Query('%(a)s', '%(m)s', '%(t)s', %(f)s, %(p)s, %(c)s, %(unique)s, '%(uuid)s', %(aq)s, %(sq)s)"""%locals()
49     
50     # 4amine
51     # xxx
52     # this should build an object from a dict as received from javascript
53     # to see an example just look at the server's output
54     # incoming POST <QueryDict: {u'query[method]': [u'slice'], u'query[fields][]': [u'slice_hrn'], u'query[timestamp]': [u'latest'], u'query[action]': [u'get']}>
55     def fill_from_dict (self, d):
56         for key in d.keys():
57            for arg in ['action', 'method', 'filters', 'fields', 'timestamp', 'params']:
58                 if arg in key:
59                     # dirty hack around fields; fields must be a list
60                     if arg == 'fields': 
61                         setattr(self, arg, [d[key]])
62                     else: 
63                         setattr(self, arg, d[key])
64                     break
65
66
67
68     def analyze_subqueries(self):
69         analyzed_query = ManifoldQuery()
70         analyzed_query.uuid = self.uuid
71         analyzed_query.action = self.action
72         analyzed_query.method = self.method
73         analyzed_query.timestamp = self.timestamp
74
75         # analyse query filters
76         # filter syntax : ['key', 'oparation', 'value']
77         for filter in self.filters:
78             key = filter[0]
79             operation = filter[1]
80             value = filter[2]
81             if '.' in key:
82                 method = key.split('.')[0]
83                 field = key.split('.')[1]
84                 if not analyzed_query.subqueries[method]:
85                     subquery = ManifoldQuery()
86                     subquery.action = self.action
87                     subquery.method = method
88                     subquery.timestamp = self.timestamp
89                     analyzed_query.subqueries[method] = subquery
90
91                 analyzed_query.subqueries[method].filters.append([field, operation, value])
92             else:
93                 analyzed_query.filters.append(filter)
94
95         # analyse query params
96         # params syntax : params = {'param1': value1, 'param2': value2, ...}
97         for param in self.params.keys():
98             if '.' in param:
99                 method = param.split('.')[0]
100                 field = param.split('.')[1]
101                 if not analyzed_query.subqueries[method]:
102                     subquery = ManifoldQuery()
103                     subquery.action = self.action
104                     subquery.method = method
105                     subquery.timestamp = self.timestamp
106                     analyzed_query.subqueries[method] = subquery
107
108                 analyzed_query.subqueries[method].params[field] = self.params[param]
109             else:
110                 analyzed_query.params[param] = self.params[param]
111
112         # analyse query fields
113         # fields syntax: fields = [element1, element2, ....]
114         for element in self.fields:
115             if '.' in element:
116                 method = element.split('.')[0]
117                 field = element.split('.')[1]
118                 if not analyzed_query.subqueries[method]:
119                     subquery = ManifoldQuery()
120                     subquery.action = self.action
121                     subquery.method = method
122                     subquery.timestamp = self.timestamp
123                     analyzed_query.subqueries[method] = subquery
124
125                 analyzed_query.subqueries[method].fields.append(field)
126             else:
127                 analyzed_query.fields.append(element)        
128
129
130         # default subqueries 
131         if analyzed_query.method == 'slice':
132             if not analyzed_query.subqueries['resource']:
133                 subquery = ManifoldQuery()
134                 subquery.action = self.action
135                 subquery.method = method
136                 subquery.timestamp = self.timestamp
137                 analyzed_query.subqueries['resource'] = subquery
138
139             if not analyzed_query.subqueries['lease']:
140                 subquery = ManifoldQuery()
141                 subquery.action = self.action
142                 subquery.method = method
143                 subquery.timestamp = self.timestamp
144                 analyzed_query.subqueries['lease'] = subquery
145
146
147         self.analyzed_query = analyzed_query