Browse Source

Modified version of migration handler

This commit is full of bugs (in LeRelation etc.)
Yann Weber 9 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
 import pymysql
4
 import pymysql
5
 
5
 
6
 import EditorialModel
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
 from DataSource.dummy.migrationhandler import DummyMigrationHandler
12
 from DataSource.dummy.migrationhandler import DummyMigrationHandler
9
 
13
 
10
 # The global MH algorithm is as follow :
14
 # The global MH algorithm is as follow :
41
     # @param password str : The db password
45
     # @param password str : The db password
42
     # @param db str : The db name
46
     # @param db str : The db name
43
     def __init__(self, host, user, passwd, db, module=pymysql, db_engine='InnoDB', foreign_keys=True, debug=False, dryrun=False, drop_if_exists=False):
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
         self._dbmodule = module
48
         self._dbmodule = module
46
         #Connect to MySQL
49
         #Connect to MySQL
47
         self.db = self._dbmodule.connect(host=host, user=user, passwd=passwd, db=db)
50
         self.db = self._dbmodule.connect(host=host, user=user, passwd=passwd, db=db)
144
         self._create_table(tname, pkname, pkftype, self.db_engine, if_exists='nothing')
147
         self._create_table(tname, pkname, pkftype, self.db_engine, if_exists='nothing')
145
         #Add a foreign key if wanted
148
         #Add a foreign key if wanted
146
         if self.foreign_keys:
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
         #Add the column
151
         #Add the column
149
         self._add_column(tname, emfield.name, emfield.fieldtype_instance())
152
         self._add_column(tname, emfield.name, emfield.fieldtype_instance())
150
         #Update table triggers
153
         #Update table triggers
199
         self._create_table(table_name, pkname, pktype, engine=engine)
202
         self._create_table(table_name, pkname, pktype, engine=engine)
200
 
203
 
201
         if self.foreign_keys:
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
     ## @brief Given an EmClass uid delete the corresponding table
207
     ## @brief Given an EmClass uid delete the corresponding table
205
     # @param em Model : A Model instance
208
     # @param em Model : A Model instance
212
         # Delete the table triggers to prevent errors
215
         # Delete the table triggers to prevent errors
213
         self._generate_triggers(tname, dict())
216
         self._generate_triggers(tname, dict())
214
 
217
 
215
-        tname = self.datasource.escape_idname(tname)
218
+        tname = utils.escape_idname(tname)
216
 
219
 
217
         self._query("""DROP TABLE {table_name};""".format(table_name=tname))
220
         self._query("""DROP TABLE {table_name};""".format(table_name=tname))
218
 
221
 
238
     # @param tname str : The table name
241
     # @param tname str : The table name
239
     # @param fname str : The column name
242
     # @param fname str : The column name
240
     def _del_column(self, tname, fname):
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
         self._query("""ALTER TABLE {table_name} DROP COLUMN {col_name};""".format(table_name=tname, col_name=fname))
247
         self._query("""ALTER TABLE {table_name} DROP COLUMN {col_name};""".format(table_name=tname, col_name=fname))
245
 
248
 
247
     # @param emclass EmClass : An EmClass instance
250
     # @param emclass EmClass : An EmClass instance
248
     # @return a table name
251
     # @return a table name
249
     def _emclass2table_name(self, emclass):
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
     ## @brief Construct a table name given a rela2type EmField instance
255
     ## @brief Construct a table name given a rela2type EmField instance
254
     # @param em Model : A Model instance
256
     # @param em Model : A Model instance
257
     def _r2t2table_name(self, em, emfield):
259
     def _r2t2table_name(self, em, emfield):
258
         emclass = emfield.em_class
260
         emclass = emfield.em_class
259
         emtype = em.component(emfield.rel_to_type_id)
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
     ## @brief Generate a columns_fieldtype dict given a rel2type EmField
264
     ## @brief Generate a columns_fieldtype dict given a rel2type EmField
264
     # @param em Model : an @ref EditorialModel.model.Model instance
265
     # @param em Model : an @ref EditorialModel.model.Model instance
278
     # @param drop_if_exist bool : If true drop tables if exists
279
     # @param drop_if_exist bool : If true drop tables if exists
279
     def _create_default_tables(self, drop_if_exist=False):
