Browse Source

Finish the new version of migrationhandler + modifications in leFactory and LeRelation (to handle generic lesup & lesub in LeRelation)

Yann Weber 9 years ago
parent
commit
146c0fd69b
3 changed files with 45 additions and 13 deletions
  1. 26
    5
      DataSource/MySQL/migrationhandler.py
  2. 13
    0
      leapi/lefactory.py
  3. 6
    8
      leapi/lerelation.py

+ 26
- 5
DataSource/MySQL/migrationhandler.py View File

@@ -197,7 +197,7 @@ class MysqlMigrationHandler(DummyMigrationHandler):
197 197
         emclass = em.component(uid)
198 198
         if not isinstance(emclass, EditorialModel.classes.EmClass):
199 199
             raise ValueError("The given uid is not an EmClass uid")
200
-        pkname, pktype = self._common_field_pk
200
+        pkname, pktype = self._object_pk
201 201
         table_name = self._emclass2table_name(emclass)
202 202
         self._create_table(table_name, pkname, pktype, engine=engine)
203 203
 
@@ -281,7 +281,7 @@ class MysqlMigrationHandler(DummyMigrationHandler):
281 281
         if_exists = 'drop' if drop_if_exist else 'nothing'
282 282
         #Object table
283 283
         tname = utils.common_tables['object']
284
-        pk_name, pk_ftype = self._common_field_pk
284
+        pk_name, pk_ftype = self._object_pk
285 285
         self._create_table(tname, pk_name, pk_ftype, engine=self.db_engine, if_exists=if_exists)
286 286
         #Adding columns
287 287
         cols = {fname: self._common_field_to_ftype(fname) for fname in EditorialModel.classtypes.common_fields}
@@ -290,6 +290,7 @@ class MysqlMigrationHandler(DummyMigrationHandler):
290 290
                 self._add_column(tname, fname, ftype)
291 291
         #Creating triggers
292 292
         self._generate_triggers(tname, cols)
293
+        object_tname = tname
293 294
 
294 295
         #Relation table
295 296
         tname = utils.common_tables['relation']
@@ -301,6 +302,25 @@ class MysqlMigrationHandler(DummyMigrationHandler):
301 302
         #Creating triggers
302 303
         self._generate_triggers(tname, self._relation_cols)
303 304
 
305
+        # Creating foreign keys between relation and object table
306
+        sup_cname, sub_cname = self.get_sup_and_sub_cols()
307
+        self._add_fk(tname, object_tname, sup_cname, self._object_pk[0], 'fk_relations_superiors')
308
+        self._add_fk(tname, object_tname, sub_cname, self._object_pk[0], 'fk_relations_subordinate')
309
+    
310
+    ## @brief Returns the fieldname for superior and subordinate in relation table
311
+    # @return a tuple (superior_name, subordinate_name)
312
+    @classmethod
313
+    def get_sup_and_sub_cols(cls):
314
+        sup = None
315
+        sub = None
316
+        for fname, finfo in EditorialModel.classtypes.relations_common_fields.items():
317
+            if finfo['fieldtype'] == 'leo':
318
+                if finfo['superior']:
319
+                    sup = fname
320
+                else:
321
+                    sub = fname
322
+        return utils.column_name(sup),utils.column_name(sub)
323
+
304 324
     ## @return true if the name changes
305 325
     def _name_change(self, initial_state, new_state):
306 326
         return 'name' in initial_state and initial_state['name'] != new_state['name']
