Переглянути джерело

More doc + tests fixes and rank fieldtype fix

Yann Weber 8 роки тому
джерело
коміт
cae0377c3d

+ 54
- 3
EditorialModel/fieldtypes/generic.py Переглянути файл

@@ -14,12 +14,15 @@ class GenericFieldType(object):
14 14
     ## @brief List fields that will be exposed to the construct_data_method
15 15
     _construct_datas_deps = []
16 16
 
17
-    ## @param internal False | str : define wheter or not a field is internal
17
+    ## @brief Generic constructor for fieldtypes 
18
+    # @param internal False | str : define wheter or not a field is internal
19
+    # @param immutable bool : indicate if the fieldtype has to be defined in child classes of LeObject or if it is defined globally and immutable
18 20
     # @throw NotImplementedError if called from bad class
19
-    def __init__(self, internal = False, **args):
21
+    def __init__(self, internal = False, immutable = False, **args):
20 22
         if self.__class__ == GenericFieldType:
21 23
             raise NotImplementedError("Abstract class")
22 24
         self.internal = internal #Check this value ?
25
+        self.immutable = bool(immutable)
23 26
     
24 27
         for argname, argval in args.items():
25 28
             setattr(self, argname, argval)
@@ -234,4 +237,52 @@ class FieldTypeDataCheckError(FieldTypeError):
234 237
             msg += "{expt_name}:{expt_msg}; ".format(expt_name=expt.__class__.__name__, expt_msg=str(expt))
235 238
         return msg
236 239
 
237
-
240
+## @page lodel2_fieldtypes Lodel2 fieldtypes
241
+#
242
+# @section fieldtypes_features Main features
243
+#
244
+# Lodel2 defines Class and Types containing fields that handle values.
245
+# Fields are defined by FieldTypes. It's objects that are able to check datas value, to construct values (~cast) and to check datas consistency given the list of datas of an Lodel2 object (Class or Type)
246
+#
247
+# @subsection fieldtypes_hierarchy Fieldtypes family
248
+#
249
+# Fieldtypes are python objects. We use inheritance to defines FieldTypes. Here is a list of main FieldTypes inheritance :
250
+# - GenericFieldType
251
+#  - SingleValueFieldType <- handles a single value
252
+#   - ReferenceFieldType <- handles a reference to another field
253
+#    - leo.EmFieldType <- handles references to a LeObject (designed for LeRelation)
254
+#   - char.EmFieldType <- handles string
255
+#   - integer.EmFieldType <- handles integer
256
+#    - pk.EmFieldType <- handles primary keys (identifier)
257
+#  - MultiValueFieldType <- handles multiple values identified by a key
258
+#   - i18n.EmFieldType <- handles a string and its translations
259
+#
260
+# @subsection fieldtypes_options Fieldtypes main options
261
+#
262
+# There is 2 options that are common for every fieldtypes :
263
+# - internal : that indicate who construct the data. Possible values are
264
+#  - False : the field is not internal, its user that provides datas
265
+#  - 'automatic' : The field is internal, its leapi that provides datas (see construct in @ref fieldtypes_validator )
266
+#  - 'autosql' : BAD NAME. The field is internal but it is the datasource that provide the data
267
+# - immutable : Its a boolean that indicate if a fieldtype defined in EditorialModel.classtypes is immutable or HAVE TO be defined in EmClass
268
+# 
269
+# @subsubsection fieldtypes_options_single_value SingleValueFieldType options
270
+#
271
+# SingleValueFieldType have more standart options :
272
+# - nullable (boolean) : is None allowed as value
273
+# - uniq (boolean) : if True the value has to be uniq in all instances of concerned Lodel2 API object
274
+# - primary (boolean) : if True the field is an identifier (primary key)
275
+# - default : if given as argument defines a default value for the FieldType
276
+#
277
+# @subsection fieldtypes_validator Data validation
278
+#
279
+# For each Lodel2 API objects (LeObject, LeRelation, ...) there is a sequence that is run to check datas and transform them. Each step is run for each fieldtypes of a Lodel2 API object
280
+#
281
+# -# Check data : this is a basic data check (for example if an integer is expected and the string 'foo' is given the check will fails)
282
+# -# Construct data : this is a data 'casting' step, this method is called with all other datas from the Lodel2 API object as argument (to be able to construct datas with other parts of the object) @ref fieldtypes_construct_order
283
+# -# Datas consistency checks : this step, as the construct step, has all datas from the Lodel2 API object as argument, and check for the whole datas consistency
284
+#
285
+# @subsubsection fieldtypes_construct_order Data construction dependencies
286
+#
287
+# To handle data construction dependencies there is an object DatasConstructor able to call the data construction when needed and to detect (not tested yet) circular dependencies
288
+# 

+ 4
- 5
EditorialModel/fieldtypes/rank.py Переглянути файл

