|
@@ -1,11 +1,15 @@
|
1
|
1
|
#-*- coding: utf-8 -*-
|
2
|
2
|
|
|
3
|
+import copy
|
3
|
4
|
import types
|
4
|
5
|
import importlib
|
5
|
6
|
|
6
|
7
|
class GenericFieldType(object):
|
7
|
8
|
|
8
|
9
|
help_text = 'Generic field type : abstract class for every fieldtype'
|
|
10
|
+
|
|
11
|
+ ## @brief List fields that will be exposed to the construct_data_method
|
|
12
|
+ _construct_datas_deps = []
|
9
|
13
|
|
10
|
14
|
## @param internal False | str : define wheter or not a field is internal
|
11
|
15
|
# @throw NotImplementedError if called from bad class
|
|
@@ -35,15 +39,22 @@ class GenericFieldType(object):
|
35
|
39
|
def _check_data_value(self, value):
|
36
|
40
|
return (value, None)
|
37
|
41
|
|
|
42
|
+ ## @brief Wrapper for _construct_data() method
|
|
43
|
+ #
|
|
44
|
+ # Now useless
|
|
45
|
+ def construct_data(self, lec, fname, datas, cur_value):
|
|
46
|
+ return self._construct_data(lec, fname, datas, cur_value)
|
|
47
|
+
|
38
|
48
|
## @brief Build field value
|
39
|
49
|
# @param lec LeCrud : A LeCrud child class
|
40
|
50
|
# @param fname str : The field name
|
41
|
51
|
# @param datas dict : dict storing fields values (from the lec)
|
|
52
|
+ # @param cur_value : the value for the current field (identified by fieldname)
|
42
|
53
|
# @return constructed datas (for the fname field)
|
43
|
54
|
# @throw RuntimeError if unable to construct data
|
44
|
|
- def construct_data(self, lec, fname, datas):
|
45
|
|
- if fname in datas:
|
46
|
|
- return datas[fname]
|
|
55
|
+ def _construct_data(self, lec, fname, datas, cur_value):
|
|
56
|
+ if fname in datas.keys():
|
|
57
|
+ return cur_value
|
47
|
58
|
elif hasattr(lec.fieldtypes()[fname], 'default'):
|
48
|
59
|
return lec.fieldtypes()[fname].default
|
49
|
60
|
elif lec.fieldtypes()[fname].nullable:
|
|
@@ -152,6 +163,41 @@ class MultiValueFieldType(GenericFieldType):
|
152
|
163
|
## stores the fieldtype that handles the values
|
153
|
164
|
self.value_fieldtype = value_fieldtype
|
154
|
165
|
|
|
166
|
+## @brief Class designed to handle datas access will fieldtypes are constructing datas
|
|
167
|
+class DatasConstructor(object):
|
|
168
|
+
|
|
169
|
+ ## @brief Init a DatasConstructor
|
|
170
|
+ # @param lec LeCrud : LeCrud child class
|
|
171
|
+ # @param datas dict : dict with field name as key and field values as value
|
|
172
|
+ # @param fieldtypes dict : dict with field name as key and fieldtype as value
|
|
173
|
+ def __init__(self, lec, datas, fieldtypes):
|
|
174
|
+ ## Stores concerned class
|
|
175
|
+ self._lec = lec
|
|
176
|
+ ## Stores datas and constructed datas
|
|
177
|
+ self._datas = copy.copy(datas)
|
|
178
|
+ ## Stores fieldtypes
|
|
179
|
+ self._fieldtypes = fieldtypes
|
|
180
|
+ ## Stores list of fieldname for constructed datas
|
|
181
|
+ self._constructed = []
|
|
182
|
+ ## Stores construct calls list
|
|
183
|
+ self._construct_calls = []
|
|
184
|
+
|
|
185
|
+ def keys(self):
|
|
186
|
+ return self._datas.keys()
|
|
187
|
+
|
|
188
|
+ def __getitem__(self, fname):
|
|
189
|
+ if fname not in self._constructed:
|
|
190
|
+ if fname in self._construct_calls:
|
|
191
|
+ raise RuntimeError('Probably circular dependencies in fieldtypes')
|
|
192
|
+ cur_value = self._datas[fname] if fname in self._datas else None
|
|
193
|
+ self._datas[fname] = self._fieldtypes[fname].construct_data(self._lec, fname, self, cur_value)
|
|
194
|
+ self._constructed.append(fname)
|
|
195
|
+ return self._datas[fname]
|
|
196
|
+
|
|
197
|
+ def __setitem__(self, fname, value):
|
|
198
|
+ self._datas[fname] = value
|
|
199
|
+
|
|
200
|
+
|
155
|
201
|
#
|
156
|
202
|
#
|
157
|
203
|
# Exceptions
|