Browse Source

Modified version of migration handler

This commit is full of bugs (in LeRelation etc.)
Yann Weber 8 years ago
parent
commit
54af3da85a
2 changed files with 66 additions and 44 deletions
  1. 58
    44
      DataSource/MySQL/migrationhandler.py
  2. 8
    0
      EditorialModel/classtypes.py

+ 58
- 44
DataSource/MySQL/migrationhandler.py View File

@@ -4,7 +4,11 @@ import copy
4 4
 import pymysql
5 5
 
6 6
 import EditorialModel
7
-from DataSource.MySQL.common_utils import MySQL
7
+import EditorialModel.classtypes
8
+import EditorialModel.fieldtypes
9
+import EditorialModel.fieldtypes.generic
10
+
11
+from DataSource.MySQL import utils
8 12
 from DataSource.dummy.migrationhandler import DummyMigrationHandler
9 13
 
10 14
 # The global MH algorithm is as follow :
@@ -41,7 +45,6 @@ class MysqlMigrationHandler(DummyMigrationHandler):
41 45
     # @param password str : The db password
42 46
     # @param db str : The db name
43 47
     def __init__(self, host, user, passwd, db, module=pymysql, db_engine='InnoDB', foreign_keys=True, debug=False, dryrun=False, drop_if_exists=False):
44
-        self.datasource = MySQL
45 48
         self._dbmodule = module
46 49
         #Connect to MySQL
47 50
         self.db = self._dbmodule.connect(host=host, user=user, passwd=passwd, db=db)
@@ -144,7 +147,7 @@ class MysqlMigrationHandler(DummyMigrationHandler):
144 147
         self._create_table(tname, pkname, pkftype, self.db_engine, if_exists='nothing')
145 148
         #Add a foreign key if wanted
146 149
         if self.foreign_keys:
147
-            self._add_fk(tname, self.datasource.relations_table_name, pkname, pkname)
150
+            self._add_fk(tname, utils.common_tables['relation'], pkname, pkname)
148 151
         #Add the column
149 152
         self._add_column(tname, emfield.name, emfield.fieldtype_instance())
150 153
         #Update table triggers
@@ -199,7 +202,7 @@ class MysqlMigrationHandler(DummyMigrationHandler):
199 202
         self._create_table(table_name, pkname, pktype, engine=engine)
200 203
 
201 204
         if self.foreign_keys:
202
-            self._add_fk(table_name, self.datasource.objects_table_name, pkname, pkname)
205
+            self._add_fk(table_name, utils.common_tables['object'], pkname, pkname)
203 206
 
204 207
     ## @brief Given an EmClass uid delete the corresponding table
205 208
     # @param em Model : A Model instance
@@ -212,7 +215,7 @@ class MysqlMigrationHandler(DummyMigrationHandler):
212 215
         # Delete the table triggers to prevent errors
213 216
         self._generate_triggers(tname, dict())
214 217
 
215
-        tname = self.datasource.escape_idname(tname)
218
+        tname = utils.escape_idname(tname)
216 219
 
217 220
         self._query("""DROP TABLE {table_name};""".format(table_name=tname))
218 221
 
@@ -238,8 +241,8 @@ class MysqlMigrationHandler(DummyMigrationHandler):
238 241
     # @param tname str : The table name
239 242
     # @param fname str : The column name
240 243
     def _del_column(self, tname, fname):
241
-        tname = self.datasource.escape_idname(tname)
242
-        fname = self.datasource.escape_idname(fname)
244
+        tname = utils.escape_idname(tname)
245
+        fname = utils.escape_idname(fname)
243 246
 
244 247
         self._query("""ALTER TABLE {table_name} DROP COLUMN {col_name};""".format(table_name=tname, col_name=fname))
245 248
 
@@ -247,8 +250,7 @@ class MysqlMigrationHandler(DummyMigrationHandler):
247 250
     # @param emclass EmClass : An EmClass instance
248 251
     # @return a table name
249 252
     def _emclass2table_name(self, emclass):
