server/migractions.py
changeset 5174 78438ad513ca
parent 5132 260d73ad4f24
child 5302 dfd147de06b2
equal deleted inserted replaced
5173:73760bbb66bd 5174:78438ad513ca
   266         if hasattr(self, '_cnx'):
   266         if hasattr(self, '_cnx'):
   267             self._cnx.rollback()
   267             self._cnx.rollback()
   268         if self.session:
   268         if self.session:
   269             self.session.set_pool()
   269             self.session.set_pool()
   270 
   270 
   271     def rqlexecall(self, rqliter, cachekey=None, ask_confirm=True):
   271     def rqlexecall(self, rqliter, ask_confirm=True):
   272         for rql, kwargs in rqliter:
   272         for rql, kwargs in rqliter:
   273             self.rqlexec(rql, kwargs, cachekey, ask_confirm=ask_confirm)
   273             self.rqlexec(rql, kwargs, ask_confirm=ask_confirm)
   274 
   274 
   275     @cached
   275     @cached
   276     def _create_context(self):
   276     def _create_context(self):
   277         """return a dictionary to use as migration script execution context"""
   277         """return a dictionary to use as migration script execution context"""
   278         context = super(ServerMigrationHelper, self)._create_context()
   278         context = super(ServerMigrationHelper, self)._create_context()
   359         for action in erschema.ACTIONS:
   359         for action in erschema.ACTIONS:
   360             perm = '%s_permission' % action
   360             perm = '%s_permission' % action
   361             # handle groups
   361             # handle groups
   362             newgroups = list(erschema.get_groups(action))
   362             newgroups = list(erschema.get_groups(action))
   363             for geid, gname in self.rqlexec('Any G, GN WHERE T %s G, G name GN, '
   363             for geid, gname in self.rqlexec('Any G, GN WHERE T %s G, G name GN, '
   364                                             'T eid %%(x)s' % perm, {'x': teid}, 'x',
   364                                             'T eid %%(x)s' % perm, {'x': teid},
   365                                             ask_confirm=False):
   365                                             ask_confirm=False):
   366                 if not gname in newgroups:
   366                 if not gname in newgroups:
   367                     if not confirm or self.confirm('Remove %s permission of %s to %s?'
   367                     if not confirm or self.confirm('Remove %s permission of %s to %s?'
   368                                                    % (action, erschema, gname)):
   368                                                    % (action, erschema, gname)):
   369                         self.rqlexec('DELETE T %s G WHERE G eid %%(x)s, T eid %s'
   369                         self.rqlexec('DELETE T %s G WHERE G eid %%(x)s, T eid %s'
   370                                      % (perm, teid),
   370                                      % (perm, teid),
   371                                      {'x': geid}, 'x', ask_confirm=False)
   371                                      {'x': geid}, ask_confirm=False)
   372                 else:
   372                 else:
   373                     newgroups.remove(gname)
   373                     newgroups.remove(gname)
   374             for gname in newgroups:
   374             for gname in newgroups:
   375                 if not confirm or self.confirm('Grant %s permission of %s to %s?'
   375                 if not confirm or self.confirm('Grant %s permission of %s to %s?'
   376                                                % (action, erschema, gname)):
   376                                                % (action, erschema, gname)):
   377                     self.rqlexec('SET T %s G WHERE G eid %%(x)s, T eid %s'
   377                     self.rqlexec('SET T %s G WHERE G eid %%(x)s, T eid %s'
   378                                  % (perm, teid),
   378                                  % (perm, teid),
   379                                  {'x': gm[gname]}, 'x', ask_confirm=False)
   379                                  {'x': gm[gname]}, ask_confirm=False)
   380             # handle rql expressions
   380             # handle rql expressions
   381             newexprs = dict((expr.expression, expr) for expr in erschema.get_rqlexprs(action))
   381             newexprs = dict((expr.expression, expr) for expr in erschema.get_rqlexprs(action))
   382             for expreid, expression in self.rqlexec('Any E, EX WHERE T %s E, E expression EX, '
   382             for expreid, expression in self.rqlexec('Any E, EX WHERE T %s E, E expression EX, '
   383                                                     'T eid %s' % (perm, teid),
   383                                                     'T eid %s' % (perm, teid),
   384                                                     ask_confirm=False):
   384                                                     ask_confirm=False):
   386                     if not confirm or self.confirm('Remove %s expression for %s permission of %s?'
   386                     if not confirm or self.confirm('Remove %s expression for %s permission of %s?'
   387                                                    % (expression, action, erschema)):
   387                                                    % (expression, action, erschema)):
   388                         # deleting the relation will delete the expression entity
   388                         # deleting the relation will delete the expression entity
   389                         self.rqlexec('DELETE T %s E WHERE E eid %%(x)s, T eid %s'
   389                         self.rqlexec('DELETE T %s E WHERE E eid %%(x)s, T eid %s'
   390                                      % (perm, teid),
   390                                      % (perm, teid),
   391                                      {'x': expreid}, 'x', ask_confirm=False)
   391                                      {'x': expreid}, ask_confirm=False)
   392                 else:
   392                 else:
   393                     newexprs.pop(expression)
   393                     newexprs.pop(expression)
   394             for expression in newexprs.values():
   394             for expression in newexprs.values():
   395                 expr = expression.expression
   395                 expr = expression.expression
   396                 if not confirm or self.confirm('Add %s expression for %s permission of %s?'
   396                 if not confirm or self.confirm('Add %s expression for %s permission of %s?'
   397                                                % (expr, action, erschema)):
   397                                                % (expr, action, erschema)):
   398                     self.rqlexec('INSERT RQLExpression X: X exprtype %%(exprtype)s, '
   398                     self.rqlexec('INSERT RQLExpression X: X exprtype %%(exprtype)s, '
   399                                  'X expression %%(expr)s, X mainvars %%(vars)s, T %s X '
   399                                  'X expression %%(expr)s, X mainvars %%(vars)s, T %s X '
   400                                  'WHERE T eid %%(x)s' % perm,
   400                                  'WHERE T eid %%(x)s' % perm,
   401                                  {'expr': expr, 'exprtype': exprtype,
   401                                  {'expr': expr, 'exprtype': exprtype,
   402                                   'vars': expression.mainvars, 'x': teid}, 'x',
   402                                   'vars': expression.mainvars, 'x': teid},
   403                                  ask_confirm=False)
   403                                  ask_confirm=False)
   404 
   404 
   405     def _synchronize_rschema(self, rtype, syncrdefs=True, syncperms=True, syncprops=True):
   405     def _synchronize_rschema(self, rtype, syncrdefs=True, syncperms=True, syncprops=True):
   406         """synchronize properties of the persistent relation schema against its
   406         """synchronize properties of the persistent relation schema against its
   407         current definition:
   407         current definition:
   522                         break
   522                         break
   523                 else:
   523                 else:
   524                     newcstr = None
   524                     newcstr = None
   525                 if newcstr is None:
   525                 if newcstr is None:
   526                     self.rqlexec('DELETE X constrained_by C WHERE C eid %(x)s',
   526                     self.rqlexec('DELETE X constrained_by C WHERE C eid %(x)s',
   527                                  {'x': cstr.eid}, 'x',
   527                                  {'x': cstr.eid}, ask_confirm=confirm)
   528                                  ask_confirm=confirm)
       
   529                 else:
   528                 else:
   530                     newconstraints.remove(newcstr)
   529                     newconstraints.remove(newcstr)
   531                     value = unicode(newcstr.serialize())
   530                     value = unicode(newcstr.serialize())
   532                     if value != unicode(cstr.serialize()):
   531                     if value != unicode(cstr.serialize()):
   533                         self.rqlexec('SET X value %(v)s WHERE X eid %(x)s',
   532                         self.rqlexec('SET X value %(v)s WHERE X eid %(x)s',
   534                                      {'x': cstr.eid, 'v': value}, 'x',
   533                                      {'x': cstr.eid, 'v': value},
   535                                      ask_confirm=confirm)
   534                                      ask_confirm=confirm)
   536             # 2. add new constraints
   535             # 2. add new constraints
   537             cstrtype_map = self.cstrtype_mapping()
   536             cstrtype_map = self.cstrtype_mapping()
   538             self.rqlexecall(ss.constraints2rql(cstrtype_map, newconstraints,
   537             self.rqlexecall(ss.constraints2rql(cstrtype_map, newconstraints,
   539                                                repordef.eid),
   538                                                repordef.eid),
   642                     if (fromtype, totype) not in removedcubes_schema[rschema.type].rdefs and \
   641                     if (fromtype, totype) not in removedcubes_schema[rschema.type].rdefs and \
   643                            (fromtype, totype) in reposchema[rschema.type].rdefs:
   642                            (fromtype, totype) in reposchema[rschema.type].rdefs:
   644                         self.cmd_drop_relation_definition(
   643                         self.cmd_drop_relation_definition(
   645                             str(fromtype), rschema.type, str(totype))
   644                             str(fromtype), rschema.type, str(totype))
   646         # execute post-remove files
   645         # execute post-remove files
   647         for pack in reversed(removedcubes):
   646         for cube in reversed(removedcubes):
   648             self.exec_event_script('postremove', self.config.cube_dir(pack))
   647             self.exec_event_script('postremove', self.config.cube_dir(cube))
   649             self.rqlexec('DELETE CWProperty X WHERE X pkey %(pk)s',
   648             self.rqlexec('DELETE CWProperty X WHERE X pkey %(pk)s',
   650                          {'pk': u'system.version.'+pack}, ask_confirm=False)
   649                          {'pk': u'system.version.'+cube}, ask_confirm=False)
   651             self.commit()
   650             self.commit()
   652 
   651 
   653     # schema migration actions ################################################
   652     # schema migration actions ################################################
   654 
   653 
   655     def cmd_add_attribute(self, etype, attrname, attrtype=None, commit=True):
   654     def cmd_add_attribute(self, etype, attrname, attrtype=None, commit=True):
   734             except KeyError:
   733             except KeyError:
   735                 # specialized entity type not in schema, ignore
   734                 # specialized entity type not in schema, ignore
   736                 continue
   735                 continue
   737             if instspschema.specializes() != eschema:
   736             if instspschema.specializes() != eschema:
   738                 self.rqlexec('SET D specializes P WHERE D eid %(d)s, P name %(pn)s',
   737                 self.rqlexec('SET D specializes P WHERE D eid %(d)s, P name %(pn)s',
   739                              {'d': instspschema.eid,
   738                              {'d': instspschema.eid, 'pn': eschema.type},
   740                               'pn': eschema.type}, ask_confirm=confirm)
   739                              ask_confirm=confirm)
   741                 for rschema, tschemas, role in spschema.relation_definitions(True):
   740                 for rschema, tschemas, role in spschema.relation_definitions(True):
   742                     for tschema in tschemas:
   741                     for tschema in tschemas:
   743                         if not tschema in instschema:
   742                         if not tschema in instschema:
   744                             continue
   743                             continue
   745                         if role == 'subject':
   744                         if role == 'subject':
  1071         if not isinstance(wfof, (list, tuple)):
  1070         if not isinstance(wfof, (list, tuple)):
  1072             wfof = (wfof,)
  1071             wfof = (wfof,)
  1073         for etype in wfof:
  1072         for etype in wfof:
  1074             rset = self.rqlexec(
  1073             rset = self.rqlexec(
  1075                 'SET X workflow_of ET WHERE X eid %(x)s, ET name %(et)s',
  1074                 'SET X workflow_of ET WHERE X eid %(x)s, ET name %(et)s',
  1076                 {'x': wf.eid, 'et': etype}, 'x', ask_confirm=False)
  1075                 {'x': wf.eid, 'et': etype}, ask_confirm=False)
  1077             assert rset, 'unexistant entity type %s' % etype
  1076             assert rset, 'unexistant entity type %s' % etype
  1078             if default:
  1077             if default:
  1079                 self.rqlexec(
  1078                 self.rqlexec(
  1080                     'SET ET default_workflow X WHERE X eid %(x)s, ET name %(et)s',
  1079                     'SET ET default_workflow X WHERE X eid %(x)s, ET name %(et)s',
  1081                     {'x': wf.eid, 'et': etype}, 'x', ask_confirm=False)
  1080                     {'x': wf.eid, 'et': etype}, ask_confirm=False)
  1082         if commit:
  1081         if commit:
  1083             self.commit()
  1082             self.commit()
  1084         return wf
  1083         return wf
  1085 
  1084 
  1086     # XXX remove once cmd_add_[state|transition] are removed
  1085     # XXX remove once cmd_add_[state|transition] are removed
  1200                 return
  1199                 return
  1201 
  1200 
  1202     def rqlexec(self, rql, kwargs=None, cachekey=None, build_descr=True,
  1201     def rqlexec(self, rql, kwargs=None, cachekey=None, build_descr=True,
  1203                 ask_confirm=True):
  1202                 ask_confirm=True):
  1204         """rql action"""
  1203         """rql action"""
       
  1204         if cachekey is not None:
       
  1205             warn('[3.8] cachekey is deprecated, you can safely remove this argument',
       
  1206                  DeprecationWarning, stacklevel=2)
  1205         if not isinstance(rql, (tuple, list)):
  1207         if not isinstance(rql, (tuple, list)):
  1206             rql = ( (rql, kwargs), )
  1208             rql = ( (rql, kwargs), )
  1207         res = None
  1209         res = None
  1208         execute = self._cw.execute
  1210         execute = self._cw.execute
  1209         for rql, kwargs in rql:
  1211         for rql, kwargs in rql:
  1211                 msg = '%s (%s)' % (rql, kwargs)
  1213                 msg = '%s (%s)' % (rql, kwargs)
  1212             else:
  1214             else:
  1213                 msg = rql
  1215                 msg = rql
  1214             if not ask_confirm or self.confirm('Execute rql: %s ?' % msg):
  1216             if not ask_confirm or self.confirm('Execute rql: %s ?' % msg):
  1215                 try:
  1217                 try:
  1216                     res = execute(rql, kwargs, cachekey, build_descr=build_descr)
  1218                     res = execute(rql, kwargs, build_descr=build_descr)
  1217                 except Exception, ex:
  1219                 except Exception, ex:
  1218                     if self.confirm('Error: %s\nabort?' % ex):
  1220                     if self.confirm('Error: %s\nabort?' % ex):
  1219                         raise
  1221                         raise
  1220         return res
  1222         return res
  1221 
  1223