48 |
48 |
49 from yams.constraints import SizeConstraint |
49 from yams.constraints import SizeConstraint |
50 from yams.schema2sql import eschema2sql, rschema2sql |
50 from yams.schema2sql import eschema2sql, rschema2sql |
51 from yams.schema import RelationDefinitionSchema |
51 from yams.schema import RelationDefinitionSchema |
52 |
52 |
53 from cubicweb import AuthenticationError, ExecutionError |
53 from cubicweb import CW_SOFTWARE_ROOT, AuthenticationError, ExecutionError |
54 from cubicweb.selectors import is_instance |
54 from cubicweb.selectors import is_instance |
55 from cubicweb.schema import (ETYPE_NAME_MAP, META_RTYPES, VIRTUAL_RTYPES, |
55 from cubicweb.schema import (ETYPE_NAME_MAP, META_RTYPES, VIRTUAL_RTYPES, |
56 PURE_VIRTUAL_RTYPES, |
56 PURE_VIRTUAL_RTYPES, |
57 CubicWebRelationSchema, order_eschemas) |
57 CubicWebRelationSchema, order_eschemas) |
58 from cubicweb.cwvreg import CW_EVENT_MANAGER |
58 from cubicweb.cwvreg import CW_EVENT_MANAGER |
348 @cached |
348 @cached |
349 def cstrtype_mapping(self): |
349 def cstrtype_mapping(self): |
350 """cached constraint types mapping""" |
350 """cached constraint types mapping""" |
351 return ss.cstrtype_mapping(self._cw) |
351 return ss.cstrtype_mapping(self._cw) |
352 |
352 |
353 def exec_event_script(self, event, cubepath=None, funcname=None, |
353 def cmd_exec_event_script(self, event, cube=None, funcname=None, |
354 *args, **kwargs): |
354 *args, **kwargs): |
355 if cubepath: |
355 """execute a cube event scripts `migration/<event>.py` where event |
|
356 is one of 'precreate', 'postcreate', 'preremove' and 'postremove'. |
|
357 """ |
|
358 assert event in ('precreate', 'postcreate', 'preremove', 'postremove') |
|
359 if cube: |
|
360 cubepath = self.config.cube_dir(cube) |
356 apc = osp.join(cubepath, 'migration', '%s.py' % event) |
361 apc = osp.join(cubepath, 'migration', '%s.py' % event) |
357 else: |
362 else: |
358 apc = osp.join(self.config.migration_scripts_dir(), '%s.py' % event) |
363 apc = osp.join(self.config.migration_scripts_dir(), '%s.py' % event) |
359 if osp.exists(apc): |
364 if osp.exists(apc): |
360 if self.config.free_wheel: |
365 if self.config.free_wheel: |
370 self.confirm = confirm |
375 self.confirm = confirm |
371 self.execscript_confirm = execscript_confirm |
376 self.execscript_confirm = execscript_confirm |
372 if self.config.free_wheel: |
377 if self.config.free_wheel: |
373 self.cmd_reactivate_verification_hooks() |
378 self.cmd_reactivate_verification_hooks() |
374 |
379 |
375 def install_custom_sql_scripts(self, directory, driver): |
380 def cmd_install_custom_sql_scripts(self, cube=None): |
|
381 """install a cube custom sql scripts `schema/*.<driver>.sql` where |
|
382 <driver> depends on the instance main database backend (eg 'postgres', |
|
383 'mysql'...) |
|
384 """ |
|
385 driver = self.repo.system_source.dbdriver |
|
386 if cube is None: |
|
387 directory = osp.join(CW_SOFTWARE_ROOT, 'schemas') |
|
388 else: |
|
389 directory = self.config.cube_dir(cube) |
376 sql_scripts = [] |
390 sql_scripts = [] |
377 for fpath in glob(osp.join(directory, '*.sql.%s' % driver)): |
391 for fpath in glob(osp.join(directory, '*.sql.%s' % driver)): |
378 newname = osp.basename(fpath).replace('.sql.%s' % driver, |
392 newname = osp.basename(fpath).replace('.sql.%s' % driver, |
379 '.%s.sql' % driver) |
393 '.%s.sql' % driver) |
380 warn('[3.5.6] rename %s into %s' % (fpath, newname), |
394 warn('[3.5.6] rename %s into %s' % (fpath, newname), |
657 self.fs_schema = newcubes_schema |
671 self.fs_schema = newcubes_schema |
658 self.update_context('fsschema', self.fs_schema) |
672 self.update_context('fsschema', self.fs_schema) |
659 new = set() |
673 new = set() |
660 # execute pre-create files |
674 # execute pre-create files |
661 driver = self.repo.system_source.dbdriver |
675 driver = self.repo.system_source.dbdriver |
662 for pack in reversed(newcubes): |
676 for cube in reversed(newcubes): |
663 cubedir = self.config.cube_dir(pack) |
677 self.cmd_install_custom_sql_scripts(cube) |
664 self.install_custom_sql_scripts(osp.join(cubedir, 'schema'), driver) |
678 self.cmd_exec_event_script('precreate', cube) |
665 self.exec_event_script('precreate', cubedir) |
|
666 # add new entity and relation types |
679 # add new entity and relation types |
667 for rschema in newcubes_schema.relations(): |
680 for rschema in newcubes_schema.relations(): |
668 if not rschema in self.repo.schema: |
681 if not rschema in self.repo.schema: |
669 self.cmd_add_relation_type(rschema.type) |
682 self.cmd_add_relation_type(rschema.type) |
670 new.add(rschema.type) |
683 new.add(rschema.type) |
683 if not (fromtype in new or totype in new or rschema in new): |
696 if not (fromtype in new or totype in new or rschema in new): |
684 continue |
697 continue |
685 self.cmd_add_relation_definition(str(fromtype), rschema.type, |
698 self.cmd_add_relation_definition(str(fromtype), rschema.type, |
686 str(totype)) |
699 str(totype)) |
687 # execute post-create files |
700 # execute post-create files |
688 for pack in reversed(newcubes): |
701 for cube in reversed(newcubes): |
689 self.exec_event_script('postcreate', self.config.cube_dir(pack)) |
702 self.cmd_exec_event_script('postcreate', cube) |
690 self.commit() |
703 self.commit() |
691 |
704 |
692 def cmd_remove_cube(self, cube, removedeps=False): |
705 def cmd_remove_cube(self, cube, removedeps=False): |
693 removedcubes = super(ServerMigrationHelper, self).cmd_remove_cube( |
706 removedcubes = super(ServerMigrationHelper, self).cmd_remove_cube( |
694 cube, removedeps) |
707 cube, removedeps) |
696 return |
709 return |
697 fsschema = self.fs_schema |
710 fsschema = self.fs_schema |
698 removedcubes_schema = self.config.load_schema(construction_mode='non-strict') |
711 removedcubes_schema = self.config.load_schema(construction_mode='non-strict') |
699 reposchema = self.repo.schema |
712 reposchema = self.repo.schema |
700 # execute pre-remove files |
713 # execute pre-remove files |
701 for pack in reversed(removedcubes): |
714 for cube in reversed(removedcubes): |
702 self.exec_event_script('preremove', self.config.cube_dir(pack)) |
715 self.cmd_exec_event_script('preremove', cube) |
703 # remove cubes'entity and relation types |
716 # remove cubes'entity and relation types |
704 for rschema in fsschema.relations(): |
717 for rschema in fsschema.relations(): |
705 if not rschema in removedcubes_schema and rschema in reposchema: |
718 if not rschema in removedcubes_schema and rschema in reposchema: |
706 self.cmd_drop_relation_type(rschema.type) |
719 self.cmd_drop_relation_type(rschema.type) |
707 toremove = [eschema for eschema in fsschema.entities() |
720 toremove = [eschema for eschema in fsschema.entities() |
718 (fromtype, totype) in reposchema[rschema.type].rdefs: |
731 (fromtype, totype) in reposchema[rschema.type].rdefs: |
719 self.cmd_drop_relation_definition( |
732 self.cmd_drop_relation_definition( |
720 str(fromtype), rschema.type, str(totype)) |
733 str(fromtype), rschema.type, str(totype)) |
721 # execute post-remove files |
734 # execute post-remove files |
722 for cube in reversed(removedcubes): |
735 for cube in reversed(removedcubes): |
723 self.exec_event_script('postremove', self.config.cube_dir(cube)) |
736 self.cmd_exec_event_script('postremove', cube) |
724 self.rqlexec('DELETE CWProperty X WHERE X pkey %(pk)s', |
737 self.rqlexec('DELETE CWProperty X WHERE X pkey %(pk)s', |
725 {'pk': u'system.version.'+cube}, ask_confirm=False) |
738 {'pk': u'system.version.'+cube}, ask_confirm=False) |
726 self.commit() |
739 self.commit() |
727 |
740 |
728 # schema migration actions ################################################ |
741 # schema migration actions ################################################ |