[migration] expose migration methods to execute schema/*.sql and migration/<event>.py files (closes #1986498) stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 06 Oct 2011 16:15:16 +0200
branchstable
changeset 7915 a7f3245e1728
parent 7912 7a2e2a3c3b0c
child 7916 54e240c1b419
[migration] expose migration methods to execute schema/*.sql and migration/<event>.py files (closes #1986498)
server/__init__.py
server/migractions.py
--- a/server/__init__.py	Thu Oct 06 10:13:24 2011 +0200
+++ b/server/__init__.py	Thu Oct 06 16:15:16 2011 +0200
@@ -210,9 +210,9 @@
     handler = config.migration_handler(schema, interactive=False,
                                        cnx=cnx, repo=repo)
     # install additional driver specific sql files
-    handler.install_custom_sql_scripts(join(CW_SOFTWARE_ROOT, 'schemas'), driver)
-    for directory in reversed(config.cubes_path()):
-        handler.install_custom_sql_scripts(join(directory, 'schema'), driver)
+    handler.cmd_install_custom_sql_scripts()
+    for cube in reversed(config.cubes()):
+        handler.cmd_install_custom_sql_scripts(cube)
     # serialize the schema
     initialize_schema(config, schema, handler)
     # yoo !
@@ -231,8 +231,7 @@
     from cubicweb.server.schemaserial import serialize_schema
     from cubicweb.server.session import hooks_control
     session = mhandler.session
-    paths = [p for p in config.cubes_path() + [config.apphome]
-             if exists(join(p, 'migration'))]
+    cubes = config.cubes()
     # deactivate every hooks but those responsible to set metadata
     # so, NO INTEGRITY CHECKS are done, to have quicker db creation.
     # Active integrity is kept else we may pb such as two default
@@ -240,18 +239,18 @@
     with hooks_control(session, session.HOOKS_DENY_ALL, 'metadata',
                        'activeintegrity'):
         # execute cubicweb's pre<event> script
-        mhandler.exec_event_script('pre%s' % event)
+        mhandler.cmd_exec_event_script('pre%s' % event)
         # execute cubes pre<event> script if any
-        for path in reversed(paths):
-            mhandler.exec_event_script('pre%s' % event, path)
+        for cube in reversed(cubes):
+            mhandler.cmd_exec_event_script('pre%s' % event, cube)
         # enter instance'schema into the database
         session.set_cnxset()
         serialize_schema(session, schema)
         # execute cubicweb's post<event> script
-        mhandler.exec_event_script('post%s' % event)
+        mhandler.cmd_exec_event_script('post%s' % event)
         # execute cubes'post<event> script if any
-        for path in reversed(paths):
-            mhandler.exec_event_script('post%s' % event, path)
+        for cube in reversed(cubes):
+            mhandler.cmd_exec_event_script('post%s' % event, cube)
 
 
 # sqlite'stored procedures have to be registered at connection opening time
--- a/server/migractions.py	Thu Oct 06 10:13:24 2011 +0200
+++ b/server/migractions.py	Thu Oct 06 16:15:16 2011 +0200
@@ -50,7 +50,7 @@
 from yams.schema2sql import eschema2sql, rschema2sql
 from yams.schema import RelationDefinitionSchema
 
-from cubicweb import AuthenticationError, ExecutionError
+from cubicweb import CW_SOFTWARE_ROOT, AuthenticationError, ExecutionError
 from cubicweb.selectors import is_instance
 from cubicweb.schema import (ETYPE_NAME_MAP, META_RTYPES, VIRTUAL_RTYPES,
                              PURE_VIRTUAL_RTYPES,
@@ -350,9 +350,14 @@
         """cached constraint types mapping"""
         return ss.cstrtype_mapping(self._cw)
 
-    def exec_event_script(self, event, cubepath=None, funcname=None,
-                          *args, **kwargs):
-        if cubepath:
+    def cmd_exec_event_script(self, event, cube=None, funcname=None,
+                              *args, **kwargs):
+        """execute a cube event scripts  `migration/<event>.py` where event
+        is one of 'precreate', 'postcreate', 'preremove' and 'postremove'.
+        """
+        assert event in ('precreate', 'postcreate', 'preremove', 'postremove')
+        if cube:
+            cubepath = self.config.cube_dir(cube)
             apc = osp.join(cubepath, 'migration', '%s.py' % event)
         else:
             apc = osp.join(self.config.migration_scripts_dir(), '%s.py' % event)
@@ -372,7 +377,16 @@
                 if self.config.free_wheel:
                     self.cmd_reactivate_verification_hooks()
 
-    def install_custom_sql_scripts(self, directory, driver):
+    def cmd_install_custom_sql_scripts(self, cube=None):
+        """install a cube custom sql scripts `schema/*.<driver>.sql` where
+        <driver> depends on the instance main database backend (eg 'postgres',
+        'mysql'...)
+        """
+        driver = self.repo.system_source.dbdriver
+        if cube is None:
+            directory = osp.join(CW_SOFTWARE_ROOT, 'schemas')
+        else:
+            directory = self.config.cube_dir(cube)
         sql_scripts = []
         for fpath in glob(osp.join(directory, '*.sql.%s' % driver)):
             newname = osp.basename(fpath).replace('.sql.%s' % driver,
@@ -659,10 +673,9 @@
         new = set()
         # execute pre-create files
         driver = self.repo.system_source.dbdriver
-        for pack in reversed(newcubes):
-            cubedir = self.config.cube_dir(pack)
-            self.install_custom_sql_scripts(osp.join(cubedir, 'schema'), driver)
-            self.exec_event_script('precreate', cubedir)
+        for cube in reversed(newcubes):
+            self.cmd_install_custom_sql_scripts(cube)
+            self.cmd_exec_event_script('precreate', cube)
         # add new entity and relation types
         for rschema in newcubes_schema.relations():
             if not rschema in self.repo.schema:
@@ -685,8 +698,8 @@
                 self.cmd_add_relation_definition(str(fromtype), rschema.type,
                                                  str(totype))
         # execute post-create files
-        for pack in reversed(newcubes):
-            self.exec_event_script('postcreate', self.config.cube_dir(pack))
+        for cube in reversed(newcubes):
+            self.cmd_exec_event_script('postcreate', cube)
             self.commit()
 
     def cmd_remove_cube(self, cube, removedeps=False):
@@ -698,8 +711,8 @@
         removedcubes_schema = self.config.load_schema(construction_mode='non-strict')
         reposchema = self.repo.schema
         # execute pre-remove files
-        for pack in reversed(removedcubes):
-            self.exec_event_script('preremove', self.config.cube_dir(pack))
+        for cube in reversed(removedcubes):
+            self.cmd_exec_event_script('preremove', cube)
         # remove cubes'entity and relation types
         for rschema in fsschema.relations():
             if not rschema in removedcubes_schema and rschema in reposchema:
@@ -720,7 +733,7 @@
                             str(fromtype), rschema.type, str(totype))
         # execute post-remove files
         for cube in reversed(removedcubes):
-            self.exec_event_script('postremove', self.config.cube_dir(cube))
+            self.cmd_exec_event_script('postremove', cube)
             self.rqlexec('DELETE CWProperty X WHERE X pkey %(pk)s',
                          {'pk': u'system.version.'+cube}, ask_confirm=False)
             self.commit()