Browse Source

Merge branch 'newlodel' of git.labocleo.org:lodel2 into newlodel

Yann Weber 9 years ago
parent
commit
cc578d504d
1 changed files with 92 additions and 5 deletions
  1. 92
    5
      lodel/leapi/query.py

+ 92
- 5
lodel/leapi/query.py View File

@@ -1,6 +1,8 @@
1 1
 #-*- coding: utf-8 -*-
2 2
 
3
-from .leobject import LeObject, LeApiErrors
3
+import re
4
+from .leobject import LeObject, LeApiErrors, LeApiDataCheckError
5
+
4 6
 
5 7
 class LeQueryError(Exception):
6 8
     pass
@@ -55,6 +57,9 @@ class LeFilteredQuery(LeQuery):
55 57
                 raise LeQueryError("The operator %s is not valid." % query_filter[1])
56 58
         return True
57 59
 
60
+    @classmethod
61
+    def is_relational_field(cls, field):
62
+        return field.startswith('superior.') or field.startswith('subordinate.')
58 63
 
59 64
 class LeGetQuery(LeFilteredQuery):
60 65
 
@@ -79,6 +84,8 @@ class LeGetQuery(LeFilteredQuery):
79 84
     def __get(self, **kwargs):
80 85
         field_list = self.__prepare_field_list(self.field_list)  #TODO implement the prepare_field_list method
81 86
 
87
+        query_filters, relational_filters = self.__prepare_filters()
88
+
82 89
         # Preparing order
83 90
         if self.order:
84 91
             order = self.__prepare_order()
@@ -102,10 +109,87 @@ class LeGetQuery(LeFilteredQuery):
102 109
         return results
103 110
 
104 111
     def __prepare_field_list(self):
105
-        pass
112
+        errors = dict()
113
+        ret_field_list = list()
114
+        for field in self.field_list:
115
+            if self.is_relational(field):
116
+                ret = self.__prepare_relational_fields(field)
117
+            else:
118
+                ret = self.__check_field(field)
119
+
120
+            if isinstance(ret, Exception):
121
+                errors[field] = ret
122
+            else:
123
+                ret_field_list.append(ret)
124
+
125
+        if len(errors) > 0:
126
+            raise LeApiDataCheckError(errors)
127
+
128
+        return ret_field_list
129
+
130
+    def __prepare_relational_fields(self, field):
131
+        # TODO Implement the method
132
+        return field
133
+
134
+    def __split_filter(self, filter):
135
+        if self.query_re is None:
136
+            self.__compile_query_re()
137
+
138
+        matches = self.query_re.match(filter)
139
+        if not matches:
140
+            raise ValueError("The query_filter '%s' seems to be invalid" % filter)
141
+
142
+        result = (matches.group('field'), re.sub(r'\s', ' ', matches.group('operator')), matches.group('value').strip())
143
+        for r in result:
144
+            if len(r) == 0:
145
+                raise ValueError("The query_filter '%s' seems to be invalid" % filter)
146
+
147
+        return result
148
+
149
+    def __compile_query_re(self):
150
+        op_re_piece = '(?P<operator>(%s)' % self._query_operators[0].replace(' ', '\s')
151
+        for operator in self._query_operators[1:]:
152
+            op_re_piece += '|(%s)' % operator.replace(' ', '\s')
153
+        op_re_piece += ')'
154
+        self.query_re = re.compile('^\s*(?P<field>(((superior)|(subordinate))\.)?[a-z_][a-z0-9\-_]*)\s*'+op_re_piece+'\s*(?P<value>[^<>=!].*)\s*$', flags=re.IGNORECASE)
155
+
156
+    def __check_field(self, target_object, field):
157
+        if field not in self.target_object.fieldnames():
158
+            return ValueError("No such field '%s' in %s" % (field, self.target_object.__class__))
159
+        return field
106 160
 
107 161
     def __prepare_filters(self):
108
-        pass
162
+        filters = list()
163
+        errors = dict()
164
+        res_filters = list()
165
+        rel_filters = list()
166
+
167
+        # Splitting in tuple if necessary
168
+        for filter in self.query_filters:
169
+            if len(filter) == 3 and not isinstance(filter, str):
170
+                filters.append(tuple(filter))
171
+            else:
172
+                filters.append(self.__split_filter(filter))
173
+
174
+        for field, operator, value in filters:
175
+            # TODO check the relation filters
176
+            ret = self.__check_field(self.target_object, field)
177
+            if isinstance(ret, Exception):
178
+                errors[field] = ret
179
+            else:
180
+                res_filters.append((ret, operator, value))
181
+
182
+        if len(errors) > 0:
183
+            raise LeApiDataCheckError("Error while preparing filters : ", errors)
184
+
185
+        return (res_filters, rel_filters)
186
+
187
+
188
+        datas = dict()
189
+        if LeFilteredQuery.validate_query_filters(self.query_filters):
190
+            datas['query_filters'] = self.query_filters
191
+        datas['target_object'] = self.target_object
192
+        return datas
109 193
 
110 194
     def __prepare_order(self):
111 195
         errors = dict()
@@ -155,7 +239,7 @@ class LeUpdateQuery(LeFilteredQuery):
155 239
     ## @brief prepares the query_filters to be used as argument for the datasource's update method
156 240
     def __prepare(self):
157 241
         datas = dict()
158
-        if super().validate_query_filters(self.query_filters):
242
+        if LeFilteredQuery.validate_query_filters(self.query_filters):
159 243
             datas['query_filters'] = self.query_filters
160 244
 
161 245
         datas['target_uid'] = self.target_uid
@@ -176,6 +260,9 @@ class LeDeleteQuery(LeFilteredQuery):
176 260
         # ret = LodelHook.call('leapi_delete_post', self.target_object, ret)
177 261
         return ret
178 262
 
263
+    ## @brief calls the datasource's delete method
264
+    # @return bool
265
+    # @TODO change the behavior in case of error in the update process
179 266
     def __delete(self):
180 267
         delete_datas = self.__prepare()
181 268
         ret = self._datasource.delete(**delete_datas)
@@ -183,7 +270,7 @@ class LeDeleteQuery(LeFilteredQuery):
183 270
 
184 271
     def __prepare(self):
185 272
         datas = dict()
186
-        if super().validate_query_filters(self.query_filters):
273
+        if LeFilteredQuery.validate_query_filters(self.query_filters):
187 274
             datas['query_filters'] = self.query_filters
188 275
 
189 276
         datas['target_uid'] = self.target_uid

Loading…
Cancel
Save