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 |