250
-        return self.datasource.get_table_name_from_class(emclass.name)
251
-        #return "class_%s"%emclass.name
253
+        return utils.object_table_name(emclass.name)
252 254
 
253 255
     ## @brief Construct a table name given a rela2type EmField instance
254 256
     # @param em Model : A Model instance
@@ -257,8 +259,7 @@ class MysqlMigrationHandler(DummyMigrationHandler):
257 259
     def _r2t2table_name(self, em, emfield):
258 260
         emclass = emfield.em_class
259 261
         emtype = em.component(emfield.rel_to_type_id)
260
-        return self.datasource.get_r2t2table_name(emclass.name, emtype.name)
261
-        #return "%s_%s_%s"%(emclass.name, emtype.name, emfield.name)
262
+        return utils.r2t_table_name(emclass.name, emtype.name)
262 263
 
263 264
     ## @brief Generate a columns_fieldtype dict given a rel2type EmField
264 265
     # @param em Model : an @ref EditorialModel.model.Model instance
@@ -278,8 +279,8 @@ class MysqlMigrationHandler(DummyMigrationHandler):
278 279
     # @param drop_if_exist bool : If true drop tables if exists
279 280
     def _create_default_tables(self, drop_if_exist=False):
280 281
         if_exists = 'drop' if drop_if_exist else 'nothing'
281
-        #Object tablea
282
-        tname = self.datasource.objects_table_name
282
+        #Object table
283
+        tname = utils.common_tables['object']
283 284
         pk_name, pk_ftype = self._common_field_pk
284 285
         self._create_table(tname, pk_name, pk_ftype, engine=self.db_engine, if_exists=if_exists)
285 286
         #Adding columns
@@ -291,7 +292,7 @@ class MysqlMigrationHandler(DummyMigrationHandler):
291 292
         self._generate_triggers(tname, cols)
292 293
 
293 294
         #Relation table
294
-        tname = self.datasource.relations_table_name
295
+        tname = utils.common_tables['relation']
295 296
         pk_name, pk_ftype = self._relation_pk
296 297
         self._create_table(tname, pk_name, pk_ftype, engine=self.db_engine, if_exists=if_exists)
297 298
         #Adding columns
@@ -313,7 +314,7 @@ class MysqlMigrationHandler(DummyMigrationHandler):
313 314
     # @param if_exist str : takes values in ['nothing', 'drop']
314 315
     def _create_table(self, table_name, pk_name, pk_ftype, engine, charset='utf8', if_exists='nothing'):
315 316
         #Escaped table name
316
-        etname = self.datasource.escape_idname(table_name)
317
+        etname = utils.escape_idname(table_name)
317 318
         pk_type = self._field_to_type(pk_ftype)
318 319
         pk_specs = self._field_to_specs(pk_ftype)
319 320
 
@@ -333,8 +334,8 @@ PRIMARY KEY({pk_name})
333 334
             raise ValueError("Unexpected value for argument if_exists '%s'." % if_exists)
334 335
 