@@ -16,13 +16,12 @@ class EmFieldType(integer.EmFieldType):
16 16
         super().__init__(**kwargs)
17 17
 
18 18
     def construct_data(self, lec, fname, datas, cur_value):
19
-        superior_id = datas[EditorialModel.classtypes.relation_superior]
19
+        superior = datas[EditorialModel.classtypes.relation_superior]
20 20
         if lec.is_lerel2type():
21
-            subordinate = lec._subordinate_cls
22
-            sub_em_type_id = subordinate._type_id
23
-            cur_value = lec.get_max_rank(superior_id, sub_em_type_id)
21
+            relation_name = datas[EditorialModel.classtypes.relation_name]
22
+            cur_value = lec.get_max_rank(superior, relation_name)
24 23
         elif lec.is_lehierarch():
25
-            cur_value = lec.get_max_rank(superior_id, datas['nature'])
24
+            cur_value = lec.get_max_rank(superior, datas['nature'])
26 25
         else:
27 26
             raise ValueError("Called with bad class : ", lec.__name__)
28 27
         return cur_value

+ 13
- 9
Lodel/__init__.py Переглянути файл

@@ -4,6 +4,19 @@
4 4
 #
5 5
 # For basics Lodel2 configuration & usage see README.md
6 6
 #
7
+# @tableofcontents
8
+#
9
+# @section mainpage_docs Documentation
10
+#
11
+# - Fieldtypes : @subpage lodel2_fieldtypes
12
+# @subsection mainpage_docs_leapi LeAPI
13
+#
14
+# - LeAPI objects instanciation : @subpage lecrud_instanciation
15
+# - Querying leapi : @subpage api_user_side
16
+#
17
+# @subsection mainpage_docs_configs Lodel2 settings
18
+# - Lodel2 settings handling : @subpage lodel_settings
19
+#
7 20
 # @section mainpage_pkg_list Main packages
8 21
 #
9 22
 # - Lodel
@@ -15,12 +28,3 @@
15 28
 # - DataSource
16 29
 #  - DataSource.MySQL
17 30
 # 
18
-# @section mainpage_docs Dev ressources
19
-#
20
-# @subsection mainpage_docs_leapi LeAPI
21
-#
22
-# - LeAPI objects instanciation : @ref lecrud_instanciation
23
-# - Querying leapi : @ref api_user_side
24
-#
25
-# @subsection mainpage_docs_configs Lodel2 settings
26
-# - Lodel2 settings handling : @ref lodel_settings

+ 16
- 9
leapi/lerelation.py Переглянути файл

@@ -216,17 +216,24 @@ class _LeRel2Type(_LeRelation):
216 216
     # @return True in case of success, False in case of failure
217 217
     # @throw ValueError if step is not castable into an integer
218 218
     def set_rank(self, new_rank):
219
-        return self._set_rank(
220
-                                new_rank,
221
-                                id_superior=getattr(self, self.uidname()),
222
-                                type_em_id=self._subordinate_cls._type_id
223
-        )
219
+        if self._relation_name is None:
220
+            raise NotImplementedError("Abstract method")
221
+        return self._set_rank(new_rank, superior = self.superior, relation_name = self._relation_name)
224 222
 
225 223
     @classmethod
226
-    def get_max_rank(cls, id_superior, type_em_id):
227
-       # SELECT rank FROM relation JOIN object ON object.lodel_id = id_subordinate WHERE object.type_id = <type_em_id>
228
-        warnings.warn("LeRel2Type.get_max_rank() is not implemented yet and will always return 0")
229
-        return 0
224
+    def get_max_rank(cls, superior, relation_name):
225
+        # SELECT rank FROM relation JOIN object ON object.lodel_id = id_subordinate WHERE object.type_id = <type_em_id>
226
+        ret = cls.get(
227
+            query_filters = [
228
+                (EditorialModel.classtypes.relation_name, '=', relation_name),
229
+                (EditorialModel.classtypes.relation_superior, '=', superior),
230
+            ],
231
+            field_list = ['rank'],
232
+            order = [('rank', 'DESC')],
233
+            limit = 1,
234
+            instanciate = False
235
+        )
236
+        return 1 if ret is None else ret[0]['rank']
230 237
 
231 238
     ## @brief Implements insert for rel2type
232 239
     # @todo checks when autodetecing the rel2type class

+ 1
- 1
leapi/test/test_lerelation.py Переглянути файл

@@ -249,7 +249,7 @@ class LeRel2TypeTestCase(LeRelationTestCase):
249 249
             eres = {
250 250
                     'nature': None,
251 251
                     'depth': None,
252
-                    'rank': 0,
252
+                    'rank': 1,
253 253
                     EditorialModel.classtypes.relation_name: None,
254 254
             }
255 255
             eres.update(query)

Loading…
Відмінити
Зберегти