cosmetic
[myslice.git] / manifold / manifoldquery.py
1 import json
2 import uuid
3
4 def uniqid (): 
5     return uuid.uuid4().hex
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.query_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 __repr__ (self):
29         result="Q: id=%(query_uuid)s - %(action)s on %(method)s "%self.__dict__
30         result += " with %d filters, %d fields"%(len(self.filters),len(self.params))
31         return result
32
33     def to_json (self):
34         query_uuid=self.query_uuid
35         a=self.action
36         m=self.method
37         t=self.timestamp
38         f=json.dumps (self.filters)
39         p=json.dumps (self.params)
40         c=json.dumps (self.fields)
41         # xxx unique can be removed, but for now we pad the js structure
42         unique=0
43
44         aq = self.analyzed_query.to_json() if self.analyzed_query else 'null'
45         # subqueries is a dictionary method:query
46         if not self.subqueries: 
47             sq="{}"
48         else:
49             sq=", ".join ( [ "'%s':%s" % (method, subquery.to_json())
50                       for (method, subquery) in self.subqueries.iteritems()])
51             sq="{%s}"%sq
52         
53         return """ new ManifoldQuery('%(a)s', '%(m)s', '%(t)s', %(f)s, %(p)s, %(c)s, %(unique)s, '%(query_uuid)s', %(aq)s, %(sq)s)"""%locals()
54     
55     # this builds a ManifoldQuery object from a dict as received from javascript through its ajax request 
56     # e.g. here's what I captured from the server's output
57     # incoming POST <QueryDict: {u'query[method]': [u'slice'], u'query[fields][]': [u'slice_hrn'], u'query[timestamp]': [u'latest'], u'query[action]': [u'get']}>
58     def fill_from_dict (self, d):
59         for key in d.keys():
60             for arg in ['action', 'method', 'filters', 'fields', 'timestamp', 'params']:
61                 if arg in key:
62                     # dirty hack around fields; fields must be a list
63                     if arg == 'fields': 
64                         setattr(self, arg, [d[key]])
65                     else: 
66                         setattr(self, arg, d[key])
67                     break
68
69     # not used yet ..
70     def analyze_subqueries(self):
71         analyzed_query = ManifoldQuery()
72         analyzed_query.query_uuid = self.query_uuid
73         analyzed_query.action = self.action
74         analyzed_query.method = self.method
75         analyzed_query.timestamp = self.timestamp
76
77         # analyse query filters
78         # filter syntax : ['key', 'oparation', 'value']
79         for filter in self.filters:
80             key = filter[0]
81             operation = filter[1]
82             value = filter[2]
83             if '.' in key:
84                 method = key.split('.')[0]
85                 field = key.split('.')[1]
86                 if not analyzed_query.subqueries[method]:
87                     subquery = ManifoldQuery()
88                     subquery.action = self.action
89                     subquery.method = method
90                     subquery.timestamp = self.timestamp
91                     analyzed_query.subqueries[method] = subquery
92
93                 analyzed_query.subqueries[method].filters.append([field, operation, value])
94             else:
95                 analyzed_query.filters.append(filter)
96
97         # analyse query params
98         # params syntax : params = {'param1': value1, 'param2': value2, ...}
99         for param in self.params.keys():
100             if '.' in param:
101                 method = param.split('.')[0]
102                 field = param.split('.')[1]
103                 if not analyzed_query.subqueries[method]:
104                     subquery = ManifoldQuery()
105                     subquery.action = self.action
106                     subquery.method = method
107                     subquery.timestamp = self.timestamp
108                     analyzed_query.subqueries[method] = subquery
109
110                 analyzed_query.subqueries[method].params[field] = self.params[param]
111             else:
112                 analyzed_query.params[param] = self.params[param]
113
114         # analyse query fields
115         # fields syntax: fields = [element1, element2, ....]
116         for element in self.fields:
117             if '.' in element:
118                 method = element.split('.')[0]
119                 field = element.split('.')[1]
120                 if not analyzed_query.subqueries[method]:
121                     subquery = ManifoldQuery()
122                     subquery.action = self.action
123                     subquery.method = method
124                     subquery.timestamp = self.timestamp
125                     analyzed_query.subqueries[method] = subquery
126
127                 analyzed_query.subqueries[method].fields.append(field)
128             else:
129                 analyzed_query.fields.append(element)        
130
131
132         # default subqueries 
133         if analyzed_query.method == 'slice':
134             if not analyzed_query.subqueries['resource']:
135                 subquery = ManifoldQuery()
136                 subquery.action = self.action
137                 subquery.method = method
138                 subquery.timestamp = self.timestamp
139                 analyzed_query.subqueries['resource'] = subquery
140
141             if not analyzed_query.subqueries['lease']:
142                 subquery = ManifoldQuery()
143                 subquery.action = self.action
144                 subquery.method = method
145                 subquery.timestamp = self.timestamp
146                 analyzed_query.subqueries['lease'] = subquery
147
148
149         self.analyzed_query = analyzed_query