280
     def _create_default_tables(self, drop_if_exist=False):
280
         if_exists = 'drop' if drop_if_exist else 'nothing'
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
         pk_name, pk_ftype = self._common_field_pk
284
         pk_name, pk_ftype = self._common_field_pk
284
         self._create_table(tname, pk_name, pk_ftype, engine=self.db_engine, if_exists=if_exists)
285
         self._create_table(tname, pk_name, pk_ftype, engine=self.db_engine, if_exists=if_exists)
285
         #Adding columns
286
         #Adding columns
291
         self._generate_triggers(tname, cols)
292
         self._generate_triggers(tname, cols)
292
 
293
 
293
         #Relation table
294
         #Relation table
294
-        tname = self.datasource.relations_table_name
295
+        tname = utils.common_tables['relation']
295
         pk_name, pk_ftype = self._relation_pk
296
         pk_name, pk_ftype = self._relation_pk
296
         self._create_table(tname, pk_name, pk_ftype, engine=self.db_engine, if_exists=if_exists)
297
         self._create_table(tname, pk_name, pk_ftype, engine=self.db_engine, if_exists=if_exists)
297
         #Adding columns
298
         #Adding columns
313
     # @param if_exist str : takes values in ['nothing', 'drop']
314
     # @param if_exist str : takes values in ['nothing', 'drop']
314
     def _create_table(self, table_name, pk_name, pk_ftype, engine, charset='utf8', if_exists='nothing'):
315
     def _create_table(self, table_name, pk_name, pk_ftype, engine, charset='utf8', if_exists='nothing'):
315
         #Escaped table name
316
         #Escaped table name
316
-        etname = self.datasource.escape_idname(table_name)
317
+        etname = utils.escape_idname(table_name)
317
         pk_type = self._field_to_type(pk_ftype)
318
         pk_type = self._field_to_type(pk_ftype)
318
         pk_specs = self._field_to_specs(pk_ftype)
319
         pk_specs = self._field_to_specs(pk_ftype)
319
 
320
 
333
             raise ValueError("Unexpected value for argument if_exists '%s'." % if_exists)
334
             raise ValueError("Unexpected value for argument if_exists '%s'." % if_exists)
334
 
335
 