@@ -377,13 +397,14 @@ ADD COLUMN {col_name} {col_type} {col_specs};"""
377 397
     # @param dst_table_name str : The name of the table the FK will point on
378 398
     # @param src_col_name str : The name of the concerned column in the src_table
379 399
     # @param dst_col_name str : The name of the concerned column in the dst_table
380
-    def _add_fk(self, src_table_name, dst_table_name, src_col_name, dst_col_name):
400
+    def _add_fk(self, src_table_name, dst_table_name, src_col_name, dst_col_name, fk_name = None):
381 401
         stname = utils.escape_idname(src_table_name)
382 402
         dtname = utils.escape_idname(dst_table_name)
383 403
         scname = utils.escape_idname(src_col_name)
384 404
         dcname = utils.escape_idname(dst_col_name)
385 405
 
386
-        fk_name = utils.get_fk_name(src_table_name, dst_table_name)
406
+        if fk_name is None:
407
+            fk_name = utils.get_fk_name(src_table_name, dst_table_name)
387 408
 
388 409
         self._del_fk(src_table_name, dst_table_name)
389 410
 
@@ -530,7 +551,7 @@ FOR EACH ROW SET {col_val_list};""".format(
530 551
 
531 552
     ## @brief Returns a tuple (pkname, pk_ftype)
532 553
     @property
533
-    def _common_field_pk(self):
554
+    def _object_pk(self):
534 555
         return self.extract_pk(EditorialModel.classtypes.common_fields)
535 556
 
536 557
     ## @brief Returns a tuple (rel_pkname, rel_ftype)

+ 13
- 0
leapi/lefactory.py View File

@@ -221,6 +221,15 @@ import %s
221 221
         """
222 222
         #Building the fieldtypes dict for LeRelation
223 223
         (lerel_uid_fieldtype, lerel_fieldtypes) = self.concret_fieldtypes(EditorialModel.classtypes.relations_common_fields)
224
+        # Fetching superior and subordinate fieldname for LeRelation
225
+        lesup = None
226
+        lesub = None
227
+        for fname, finfo in EditorialModel.classtypes.relations_common_fields.items():
228
+            if finfo['fieldtype'] == 'leo':
229
+                if finfo['superior']:
230
+                    lesup = fname
231
+                else:
232
+                    lesub = fname
224 233
         """
225 234
         lerel_fieldtypes = list()
226 235
         lerel_uid_fieldtype = None
@@ -252,6 +261,8 @@ class LeObject(LeCrud, leapi.leobject._LeObject):
252 261
 class LeRelation(LeCrud, leapi.lerelation._LeRelation):
253 262
     _uid_fieldtype = {lerel_uid_fieldtype}
254 263
     _rel_fieldtypes = {lerel_fieldtypes}
264
+    _lesup_name = {lesup_name}
265
+    _lesub_name = {lesub_name}
255 266
 
256 267
 class LeHierarch(LeRelation, leapi.lerelation._LeHierarch):
257 268
     pass
@@ -272,6 +283,8 @@ class LeType(LeClass, _LeType):
272 283
             leo_fieldtypes = '{\n\t' + (',\n\t'.join(leobj_fieldtypes))+ '\n\t}',
273 284
             lerel_fieldtypes = '{\n\t' + (',\n\t'.join(lerel_fieldtypes))+ '\n\t}',
274 285
             lerel_uid_fieldtype = lerel_uid_fieldtype,
286
+            lesup_name = repr(lesup),
287
+            lesub_name = repr(lesub),
275 288
         )
276 289
 
277 290
         emclass_l = model.components(EditorialModel.classes.EmClass)

+ 6
- 8
leapi/lerelation.py View File

@@ -11,10 +11,8 @@ from . import lefactory
11 11
 ## @brief Main class for relations
12 12
 class _LeRelation(lecrud._LeCrud):
13 13
 
14
-    ## @brief Handles the superior
15
-    _lesup_fieldtype = {'lesup': ft_leo.EmFieldType(True)}
16
-    ## @brief Handles the subordinate
17
-    _lesub_fieldtype = {'lesub': ft_leo.EmFieldType(False) }
14
+    _lesup_name = None
15
+    _lesub_name = None
18 16
     ## @brief Stores the list of fieldtypes that are common to all relations
19 17
     _rel_fieldtypes = dict()
20 18
 
@@ -25,13 +23,13 @@ class _LeRelation(lecrud._LeCrud):
25 23
     @classmethod
26 24
     def sup_filter(self, leo):
27 25
         if isinstance(leo, leobject._LeObject):
28
-            return ('lesup', '=', leo)
26
+            return (self._lesup_name, '=', leo)
29 27
 
30 28
     ## @brief Forge a filter to match the superior
31 29
     @classmethod
32 30
     def sub_filter(self, leo):
33 31
         if isinstance(leo, leobject._LeObject):
34
-            return ('lesub', '=', leo)
32
+            return (self._lesub_name, '=', leo)
35 33
 
36 34
     ## @return a dict with field name as key and fieldtype instance as value
37 35
     @classmethod
@@ -60,7 +58,7 @@ class _LeRelation(lecrud._LeCrud):
60 58
         filters, rel_filters = super()._prepare_filters(filters_l)
61 59
         res_filters = list()
62 60
         for field, op, value in filters:
63
-            if field in ['lesup', 'lesub']:
61
+            if field in [self._lesup_name, self._lesub_name]:
64 62
                 if isinstance(value, str):
65 63
                     try:
66 64
                         value = int(value)
@@ -162,7 +160,7 @@ class _LeRel2Type(_LeRelation):
162 160
             datas['nature'] = None
163 161
         if cls == cls.name2class('LeRel2Type') and classname is None:
164 162
             # autodetect the rel2type child class
165
-            classname = relname(datas['lesup'], datas['lesub'])
163
+            classname = relname(datas[self._lesup_name], datas[self._lesub_name])
166 164
         return super().insert(datas, classname)
167 165
 
168 166
     ## @brief Given a superior and a subordinate, returns the classname of the give rel2type

Loading…
Cancel
Save