entities/wfobjs.py
changeset 5174 78438ad513ca
parent 4835 13b0b96d7982
child 5224 34e669b6fd95
equal deleted inserted replaced
5173:73760bbb66bd 5174:78438ad513ca
    63     # state / transitions accessors ############################################
    63     # state / transitions accessors ############################################
    64 
    64 
    65     def state_by_name(self, statename):
    65     def state_by_name(self, statename):
    66         rset = self._cw.execute('Any S, SN WHERE S name SN, S name %(n)s, '
    66         rset = self._cw.execute('Any S, SN WHERE S name SN, S name %(n)s, '
    67                                 'S state_of WF, WF eid %(wf)s',
    67                                 'S state_of WF, WF eid %(wf)s',
    68                                 {'n': statename, 'wf': self.eid}, 'wf')
    68                                 {'n': statename, 'wf': self.eid})
    69         if rset:
    69         if rset:
    70             return rset.get_entity(0, 0)
    70             return rset.get_entity(0, 0)
    71         return None
    71         return None
    72 
    72 
    73     def state_by_eid(self, eid):
    73     def state_by_eid(self, eid):
    74         rset = self._cw.execute('Any S, SN WHERE S name SN, S eid %(s)s, '
    74         rset = self._cw.execute('Any S, SN WHERE S name SN, S eid %(s)s, '
    75                                 'S state_of WF, WF eid %(wf)s',
    75                                 'S state_of WF, WF eid %(wf)s',
    76                                 {'s': eid, 'wf': self.eid}, ('wf', 's'))
    76                                 {'s': eid, 'wf': self.eid})
    77         if rset:
    77         if rset:
    78             return rset.get_entity(0, 0)
    78             return rset.get_entity(0, 0)
    79         return None
    79         return None
    80 
    80 
    81     def transition_by_name(self, trname):
    81     def transition_by_name(self, trname):
    82         rset = self._cw.execute('Any T, TN WHERE T name TN, T name %(n)s, '
    82         rset = self._cw.execute('Any T, TN WHERE T name TN, T name %(n)s, '
    83                                 'T transition_of WF, WF eid %(wf)s',
    83                                 'T transition_of WF, WF eid %(wf)s',
    84                                 {'n': trname, 'wf': self.eid}, 'wf')
    84                                 {'n': trname, 'wf': self.eid})
    85         if rset:
    85         if rset:
    86             return rset.get_entity(0, 0)
    86             return rset.get_entity(0, 0)
    87         return None
    87         return None
    88 
    88 
    89     def transition_by_eid(self, eid):
    89     def transition_by_eid(self, eid):
    90         rset = self._cw.execute('Any T, TN WHERE T name TN, T eid %(t)s, '
    90         rset = self._cw.execute('Any T, TN WHERE T name TN, T eid %(t)s, '
    91                                 'T transition_of WF, WF eid %(wf)s',
    91                                 'T transition_of WF, WF eid %(wf)s',
    92                                 {'t': eid, 'wf': self.eid}, ('wf', 't'))
    92                                 {'t': eid, 'wf': self.eid})
    93         if rset:
    93         if rset:
    94             return rset.get_entity(0, 0)
    94             return rset.get_entity(0, 0)
    95         return None
    95         return None
    96 
    96 
    97     # wf construction methods ##################################################
    97     # wf construction methods ##################################################
    98 
    98 
    99     def add_state(self, name, initial=False, **kwargs):
    99     def add_state(self, name, initial=False, **kwargs):
   100         """add a state to this workflow"""
   100         """add a state to this workflow"""
   101         state = self._cw.create_entity('State', name=unicode(name), **kwargs)
   101         state = self._cw.create_entity('State', name=unicode(name), **kwargs)
   102         self._cw.execute('SET S state_of WF WHERE S eid %(s)s, WF eid %(wf)s',
   102         self._cw.execute('SET S state_of WF WHERE S eid %(s)s, WF eid %(wf)s',
   103                          {'s': state.eid, 'wf': self.eid}, ('s', 'wf'))
   103                          {'s': state.eid, 'wf': self.eid})
   104         if initial:
   104         if initial:
   105             assert not self.initial, "Initial state already defined as %s" % self.initial
   105             assert not self.initial, "Initial state already defined as %s" % self.initial
   106             self._cw.execute('SET WF initial_state S '
   106             self._cw.execute('SET WF initial_state S '
   107                              'WHERE S eid %(s)s, WF eid %(wf)s',
   107                              'WHERE S eid %(s)s, WF eid %(wf)s',
   108                              {'s': state.eid, 'wf': self.eid}, ('s', 'wf'))
   108                              {'s': state.eid, 'wf': self.eid})
   109         return state
   109         return state
   110 
   110 
   111     def _add_transition(self, trtype, name, fromstates,
   111     def _add_transition(self, trtype, name, fromstates,
   112                         requiredgroups=(), conditions=(), **kwargs):
   112                         requiredgroups=(), conditions=(), **kwargs):
   113         tr = self._cw.create_entity(trtype, name=unicode(name), **kwargs)
   113         tr = self._cw.create_entity(trtype, name=unicode(name), **kwargs)
   114         self._cw.execute('SET T transition_of WF '
   114         self._cw.execute('SET T transition_of WF '
   115                          'WHERE T eid %(t)s, WF eid %(wf)s',
   115                          'WHERE T eid %(t)s, WF eid %(wf)s',
   116                          {'t': tr.eid, 'wf': self.eid}, ('t', 'wf'))
   116                          {'t': tr.eid, 'wf': self.eid})
   117         assert fromstates, fromstates
   117         assert fromstates, fromstates
   118         if not isinstance(fromstates, (tuple, list)):
   118         if not isinstance(fromstates, (tuple, list)):
   119             fromstates = (fromstates,)
   119             fromstates = (fromstates,)
   120         for state in fromstates:
   120         for state in fromstates:
   121             if hasattr(state, 'eid'):
   121             if hasattr(state, 'eid'):
   122                 state = state.eid
   122                 state = state.eid
   123             self._cw.execute('SET S allowed_transition T '
   123             self._cw.execute('SET S allowed_transition T '
   124                              'WHERE S eid %(s)s, T eid %(t)s',
   124                              'WHERE S eid %(s)s, T eid %(t)s',
   125                              {'s': state, 't': tr.eid}, ('s', 't'))
   125                              {'s': state, 't': tr.eid})
   126         tr.set_permissions(requiredgroups, conditions, reset=False)
   126         tr.set_permissions(requiredgroups, conditions, reset=False)
   127         return tr
   127         return tr
   128 
   128 
   129     def add_transition(self, name, fromstates, tostate=None,
   129     def add_transition(self, name, fromstates, tostate=None,
   130                        requiredgroups=(), conditions=(), **kwargs):
   130                        requiredgroups=(), conditions=(), **kwargs):
   134         if tostate is not None:
   134         if tostate is not None:
   135             if hasattr(tostate, 'eid'):
   135             if hasattr(tostate, 'eid'):
   136                 tostate = tostate.eid
   136                 tostate = tostate.eid
   137             self._cw.execute('SET T destination_state S '
   137             self._cw.execute('SET T destination_state S '
   138                              'WHERE S eid %(s)s, T eid %(t)s',
   138                              'WHERE S eid %(s)s, T eid %(t)s',
   139                              {'t': tr.eid, 's': tostate}, ('s', 't'))
   139                              {'t': tr.eid, 's': tostate})
   140         return tr
   140         return tr
   141 
   141 
   142     def add_wftransition(self, name, subworkflow, fromstates, exitpoints=(),
   142     def add_wftransition(self, name, subworkflow, fromstates, exitpoints=(),
   143                          requiredgroups=(), conditions=(), **kwargs):
   143                          requiredgroups=(), conditions=(), **kwargs):
   144         """add a workflow transition to this workflow"""
   144         """add a workflow transition to this workflow"""
   145         tr = self._add_transition('WorkflowTransition', name, fromstates,
   145         tr = self._add_transition('WorkflowTransition', name, fromstates,
   146                                   requiredgroups, conditions, **kwargs)
   146                                   requiredgroups, conditions, **kwargs)
   147         if hasattr(subworkflow, 'eid'):
   147         if hasattr(subworkflow, 'eid'):
   148             subworkflow = subworkflow.eid
   148             subworkflow = subworkflow.eid
   149         assert self._cw.execute('SET T subworkflow WF WHERE WF eid %(wf)s,T eid %(t)s',
   149         assert self._cw.execute('SET T subworkflow WF WHERE WF eid %(wf)s,T eid %(t)s',
   150                                 {'t': tr.eid, 'wf': subworkflow}, ('wf', 't'))
   150                                 {'t': tr.eid, 'wf': subworkflow})
   151         for fromstate, tostate in exitpoints:
   151         for fromstate, tostate in exitpoints:
   152             tr.add_exit_point(fromstate, tostate)
   152             tr.add_exit_point(fromstate, tostate)
   153         return tr
   153         return tr
   154 
   154 
   155     def replace_state(self, todelstate, replacement):
   155     def replace_state(self, todelstate, replacement):
   157         if not hasattr(todelstate, 'eid'):
   157         if not hasattr(todelstate, 'eid'):
   158             todelstate = self.state_by_name(todelstate)
   158             todelstate = self.state_by_name(todelstate)
   159         if not hasattr(replacement, 'eid'):
   159         if not hasattr(replacement, 'eid'):
   160             replacement = self.state_by_name(replacement)
   160             replacement = self.state_by_name(replacement)
   161         execute = self._cw.execute
   161         execute = self._cw.execute
   162         execute('SET X in_state S WHERE S eid %(s)s', {'s': todelstate.eid}, 's')
   162         execute('SET X in_state S WHERE S eid %(s)s', {'s': todelstate.eid})
   163         execute('SET X from_state NS WHERE X to_state OS, OS eid %(os)s, NS eid %(ns)s',
   163         execute('SET X from_state NS WHERE X to_state OS, OS eid %(os)s, NS eid %(ns)s',
   164                 {'os': todelstate.eid, 'ns': replacement.eid}, 's')
   164                 {'os': todelstate.eid, 'ns': replacement.eid})
   165         execute('SET X to_state NS WHERE X to_state OS, OS eid %(os)s, NS eid %(ns)s',
   165         execute('SET X to_state NS WHERE X to_state OS, OS eid %(os)s, NS eid %(ns)s',
   166                 {'os': todelstate.eid, 'ns': replacement.eid}, 's')
   166                 {'os': todelstate.eid, 'ns': replacement.eid})
   167         todelstate.delete()
   167         todelstate.delete()
   168 
   168 
   169 
   169 
   170 class BaseTransition(AnyEntity):
   170 class BaseTransition(AnyEntity):
   171     """customized class for abstract transition
   171     """customized class for abstract transition
   225         """set or add (if `reset` is False) groups and conditions for this
   225         """set or add (if `reset` is False) groups and conditions for this
   226         transition
   226         transition
   227         """
   227         """
   228         if reset:
   228         if reset:
   229             self._cw.execute('DELETE T require_group G WHERE T eid %(x)s',
   229             self._cw.execute('DELETE T require_group G WHERE T eid %(x)s',
   230                              {'x': self.eid}, 'x')
   230                              {'x': self.eid})
   231             self._cw.execute('DELETE T condition R WHERE T eid %(x)s',
   231             self._cw.execute('DELETE T condition R WHERE T eid %(x)s',
   232                              {'x': self.eid}, 'x')
   232                              {'x': self.eid})
   233         for gname in requiredgroups:
   233         for gname in requiredgroups:
   234             rset = self._cw.execute('SET T require_group G '
   234             rset = self._cw.execute('SET T require_group G '
   235                                     'WHERE T eid %(x)s, G name %(gn)s',
   235                                     'WHERE T eid %(x)s, G name %(gn)s',
   236                                     {'x': self.eid, 'gn': gname}, 'x')
   236                                     {'x': self.eid, 'gn': gname})
   237             assert rset, '%s is not a known group' % gname
   237             assert rset, '%s is not a known group' % gname
   238         if isinstance(conditions, basestring):
   238         if isinstance(conditions, basestring):
   239             conditions = (conditions,)
   239             conditions = (conditions,)
   240         for expr in conditions:
   240         for expr in conditions:
   241             if isinstance(expr, basestring):
   241             if isinstance(expr, basestring):
   245                 kwargs = expr
   245                 kwargs = expr
   246             kwargs['x'] = self.eid
   246             kwargs['x'] = self.eid
   247             kwargs.setdefault('mainvars', u'X')
   247             kwargs.setdefault('mainvars', u'X')
   248             self._cw.execute('INSERT RQLExpression X: X exprtype "ERQLExpression", '
   248             self._cw.execute('INSERT RQLExpression X: X exprtype "ERQLExpression", '
   249                              'X expression %(expr)s, X mainvars %(mainvars)s, '
   249                              'X expression %(expr)s, X mainvars %(mainvars)s, '
   250                              'T condition X WHERE T eid %(x)s',kwargs, 'x')
   250                              'T condition X WHERE T eid %(x)s', kwargs)
   251         # XXX clear caches?
   251         # XXX clear caches?
   252 
   252 
   253     @deprecated('[3.6.1] use set_permission')
   253     @deprecated('[3.6.1] use set_permission')
   254     def set_transition_permissions(self, requiredgroups=(), conditions=(),
   254     def set_transition_permissions(self, requiredgroups=(), conditions=(),
   255                                    reset=True):
   255                                    reset=True):
   297         if hasattr(fromstate, 'eid'):
   297         if hasattr(fromstate, 'eid'):
   298             fromstate = fromstate.eid
   298             fromstate = fromstate.eid
   299         if tostate is None:
   299         if tostate is None:
   300             self._cw.execute('INSERT SubWorkflowExitPoint X: T subworkflow_exit X, '
   300             self._cw.execute('INSERT SubWorkflowExitPoint X: T subworkflow_exit X, '
   301                              'X subworkflow_state FS WHERE T eid %(t)s, FS eid %(fs)s',
   301                              'X subworkflow_state FS WHERE T eid %(t)s, FS eid %(fs)s',
   302                              {'t': self.eid, 'fs': fromstate}, ('t', 'fs'))
   302                              {'t': self.eid, 'fs': fromstate})
   303         else:
   303         else:
   304             if hasattr(tostate, 'eid'):
   304             if hasattr(tostate, 'eid'):
   305                 tostate = tostate.eid
   305                 tostate = tostate.eid
   306             self._cw.execute('INSERT SubWorkflowExitPoint X: T subworkflow_exit X, '
   306             self._cw.execute('INSERT SubWorkflowExitPoint X: T subworkflow_exit X, '
   307                              'X subworkflow_state FS, X destination_state TS '
   307                              'X subworkflow_state FS, X destination_state TS '
   308                              'WHERE T eid %(t)s, FS eid %(fs)s, TS eid %(ts)s',
   308                              'WHERE T eid %(t)s, FS eid %(fs)s, TS eid %(ts)s',
   309                              {'t': self.eid, 'fs': fromstate, 'ts': tostate},
   309                              {'t': self.eid, 'fs': fromstate, 'ts': tostate})
   310                              ('t', 'fs', 'ts'))
       
   311 
   310 
   312     def get_exit_point(self, entity, stateeid):
   311     def get_exit_point(self, entity, stateeid):
   313         """if state is an exit point, return its associated destination state"""
   312         """if state is an exit point, return its associated destination state"""
   314         if hasattr(stateeid, 'eid'):
   313         if hasattr(stateeid, 'eid'):
   315             stateeid = stateeid.eid
   314             stateeid = stateeid.eid
   467         rset = self._cw.execute(
   466         rset = self._cw.execute(
   468             'Any T,TT, TN WHERE S allowed_transition T, S eid %(x)s, '
   467             'Any T,TT, TN WHERE S allowed_transition T, S eid %(x)s, '
   469             'T type TT, T type %(type)s, '
   468             'T type TT, T type %(type)s, '
   470             'T name TN, T transition_of WF, WF eid %(wfeid)s',
   469             'T name TN, T transition_of WF, WF eid %(wfeid)s',
   471             {'x': self.current_state.eid, 'type': type,
   470             {'x': self.current_state.eid, 'type': type,
   472              'wfeid': self.current_workflow.eid}, 'x')
   471              'wfeid': self.current_workflow.eid})
   473         for tr in rset.entities():
   472         for tr in rset.entities():
   474             if tr.may_be_fired(self.eid):
   473             if tr.may_be_fired(self.eid):
   475                 yield tr
   474                 yield tr
   476 
   475 
   477     def _add_trinfo(self, comment, commentformat, treid=None, tseid=None):
   476     def _add_trinfo(self, comment, commentformat, treid=None, tseid=None):