335
         self._query(qres.format(
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
             pk_type=pk_type,
339
             pk_type=pk_type,
339
             pk_specs=pk_specs,
340
             pk_specs=pk_specs,
340
             engine=engine,
341
             engine=engine,
346
     # @param col_name str : The columns name
347
     # @param col_name str : The columns name
347
     # @param col_fieldtype EmFieldype the fieldtype
348
     # @param col_fieldtype EmFieldype the fieldtype
348
     def _add_column(self, table_name, col_name, col_fieldtype, drop_if_exists=False):
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
         add_col = """ALTER TABLE {table_name}
353
         add_col = """ALTER TABLE {table_name}
350
 ADD COLUMN {col_name} {col_type} {col_specs};"""
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
         add_col = add_col.format(
359
         add_col = add_col.format(
356
             table_name=etname,
360
             table_name=etname,
374
     # @param src_col_name str : The name of the concerned column in the src_table
378
     # @param src_col_name str : The name of the concerned column in the src_table
375
     # @param dst_col_name str : The name of the concerned column in the dst_table
379
     # @param dst_col_name str : The name of the concerned column in the dst_table
376
     def _add_fk(self, src_table_name, dst_table_name, src_col_name, dst_col_name):
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
         self._del_fk(src_table_name, dst_table_name)
388
         self._del_fk(src_table_name, dst_table_name)
385
 
389
 
386
         self._query("""ALTER TABLE {src_table}
390
         self._query("""ALTER TABLE {src_table}
387
 ADD CONSTRAINT {fk_name}
391
 ADD CONSTRAINT {fk_name}
388
 FOREIGN KEY ({src_col}) references {dst_table}({dst_col});""".format(
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
             src_table=stname,
394
             src_table=stname,
391
             src_col=scname,
395
             src_col=scname,
392
             dst_table=dtname,
396
             dst_table=dtname,
401
         try:
405
         try:
402
             self._query("""ALTER TABLE {src_table}
406
             self._query("""ALTER TABLE {src_table}
403
 DROP FOREIGN KEY {fk_name}""".format(
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
         except self._dbmodule.err.InternalError:
411
         except self._dbmodule.err.InternalError:
408
             # If the FK don't exists we do not care
412
             # If the FK don't exists we do not care
438
     # @param moment str : can be 'update' or 'insert'
442
     # @param moment str : can be 'update' or 'insert'
439
     # @param cols_val dict : Dict with column name as key and column value as value
443
     # @param cols_val dict : Dict with column name as key and column value as value
440
     def _table_trigger(self, table_name, moment, cols_val):
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
         #Try to delete the trigger
446
         #Try to delete the trigger
443
         drop_trig = """DROP TRIGGER IF EXISTS {trigger_name};""".format(trigger_name=trigger_name)
447
         drop_trig = """DROP TRIGGER IF EXISTS {trigger_name};""".format(trigger_name=trigger_name)
444
         self._query(drop_trig)
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
         #Create a trigger if needed
451
         #Create a trigger if needed
448
         if len(col_val_l) > 0:
452
         if len(col_val_l) > 0:
449
             trig_q = """CREATE TRIGGER {trigger_name} BEFORE {moment} ON {table_name}
453
             trig_q = """CREATE TRIGGER {trigger_name} BEFORE {moment} ON {table_name}
450
 FOR EACH ROW SET {col_val_list};""".format(
454
 FOR EACH ROW SET {col_val_list};""".format(
451
                 trigger_name=trigger_name,
455
                 trigger_name=trigger_name,
452
-                table_name=self.datasource.escape_idname(table_name),
456
+                table_name=utils.escape_idname(table_name),
453
                 moment=moment, col_val_list=col_val_l
457
                 moment=moment, col_val_list=col_val_l
454
             )
458
             )
455
             self._query(trig_q)
459
             self._query(trig_q)
506
             res = "INT"
510
             res = "INT"
507
         elif ftype == 'rel2type':
511
         elif ftype == 'rel2type':
508
             res = "INT"
512
             res = "INT"
513
+        elif ftype == 'leobject':
514
+            res = "INT"
509
         else:
515
         else:
510
             raise ValueError("Unsuported fieldtype ftype : %s" % ftype)
516
             raise ValueError("Unsuported fieldtype ftype : %s" % ftype)
511
 
517
 
512
         return res
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
     ## @brief Returns a tuple (pkname, pk_ftype)
531
     ## @brief Returns a tuple (pkname, pk_ftype)
515
     @property
532
     @property
516
     def _common_field_pk(self):
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
     ## @brief Returns a tuple (rel_pkname, rel_ftype)
536
     ## @brief Returns a tuple (rel_pkname, rel_ftype)
523
-    # @todo do it
524
     @property
537
     @property
525
     def _relation_pk(self):
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
     ## @brief Returns a dict { colname:fieldtype } of relation table columns
541
     ## @brief Returns a dict { colname:fieldtype } of relation table columns
529
     @property
542
     @property
530
     def _relation_cols(self):
543
     def _relation_cols(self):
531
         from_name = EditorialModel.fieldtypes.generic.GenericFieldType.from_name
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
     ## @brief Given a common field name return an EmFieldType instance
553
     ## @brief Given a common field name return an EmFieldType instance
541
     # @param cname str : Common field name
554
     # @param cname str : Common field name
542
     # @return An EmFieldType instance
555
     # @return An EmFieldType instance
543
-    def _common_field_to_ftype(self, cname):
556
+    @classmethod
557
+    def _common_field_to_ftype(cls, cname):
544
         fta = copy.copy(EditorialModel.classtypes.common_fields[cname])
558
         fta = copy.copy(EditorialModel.classtypes.common_fields[cname])
545
         fto = EditorialModel.fieldtypes.generic.GenericFieldType.from_name(fta['fieldtype'])
559
         fto = EditorialModel.fieldtypes.generic.GenericFieldType.from_name(fta['fieldtype'])
546
         del fta['fieldtype']
560
         del fta['fieldtype']

+ 8
- 0
EditorialModel/classtypes.py View File

48
         'fieldtype': 'integer',
48
         'fieldtype': 'integer',
49
         'internal': 'automatic',
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