Browse Source

Upgrade the EmClass.check() method making it detect inconsistency between EmClass fields and common_fields defines in EditorialModel.classtypes

Note : the check method does not correct the EmFields only displays a warning
Yann Weber 9 years ago
parent
commit
a56bb65c94
3 changed files with 47 additions and 2 deletions
  1. 38
    2
      EditorialModel/classes.py
  2. 3
    0
      EditorialModel/classtypes.py
  3. 6
    0
      EditorialModel/fields.py

+ 38
- 2
EditorialModel/classes.py View File

@@ -5,6 +5,10 @@
5 5
 
6 6
 import copy
7 7
 
8
+# imports used in classtypes <-> actual model checks
9
+import difflib
10
+import warnings
11
+
8 12
 import EditorialModel
9 13
 from EditorialModel.components import EmComponent
10 14
 from EditorialModel.classtypes import EmClassType
@@ -31,10 +35,42 @@ class EmClass(EmComponent):
31 35
         self.sortcolumn = sortcolumn  # 'rank'
32 36
         super(EmClass, self).__init__(model=model, uid=uid, name=name, string=string, help_text=help_text, date_update=date_update, date_create=date_create, rank=rank)
33 37
 
34
-    ## Check if the EmComponent is valid
35
-    # @note this function add default and common fields to the EmClass if they are not yet created
38
+    ## @brief Check if the EmComponent is valid
39
+    # 
40
+    # This function add default and common fields to the EmClass if they are not yet created (and raises warning if existing common fields are outdated given the one describe in EditorialModel.classtypes
36 41
     # @throw EmComponentCheckError if fails
42
+    # 
43
+    # @warning If default parameters of EmField constructor changes this method can be broken
37 44
     def check(self):
45
+        # Checks that this class is up to date given the common_fields described in EditorialModel.classtypes
46
+        # if not just print a warning, don't raise an Exception
47
+        for field in self.fields():
48
+            if field.name in EditorialModel.classtypes.common_fields:
49
+                # Building fieltypes options to match the ones stored in EditorialModel.classtypes
50
+                ftype_opts = field.fieldtype_options()
51
+                ftype_opts['fieldtype'] = field.fieldtype
52
+
53
+                ctype_opts = EditorialModel.classtypes.common_fields[field.name]
54
+                #Adding default value for options nullable, uniq and internal to fieldtypes options stored in classtypes
55
+                defaults = { 'nullable': False, 'uniq': False, 'internal': False}
56
+                for opt_name, opt_val in defaults.items():
57
+                    if opt_name not in ctype_opts:
58
+                        ctype_opts[opt_name] = opt_val
59
+
60
+                if ftype_opts != ctype_opts:
61
+                    # If options mismatch produce a diff and display a warning
62
+                    ctype_opts = [ "%s: %s\n"%(repr(k), repr(ctype_opts[k])) for k in sorted(ctype_opts.keys())]
63
+                    ftype_opts = [ "%s: %s\n"%(repr(k), repr(ftype_opts[k])) for k in sorted(ftype_opts.keys())]
64
+
65
+                    diff_list = difflib.unified_diff(
66
+                        ctype_opts,
67
+                        ftype_opts, 
68
+                        fromfile="Classtypes.%s" % field.name,
69
+                        tofile="CurrentModel_%s.%s" % (self.name, field.name)
70
+                    )
71
+                    diff = ''.join(diff_list)
72
+                    warnings.warn("LOADED MODEL IS OUTDATED !!! The common_fields defined in classtypes differs from the fields in this model.\nHere is a diff : \n%s" % diff)
73
+            
38 74
         for fname in self.default_fields_list().keys():
39 75
             if fname not in [f.name for f in self.fields()]:
40 76
                 self.model.add_default_class_fields(self.uid)

+ 3
- 0
EditorialModel/classtypes.py View File

@@ -9,15 +9,18 @@ common_fields = {
9 9
     'class_id': {
10 10
         'fieldtype': 'emuid',
11 11
         'is_id_class': True,
12
+        'internal': 'automatic',
12 13
     },
13 14
     'type_id': {
14 15
         'fieldtype': 'emuid',
15 16
         'is_id_class': False,
17
+        'internal': 'automatic',
16 18
     },
17 19
     'string': {
18 20
         'fieldtype': 'char',
19 21
         'max_length': 128,
20 22
         'internal': 'automatic',
23
+        'nullable': True,
21 24
     },
22 25
     'creation_date': {
23 26
         'fieldtype': 'datetime',

+ 6
- 0
EditorialModel/fields.py View File

@@ -1,5 +1,6 @@
1 1
 #-*- coding: utf-8 -*-
2 2
 
3
+import copy
3 4
 import importlib
4 5
 import warnings
5 6
 
@@ -87,6 +88,11 @@ class EmField(EmComponent):
87 88
     @property
88 89
     def em_class(self):
89 90
         return self.model.component(self.class_id)
91
+    
92
+    ## @brief Getter for private property EmField._fieldtype_args
93
+    # @return A copy of private dict _fieldtype_args
94
+    def fieldtype_options(self):
95
+        return copy.copy(self._fieldtype_args)
90 96
 
91 97
     ## @brief Get the fieldtype instance
92 98
     # @return a fieldtype instance

Loading…
Cancel
Save