server/migractions.py
changeset 3720 5376aaadd16b
parent 3659 993997b4b41d
parent 3715 e3ccadb126d7
child 3890 d7a270f50f54
equal deleted inserted replaced
3678:29f74716fd70 3720:5376aaadd16b
    52     """
    52     """
    53 
    53 
    54     def __init__(self, config, schema, interactive=True,
    54     def __init__(self, config, schema, interactive=True,
    55                  repo=None, cnx=None, verbosity=1, connect=True):
    55                  repo=None, cnx=None, verbosity=1, connect=True):
    56         MigrationHelper.__init__(self, config, interactive, verbosity)
    56         MigrationHelper.__init__(self, config, interactive, verbosity)
       
    57         # no config on shell to a remote instance
    57         if not interactive:
    58         if not interactive:
    58             assert cnx
    59             assert cnx
    59             assert repo
    60             assert repo
    60         if cnx is not None:
    61         if cnx is not None:
    61             assert repo
    62             assert repo
    62             self._cnx = cnx
    63             self._cnx = cnx
    63             self.repo = repo
    64             self.repo = repo
    64             self.session.data['rebuild-infered'] = False
    65             if config is not None:
       
    66                 self.session.data['rebuild-infered'] = False
    65         elif connect:
    67         elif connect:
    66             self.repo_connect()
    68             self.repo_connect()
    67         if not schema:
    69         if not schema:
    68             schema = config.load_schema(expand_cubes=True)
    70             schema = config.load_schema(expand_cubes=True)
    69         self.fs_schema = schema
    71         self.fs_schema = schema
    91                 self.backup_database()
    93                 self.backup_database()
    92             elif options.backup_db:
    94             elif options.backup_db:
    93                 self.backup_database(askconfirm=False)
    95                 self.backup_database(askconfirm=False)
    94         super(ServerMigrationHelper, self).migrate(vcconf, toupgrade, options)
    96         super(ServerMigrationHelper, self).migrate(vcconf, toupgrade, options)
    95 
    97 
    96     def process_script(self, migrscript, funcname=None, *args, **kwargs):
    98     def cmd_process_script(self, migrscript, funcname=None, *args, **kwargs):
    97         """execute a migration script
    99         """execute a migration script
    98         in interactive mode,  display the migration script path, ask for
   100         in interactive mode,  display the migration script path, ask for
    99         confirmation and execute it if confirmed
   101         confirmation and execute it if confirmed
   100         """
   102         """
   101         try:
   103         try:
   102             if migrscript.endswith('.sql'):
   104             if migrscript.endswith('.sql'):
   103                 if self.execscript_confirm(migrscript):
   105                 if self.execscript_confirm(migrscript):
   104                     sqlexec(open(migrscript).read(), self.session.system_sql)
   106                     sqlexec(open(migrscript).read(), self.session.system_sql)
   105             else:
   107             else:
   106                 return super(ServerMigrationHelper, self).process_script(
   108                 return super(ServerMigrationHelper, self).cmd_process_script(
   107                     migrscript, funcname, *args, **kwargs)
   109                     migrscript, funcname, *args, **kwargs)
   108             self.commit()
   110             self.commit()
   109         except:
   111         except:
   110             self.rollback()
   112             self.rollback()
   111             raise
   113             raise
   231             self.session.data['rebuild-infered'] = False
   233             self.session.data['rebuild-infered'] = False
   232             return self._cnx
   234             return self._cnx
   233 
   235 
   234     @property
   236     @property
   235     def session(self):
   237     def session(self):
   236         return self.repo._get_session(self.cnx.sessionid)
   238         if self.config is not None:
       
   239             return self.repo._get_session(self.cnx.sessionid)
       
   240         # no access to session on remote instance
       
   241         return None
   237 
   242 
   238     def commit(self):
   243     def commit(self):
   239         if hasattr(self, '_cnx'):
   244         if hasattr(self, '_cnx'):
   240             self._cnx.commit()
   245             self._cnx.commit()
   241 
   246 
   253         context = super(ServerMigrationHelper, self)._create_context()
   258         context = super(ServerMigrationHelper, self)._create_context()
   254         context.update({'checkpoint': self.checkpoint,
   259         context.update({'checkpoint': self.checkpoint,
   255                         'sql': self.sqlexec,
   260                         'sql': self.sqlexec,
   256                         'rql': self.rqlexec,
   261                         'rql': self.rqlexec,
   257                         'rqliter': self.rqliter,
   262                         'rqliter': self.rqliter,
   258                         'schema': self.repo.schema,
   263                         'schema': self.repo.get_schema(),
       
   264                         'cnx': self.cnx,
   259                         'fsschema': self.fs_schema,
   265                         'fsschema': self.fs_schema,
   260                         'session' : self.session,
   266                         'session' : self.session,
   261                         'repo' : self.repo,
   267                         'repo' : self.repo,
   262                         'synchronize_schema': deprecated()(self.cmd_sync_schema_props_perms), # 3.4
   268                         'synchronize_schema': deprecated()(self.cmd_sync_schema_props_perms), # 3.4
   263                         'synchronize_eschema': deprecated()(self.cmd_sync_schema_props_perms), # 3.4
   269                         'synchronize_eschema': deprecated()(self.cmd_sync_schema_props_perms), # 3.4
   266         return context
   272         return context
   267 
   273 
   268     @cached
   274     @cached
   269     def group_mapping(self):
   275     def group_mapping(self):
   270         """cached group mapping"""
   276         """cached group mapping"""
   271         self.session.set_pool()
   277         return ss.group_mapping(self._cw)
   272         return ss.group_mapping(self.session)
       
   273 
   278 
   274     def exec_event_script(self, event, cubepath=None, funcname=None,
   279     def exec_event_script(self, event, cubepath=None, funcname=None,
   275                           *args, **kwargs):
   280                           *args, **kwargs):
   276         if cubepath:
   281         if cubepath:
   277             apc = osp.join(cubepath, 'migration', '%s.py' % event)
   282             apc = osp.join(cubepath, 'migration', '%s.py' % event)
   287             confirm = self.confirm
   292             confirm = self.confirm
   288             execscript_confirm = self.execscript_confirm
   293             execscript_confirm = self.execscript_confirm
   289             self.confirm = yes
   294             self.confirm = yes
   290             self.execscript_confirm = yes
   295             self.execscript_confirm = yes
   291             try:
   296             try:
   292                 return self.process_script(apc, funcname, *args, **kwargs)
   297                 return self.cmd_process_script(apc, funcname, *args, **kwargs)
   293             finally:
   298             finally:
   294                 self.confirm = confirm
   299                 self.confirm = confirm
   295                 self.execscript_confirm = execscript_confirm
   300                 self.execscript_confirm = execscript_confirm
   296                 if self.config.free_wheel:
   301                 if self.config.free_wheel:
   297                     self.repo.hm.register_hook(setowner_after_add_entity,
   302                     self.repo.hm.register_hook(setowner_after_add_entity,
   304         """permission synchronization for an entity or relation type"""
   309         """permission synchronization for an entity or relation type"""
   305         if ertype in VIRTUAL_RTYPES:
   310         if ertype in VIRTUAL_RTYPES:
   306             return
   311             return
   307         newrschema = self.fs_schema[ertype]
   312         newrschema = self.fs_schema[ertype]
   308         teid = self.repo.schema[ertype].eid
   313         teid = self.repo.schema[ertype].eid
   309         if 'update' in newrschema.ACTIONS or newrschema.is_final():
   314         if 'update' in newrschema.ACTIONS or newrschema.final:
   310             # entity type
   315             # entity type
   311             exprtype = u'ERQLExpression'
   316             exprtype = u'ERQLExpression'
   312         else:
   317         else:
   313             # relation type
   318             # relation type
   314             exprtype = u'RRQLExpression'
   319             exprtype = u'RRQLExpression'
   641         instschema = self.repo.schema
   646         instschema = self.repo.schema
   642         if etype in instschema:
   647         if etype in instschema:
   643             # XXX (syt) plz explain: if we're adding an entity type, it should
   648             # XXX (syt) plz explain: if we're adding an entity type, it should
   644             # not be there...
   649             # not be there...
   645             eschema = instschema[etype]
   650             eschema = instschema[etype]
   646             if eschema.is_final():
   651             if eschema.final:
   647                 instschema.del_entity_type(etype)
   652                 instschema.del_entity_type(etype)
   648         else:
   653         else:
   649             eschema = self.fs_schema.eschema(etype)
   654             eschema = self.fs_schema.eschema(etype)
   650         confirm = self.verbosity >= 2
   655         confirm = self.verbosity >= 2
   651         # register the entity into CWEType
   656         # register the entity into CWEType
   684                         if not tschema in instschema:
   689                         if not tschema in instschema:
   685                             continue
   690                             continue
   686                         if role == 'subject':
   691                         if role == 'subject':
   687                             subjschema = spschema
   692                             subjschema = spschema
   688                             objschema = tschema
   693                             objschema = tschema
   689                             if rschema.final and instspschema.has_subject_relation(rschema):
   694                             if rschema.final and rschema in instspschema.subjrels:
   690                                 # attribute already set, has_rdef would check if
   695                                 # attribute already set, has_rdef would check if
   691                                 # it's of the same type, we don't want this so
   696                                 # it's of the same type, we don't want this so
   692                                 # simply skip here
   697                                 # simply skip here
   693                                 continue
   698                                 continue
   694                         elif role == 'object':
   699                         elif role == 'object':
   850 
   855 
   851     def cmd_drop_relation_definition(self, subjtype, rtype, objtype, commit=True):
   856     def cmd_drop_relation_definition(self, subjtype, rtype, objtype, commit=True):
   852         """unregister an existing relation definition"""
   857         """unregister an existing relation definition"""
   853         rschema = self.repo.schema.rschema(rtype)
   858         rschema = self.repo.schema.rschema(rtype)
   854         # unregister the definition from CWAttribute or CWRelation
   859         # unregister the definition from CWAttribute or CWRelation
   855         if rschema.is_final():
   860         if rschema.final:
   856             etype = 'CWAttribute'
   861             etype = 'CWAttribute'
   857         else:
   862         else:
   858             etype = 'CWRelation'
   863             etype = 'CWRelation'
   859         rql = ('DELETE %s X WHERE X from_entity FE, FE name "%s",'
   864         rql = ('DELETE %s X WHERE X from_entity FE, FE name "%s",'
   860                'X relation_type RT, RT name "%s", X to_entity TE, TE name "%s"')
   865                'X relation_type RT, RT name "%s", X to_entity TE, TE name "%s"')
   979                    for the specified entity type(s); set it to false in
   984                    for the specified entity type(s); set it to false in
   980                    the case of a subworkflow
   985                    the case of a subworkflow
   981 
   986 
   982          :rtype: `Workflow`
   987          :rtype: `Workflow`
   983         """
   988         """
   984         self.session.set_pool() # ensure pool is set
       
   985         wf = self.cmd_create_entity('Workflow', name=unicode(name),
   989         wf = self.cmd_create_entity('Workflow', name=unicode(name),
   986                                     **kwargs)
   990                                     **kwargs)
   987         if not isinstance(wfof, (list, tuple)):
   991         if not isinstance(wfof, (list, tuple)):
   988             wfof = (wfof,)
   992             wfof = (wfof,)
   989         for etype in wfof:
   993         for etype in wfof:
   999             self.commit()
  1003             self.commit()
  1000         return wf
  1004         return wf
  1001 
  1005 
  1002     # XXX remove once cmd_add_[state|transition] are removed
  1006     # XXX remove once cmd_add_[state|transition] are removed
  1003     def _get_or_create_wf(self, etypes):
  1007     def _get_or_create_wf(self, etypes):
  1004         self.session.set_pool() # ensure pool is set
       
  1005         if not isinstance(etypes, (list, tuple)):
  1008         if not isinstance(etypes, (list, tuple)):
  1006             etypes = (etypes,)
  1009             etypes = (etypes,)
  1007         rset = self.rqlexec('Workflow X WHERE X workflow_of ET, ET name %(et)s',
  1010         rset = self.rqlexec('Workflow X WHERE X workflow_of ET, ET name %(et)s',
  1008                             {'et': etypes[0]})
  1011                             {'et': etypes[0]})
  1009         if rset:
  1012         if rset:
  1039                                        requiredgroups=(), conditions=(),
  1042                                        requiredgroups=(), conditions=(),
  1040                                        reset=True, commit=False):
  1043                                        reset=True, commit=False):
  1041         """set or add (if `reset` is False) groups and conditions for a
  1044         """set or add (if `reset` is False) groups and conditions for a
  1042         transition
  1045         transition
  1043         """
  1046         """
  1044         self.session.set_pool() # ensure pool is set
  1047         tr = self._cw.entity_from_eid(treid)
  1045         tr = self.session.entity_from_eid(treid)
       
  1046         tr.set_transition_permissions(requiredgroups, conditions, reset)
  1048         tr.set_transition_permissions(requiredgroups, conditions, reset)
  1047         if commit:
  1049         if commit:
  1048             self.commit()
  1050             self.commit()
  1049 
  1051 
  1050     @deprecated('[3.5] use entity.fire_transition("transition") or entity.change_state("state")')
  1052     @deprecated('[3.5] use entity.fire_transition("transition") or entity.change_state("state")')
  1051     def cmd_set_state(self, eid, statename, commit=False):
  1053     def cmd_set_state(self, eid, statename, commit=False):
  1052         self.session.set_pool() # ensure pool is set
  1054         self._cw.entity_from_eid(eid).change_state(statename)
  1053         self.session.entity_from_eid(eid).change_state(statename)
       
  1054         if commit:
  1055         if commit:
  1055             self.commit()
  1056             self.commit()
  1056 
  1057 
  1057     # CWProperty handling ######################################################
  1058     # CWProperty handling ######################################################
  1058 
  1059 
  1072             self.rqlexec('SET X value %(v)s WHERE X pkey %(k)s',
  1073             self.rqlexec('SET X value %(v)s WHERE X pkey %(k)s',
  1073                          {'k': pkey, 'v': value}, ask_confirm=False)
  1074                          {'k': pkey, 'v': value}, ask_confirm=False)
  1074 
  1075 
  1075     # other data migration commands ###########################################
  1076     # other data migration commands ###########################################
  1076 
  1077 
  1077     def cmd_create_entity(self, etype, *args, **kwargs):
  1078     @property
       
  1079     def _cw(self):
       
  1080         session = self.session
       
  1081         if session is not None:
       
  1082             session.set_pool()
       
  1083             return session
       
  1084         return self.cnx.request()
       
  1085 
       
  1086     def cmd_create_entity(self, etype, **kwargs):
  1078         """add a new entity of the given type"""
  1087         """add a new entity of the given type"""
  1079         commit = kwargs.pop('commit', False)
  1088         commit = kwargs.pop('commit', False)
  1080         self.session.set_pool()
  1089         entity = self._cw.create_entity(etype, **kwargs)
  1081         entity = self.session.create_entity(etype, *args, **kwargs)
       
  1082         if commit:
  1090         if commit:
  1083             self.commit()
  1091             self.commit()
  1084         return entity
  1092         return entity
  1085 
  1093 
  1086     @deprecated('use create_entity')
  1094     @deprecated('use create_entity')
  1112     def rqlexec(self, rql, kwargs=None, cachekey=None, ask_confirm=True):
  1120     def rqlexec(self, rql, kwargs=None, cachekey=None, ask_confirm=True):
  1113         """rql action"""
  1121         """rql action"""
  1114         if not isinstance(rql, (tuple, list)):
  1122         if not isinstance(rql, (tuple, list)):
  1115             rql = ( (rql, kwargs), )
  1123             rql = ( (rql, kwargs), )
  1116         res = None
  1124         res = None
  1117         self.session.set_pool()
       
  1118         for rql, kwargs in rql:
  1125         for rql, kwargs in rql:
  1119             if kwargs:
  1126             if kwargs:
  1120                 msg = '%s (%s)' % (rql, kwargs)
  1127                 msg = '%s (%s)' % (rql, kwargs)
  1121             else:
  1128             else:
  1122                 msg = rql
  1129                 msg = rql
  1123             if not ask_confirm or self.confirm('execute rql: %s ?' % msg):
  1130             if not ask_confirm or self.confirm('execute rql: %s ?' % msg):
  1124                 try:
  1131                 try:
  1125                     res = self.session.execute(rql, kwargs, cachekey)
  1132                     res = self._cw.execute(rql, kwargs, cachekey)
  1126                 except Exception, ex:
  1133                 except Exception, ex:
  1127                     if self.confirm('error: %s\nabort?' % ex):
  1134                     if self.confirm('error: %s\nabort?' % ex):
  1128                         raise
  1135                         raise
  1129         return res
  1136         return res
  1130 
  1137 
  1209         else:
  1216         else:
  1210             msg = rql
  1217             msg = rql
  1211         if self.ask_confirm:
  1218         if self.ask_confirm:
  1212             if not self._h.confirm('execute rql: %s ?' % msg):
  1219             if not self._h.confirm('execute rql: %s ?' % msg):
  1213                 raise StopIteration
  1220                 raise StopIteration
  1214         self._h.session.set_pool()
       
  1215         try:
  1221         try:
  1216             rset = self._h.session.execute(rql, kwargs)
  1222             rset = self._h._cw.execute(rql, kwargs)
  1217         except Exception, ex:
  1223         except Exception, ex:
  1218             if self._h.confirm('error: %s\nabort?' % ex):
  1224             if self._h.confirm('error: %s\nabort?' % ex):
  1219                 raise
  1225                 raise
  1220             else:
  1226             else:
  1221                 raise StopIteration
  1227                 raise StopIteration