335 336
         self._query(qres.format(
336
-            table_name=self.datasource.escape_idname(table_name),
337
-            pk_name=self.datasource.escape_idname(pk_name),
337
+            table_name=utils.escape_idname(table_name),
338
+            pk_name=utils.escape_idname(pk_name),
338 339
             pk_type=pk_type,
339 340
             pk_specs=pk_specs,
340 341
             engine=engine,
@@ -346,11 +347,14 @@ PRIMARY KEY({pk_name})
346 347
     # @param col_name str : The columns name
347 348
     # @param col_fieldtype EmFieldype the fieldtype
348 349
     def _add_column(self, table_name, col_name, col_fieldtype, drop_if_exists=False):
350
+
351
+        col_name = utils.column_name(col_name)
352
+
349 353
         add_col = """ALTER TABLE {table_name}
350 354
 ADD COLUMN {col_name} {col_type} {col_specs};"""
351 355
 
352
-        etname = self.datasource.escape_idname(table_name)
353
-        ecname = self.datasource.escape_idname(col_name)
356
+        etname = utils.escape_idname(table_name)
357
+        ecname = utils.escape_idname(col_name)
354 358
 
355 359
         add_col = add_col.format(
356 360
             table_name=etname,
@@ -374,19 +378,19 @@ ADD COLUMN {col_name} {col_type} {col_specs};"""
374 378
     # @param src_col_name str : The name of the concerned column in the src_table
375 379
     # @param dst_col_name str : The name of the concerned column in the dst_table
376 380
     def _add_fk(self, src_table_name, dst_table_name, src_col_name, dst_col_name):
377
-        stname = self.datasource.escape_idname(src_table_name)
378
-        dtname = self.datasource.escape_idname(dst_table_name)
379
-        scname = self.datasource.escape_idname(src_col_name)
380
-        dcname = self.datasource.escape_idname(dst_col_name)
381
+        stname = utils.escape_idname(src_table_name)
382
+        dtname = utils.escape_idname(dst_table_name)
383
+        scname = utils.escape_idname(src_col_name)
384
+        dcname = utils.escape_idname(dst_col_name)
381 385
 
382
-        fk_name = self.datasource.get_fk_name(src_table_name, dst_table_name)
386
+        fk_name = utils.get_fk_name(src_table_name, dst_table_name)
383 387
 
384 388
         self._del_fk(src_table_name, dst_table_name)
385 389
 
386 390
         self._query("""ALTER TABLE {src_table}
387 391
 ADD CONSTRAINT {fk_name}
388 392
 FOREIGN KEY ({src_col}) references {dst_table}({dst_col});""".format(
389
-            fk_name=self.datasource.escape_idname(fk_name),
393
+            fk_name=utils.escape_idname(fk_name),
390 394
             src_table=stname,
391 395
             src_col=scname,
392 396
             dst_table=dtname,
@@ -401,8 +405,8 @@ FOREIGN KEY ({src_col}) references {dst_table}({dst_col});""".format(
401 405
         try:
402 406
             self._query("""ALTER TABLE {src_table}
403 407
 DROP FOREIGN KEY {fk_name}""".format(
404
-                src_table=self.datasource.escape_idname(src_table_name),
405
-                fk_name=self.datasource.escape_idname(self.datasource.get_fk_name(src_table_name, dst_table_name))
408
+                src_table=utils.escape_idname(src_table_name),
409
+                fk_name=utils.escape_idname(utils.get_fk_name(src_table_name, dst_table_name))
406 410
             ))
407 411
         except self._dbmodule.err.InternalError:
408 412
             # If the FK don't exists we do not care
@@ -438,18 +442,18 @@ DROP FOREIGN KEY {fk_name}""".format(
438 442
     # @param moment str : can be 'update' or 'insert'
439 443
     # @param cols_val dict : Dict with column name as key and column value as value
440 444
     def _table_trigger(self, table_name, moment, cols_val):
441
-        trigger_name = self.datasource.escape_idname("%s_%s_trig" % (table_name, moment))
445
+        trigger_name = utils.escape_idname("%s_%s_trig" % (table_name, moment))
442 446
         #Try to delete the trigger
443 447
         drop_trig = """DROP TRIGGER IF EXISTS {trigger_name};""".format(trigger_name=trigger_name)
444 448
         self._query(drop_trig)
445 449
 
446
-        col_val_l = ', '.join(["NEW.%s = %s" % (self.datasource.escape_idname(cname), cval)for cname, cval in cols_val.items()])
450
+        col_val_l = ', '.join(["NEW.%s = %s" % (utils.escape_idname(utils.column_name(cname)), cval)for cname, cval in cols_val.items()])
447 451
         #Create a trigger if needed
448 452
         if len(col_val_l) > 0:
449 453
             trig_q = """CREATE TRIGGER {trigger_name} BEFORE {moment} ON {table_name}
450 454
 FOR EACH ROW SET {col_val_list};""".format(
451 455
                 trigger_name=trigger_name,
452
-                table_name=self.datasource.escape_idname(table_name),
456
+                table_name=utils.escape_idname(table_name),
453 457
                 moment=moment, col_val_list=col_val_l
454 458
             )
455 459
             self._query(trig_q)
@@ -506,41 +510,51 @@ FOR EACH ROW SET {col_val_list};""".format(
506 510
             res = "INT"
507 511
         elif ftype == 'rel2type':
508 512
             res = "INT"
513
+        elif ftype == 'leobject':
514
+            res = "INT"
509 515
         else:
510 516
             raise ValueError("Unsuported fieldtype ftype : %s" % ftype)
511 517
 
512 518
         return res
513 519
 
520
+    ## @brief Return primary key name & fieldtype for relation or object
521
+    @classmethod
522
+    def extract_pk(cls, common_fields):
523
+        for fname, finfo in common_fields.items():
524
+            if finfo['fieldtype'] == 'pk':
525
+                fto = EditorialModel.fieldtypes.generic.GenericFieldType.from_name('pk')
526
+                finfo_cp = copy.copy(finfo)
527
+                del(finfo_cp['fieldtype'])
528
+                return (utils.column_name(fname), fto(**finfo_cp))
529
+        raise RuntimeError("No primary key found in common fields : %s"%common_fields)
530
+
514 531
     ## @brief Returns a tuple (pkname, pk_ftype)
515 532
     @property
516 533
     def _common_field_pk(self):
517
-        for fname, fta in EditorialModel.classtypes.common_fields.items():
518
-            if fta['fieldtype'] == 'pk':
519
-                return (fname, self._common_field_to_ftype(fname))
520
-        return (None, None)
534
+        return self.extract_pk(EditorialModel.classtypes.common_fields)
521 535
 
522 536
     ## @brief Returns a tuple (rel_pkname, rel_ftype)
523
-    # @todo do it
524 537
     @property
525 538
     def _relation_pk(self):
526
-        return (MySQL.relations_pkname, EditorialModel.fieldtypes.pk.EmFieldType())
539
+        return self.extract_pk(EditorialModel.classtypes.relations_common_fields)
527 540
 
528 541
     ## @brief Returns a dict { colname:fieldtype } of relation table columns
529 542
     @property
530 543
     def _relation_cols(self):
531 544
         from_name = EditorialModel.fieldtypes.generic.GenericFieldType.from_name
532
-        return {
533
-            'id_sup': from_name('integer')(),
534
-            'id_sub': from_name('integer')(),
535
-            'rank': from_name('integer')(nullable=True),
536
-            'depth': from_name('integer')(nullable=True),
537
-            'nature': from_name('char')(max_lenght=10, nullable=True),
538
-        }
545
+        res = dict()
546
+        for fieldname, fieldinfo in EditorialModel.classtypes.relations_common_fields.items():
547
+            finfo = copy.copy(fieldinfo)
548
+            fieldtype_name = finfo['fieldtype']
549
+            del(finfo['fieldtype'])
550
+            res[fieldname] = EditorialModel.fieldtypes.generic.GenericFieldType.from_name(fieldtype_name)(**finfo)
551
+        return res
539 552
 
540 553
     ## @brief Given a common field name return an EmFieldType instance
541 554
     # @param cname str : Common field name
542 555
     # @return An EmFieldType instance
543
-    def _common_field_to_ftype(self, cname):
556
+    @classmethod
557
+    def _common_field_to_ftype(cls, cname):
544 558
         fta = copy.copy(EditorialModel.classtypes.common_fields[cname])
545 559
         fto = EditorialModel.fieldtypes.generic.GenericFieldType.from_name(fta['fieldtype'])
546 560
         del fta['fieldtype']

+ 8
- 0
EditorialModel/classtypes.py View File

@@ -48,6 +48,14 @@ relations_common_fields = {
48 48
         'fieldtype': 'integer',
49 49
         'internal': 'automatic',
50 50
     },
51
+    'superior': {
52
+        'fieldtype': 'leo',
53
+        'superior': True,
54
+    },
55
+    'subordinate': {
56
+        'fieldtype': 'leo',
57
+        'superior': False,
58
+    }
51 59
 }
52 60
 
53 61
 

Loading…
Cancel
Save