Browse Source

Reimplementig EmComponent::__setattr__ to call migration handler

Addding a method to indicate the end of a component initialisation phase (used in Model.load and Model.create_component)
Adding a method that dump component attributes (used in Model.create_component and Model.delete_component to call the migration_handler)
Yann Weber 9 years ago
parent
commit
fe9184f608

+ 18
- 1
EditorialModel/components.py View File

@@ -45,9 +45,26 @@ class EmComponent(object):
45 45
 
46 46
         #Handling specials ranks for component creation
47 47
         self.rank = rank
48
-
49 48
         pass
50 49
 
50
+    @property
51
+    ## @brief Return a dict with attributes name as key and attributes value as value
52
+    # @note Used at creation and deletion to call the migration handler
53
+    def attr_dump(self):
54
+        return { fname : fval for fname, fval in self.__dict__.items() if not fname.startswith('__') }
55
+        
56
+    ## @brief This function has to be called after the instanciation, checks, and init manipulations are done
57
+    # @note Create a new attribute _inited that allow __setattr__ to know if it has or not to call the migration handler
58
+    def init_ended(self):
59
+        self._inited = True
60
+
61
+    ## @brief Reimplementation for calling the migration handler to register the change
62
+    def __setattr__(self, attr_name, value):
63
+        if '_inited' in self.__dict__:
64
+            # if fails raise MigrationHandlerChangeError
65
+            self.model.migration_handler.register_change(self.uid, {attr_name: getattr(self, attr_name) }, {attr_name: value} )
66
+        super(EmComponent, self).__setattr__(attr_name, value)
67
+
51 68
     ## Check the type of attribute named var_name
52 69
     # @param var_name str : the attribute name
53 70
     # @param excepted_type tuple|type : Tuple of type or a type 

+ 3
- 0
EditorialModel/exceptions.py View File

@@ -17,3 +17,6 @@ class EmComponentRankingNotExistError(Exception):
17 17
 ## @brief An exception class to return a failure reason for EmComponent.check() method
18 18
 class EmComponentCheckError(Exception):
19 19
     pass
20
+
21
+class MigrationHandlerChangeError(Exception):
22
+    pass

+ 29
- 4
EditorialModel/migrationhandler/dummy.py View File

@@ -2,13 +2,38 @@
2 2
 
3 3
 ## Manage Model changes
4 4
 class DummyMigrationHandler(object):
5
+
6
+    def __init__(self, debug = False):
7
+        self.debug = debug
5 8
     
6 9
     ## @brief Record a change in the EditorialModel and indicate wether or not it is possible to make it
7 10
     # @note The states ( initial_state and new_state ) contains only fields that changes
8 11
     # @param uid int : The uid of the change EmComponent
9
-    # @param initial_state dict : dict with field name as key and field value as value representing the original state
10
-    # @param new_state dict : dict with field name as key and field value as value representing the new state
11
-    # @return True if the modification is allowed False if not.
12
+    # @param initial_state dict | None : dict with field name as key and field value as value. Representing the original state. None mean creation of a new component.
13
+    # @param new_state dict | None : dict with field name as key and field value as value. Representing the new state. None mean component deletion
14
+    # @throw EditorialModel.exceptions.MigrationHandlerChangeError if the change was refused
12 15
     def register_change(self, uid, initial_state, new_state):
13
-        return True
16
+        if self.debug:
17
+            print("\n##############")
18
+            print("DummyMigrationHandler debug. Changes for component with uid %d :"%uid)
19
+            if initial_state is None:
20
+                print("Component creation (uid = %d): \n\t"%uid,new_state)
21
+            elif new_state is None:
22
+                print("Component deletion (uid = %d): \n\t"%uid,initial_state)
23
+            else:
24
+                field_list = set(initial_state.keys()).union(set(new_state.keys()))
25
+                for field_name in field_list:
26
+                    str_chg = "\t%s "%field_name
27
+                    if field_name in initial_state:
28
+                        str_chg += "'"+str(initial_state[field_name])+"'"
29
+                    else:
30
+                        str_chg += " creating "
31
+                    str_chg += " => "
32
+                    if field_name in new_state:
33
+                        str_chg += "'"+str(new_state[field_name])+"'"
34
+                    else:
35
+                        str_chg += " deletion "
36
+                    print(str_chg)
37
+            print("##############\n")
38
+        pass
14 39
         

+ 13
- 0
EditorialModel/model.py View File

@@ -75,6 +75,8 @@ class Model(object):
75 75
                 component.check()
76 76
             except EmComponentCheckError as e:
77 77
                 raise EmComponentCheckError("The component with uid %d is not valid. Check returns the following error : \"%s\"" % (uid, str(e)))
78
+            #Everything is done. Indicating that the component initialisation is over
79
+            component.init_ended()
78 80
 
79 81
     ## Saves data using the current backend
80 82
     def save(self):
@@ -115,6 +117,7 @@ class Model(object):
115 117
     # @param component_type str : a component type ( component_class, component_fieldgroup, component_field or component_type )
116 118
     # @param datas dict : the options needed by the component creation
117 119
     # @throw ValueError if datas['rank'] is not valid (too big or too small, not an integer nor 'last' or 'first' )
120
+    # @todo Handle a raise from the migration handler
118 121
     def create_component(self, component_type, datas):
119 122
         
120 123
         em_obj = self.emclass_from_name(component_type)
@@ -134,13 +137,23 @@ class Model(object):
134 137
         if rank != 'last':
135 138
             em_component.set_rank( 1 if rank == 'first' else rank)
136 139
 
140
+        #everything done, indicating that initialisation is over
141
+        em_component.init_ended()
142
+
143
+        #register the creation in migration handler
144
+        self.migration_handler.register_change(em_component.uid, None, em_component.attr_dump)
145
+
137 146
         return em_component
138 147
 
139 148
     ## Delete a component
140 149
     # @param uid int : Component identifier
141 150
     # @throw EditorialModel.components.EmComponentNotExistError
142 151
     # @todo unable uid check
152
+    # @todo Handle a raise from the migration handler
143 153
     def delete_component(self, uid):
154
+        #register the deletion in migration handler
155
+        self.migration_handler.register_change(uid, self.component(uid).attr_dump, None)
156
+
144 157
         if uid not in self._components[uid]:
145 158
             raise EditorialModel.components.EmComponentNotExistError()
146 159
         em_component = self._components[uid]

Loading…
Cancel
Save