1 import Base 2 import ./change_tick.bend as Tick 3 import ./world.bend as W 4 import ./compose.bend as Q 5 import ./transaction.bend as T 6 import ./commands.bend as Cmd 7 8 # Ordinary query selection and access stay in Q.Frame. The affine accumulator is 9 # outside the transaction journal and survives each entered row, including error. 10 type Executed is Type: 11 Executed{world:World,capture:L,outcome:T.Outcome,values:List<&2,Out>} 12 def prepend(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,value:Out,observed:L & (T.Tx,E> & (T.Outcome> & List<&2,Out>))) -> L & (T.Tx,E> & (T.Outcome> & List<&2,Out>)): 13 match observed: 14 case (capture,(tx,(status,values))):(capture,(tx,(status,value <> values))) 15 def completed(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,next:L -> T.Tx,E> -> L & (T.Tx,E> & (T.Outcome> & List<&2,Out>)),capture:L,tx:T.Tx,E>,value:Out,status:T.Outcome>) -> L & (T.Tx,E> & (T.Outcome> & List<&2,Out>)): 16 match status: 17 case T.Success{}:prepend(~S,~C,~R,~E,~L,~U,~Out,value,next(capture,tx)) 18 case T.Failure{error}:(capture,(tx,(T.Failure{error},[]))) 19 def body_returned(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,next:L -> T.Tx,E> -> L & (T.Tx,E> & (T.Outcome> & List<&2,Out>)),observed:Q.Frame & (L & (T.Outcome & Out))) -> L & (T.Tx,E> & (T.Outcome> & List<&2,Out>)): 20 match observed: 21 case (Q.Frame{tx,_,internal,_},(capture,(user,value))):completed(~S,~C,~R,~E,~L,~U,~Out,next,capture,tx,value,Q.outcome(~U,internal,user)) 22 def selected(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,~Ops:Type -> Type,~A:Data,~plan:Q.Plan,~body:@-H:Type -> @-caps:Ops(H) -> L -> A -> H -> H & (L & (T.Outcome & Out)),args:A,capture:L,next:L -> T.Tx,E> -> L & (T.Tx,E> & (T.Outcome> & List<&2,Out>)),observed:Q.Frame & Bool) -> L & (T.Tx,E> & (T.Outcome> & List<&2,Out>)): 23 match observed: 24 case (Q.Frame{tx,_,_,_},False{}):next(capture,tx) 25 case (frame,True{}):body_returned(~S,~C,~R,~E,~L,~U,~Out,next,body(Q.Frame,Q.plan_caps(~S,~C,~R,~E,~Ops,plan),capture,args,frame)) 26 def run_handles(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,~Ops:Type -> Type,~A:Data,~plan:Q.Plan,~body:@-H:Type -> @-caps:Ops(H) -> L -> A -> H -> H & (L & (T.Outcome & Out)),handles:List<&2,W.Handle>,+args:A,+cursor:Maybe<&2,Tick.Tick>,capture:L,tx:T.Tx,E>) -> L & (T.Tx,E> & (T.Outcome> & List<&2,Out>)): 27 match handles: 28 case []:(capture,(tx,(T.Success{},[]))) 29 case handle <> rest:selected(~S,~C,~R,~E,~L,~U,~Out,~Ops,~A,~plan,~body,args,capture,local => transaction => run_handles(~S,~C,~R,~E,~L,~U,~Out,~Ops,~A,~plan,~body,rest,args,cursor,local,transaction),Q.plan_select(~S,~C,~R,~E,~Ops,plan)(Q.Frame{tx,handle,None{},cursor})) 30 def returned(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,capture:L,values:List<&2,Out>,result:T.Returned,Q.Error>) -> Executed,L,Q.Error,Out>: 31 match result: 32 case T.Returned{world,T.Success{}}:Executed{world,capture,T.Success{},values} 33 case T.Returned{world,T.Failure{error}}:Executed{world,capture,T.Failure{error},[]} 34 def finished(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,observed:L & (T.Tx,E> & (T.Outcome> & List<&2,Out>))) -> Executed,L,Q.Error,Out>: 35 match observed: 36 case (capture,(tx,(status,values))):returned(~S,~C,~R,~E,~L,~U,~Out,capture,values,Cmd.tx_finish(~S,~C,~R,~E,~Q.Error,tx,status)) 37 def scope_finished(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,owned:Bool,result:Executed,L,Q.Error,Out>) -> Executed,L,Q.Error,Out>: 38 match result: 39 case Executed{world,capture,outcome,values}:Executed{W.finish_run(~S,~C,~R,~E,owned,world),capture,outcome,values} 40 def reserved_inner(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,~Ops:Type -> Type,~A:Data,~plan:Q.Plan,~body:@-H:Type -> @-caps:Ops(H) -> L -> A -> H -> H & (L & (T.Outcome & Out)),args:A,cursor:Maybe<&2,Tick.Tick>,capture:L,result:W.World & List<&2,W.Handle>) -> Executed,L,Q.Error,Out>: 41 (world,handles) = result 42 finished(~S,~C,~R,~E,~L,~U,~Out,run_handles(~S,~C,~R,~E,~L,~U,~Out,~Ops,~A,~plan,~body,handles,args,cursor,capture,T.begin(~W.World,~E,world))) 43 def reserved_scoped(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,~Ops:Type -> Type,~A:Data,~plan:Q.Plan,~body:@-H:Type -> @-caps:Ops(H) -> L -> A -> H -> H & (L & (T.Outcome & Out)),args:A,cursor:Maybe<&2,Tick.Tick>,capture:L,handles:List<&2,W.Handle>,admitted:W.World & Bool) -> Executed,L,Q.Error,Out>: 44 (world,owned)=admitted 45 scope_finished(~S,~C,~R,~E,~L,~U,~Out,owned,reserved_inner(~S,~C,~R,~E,~L,~U,~Out,~Ops,~A,~plan,~body,args,cursor,capture,(world,handles))) 46 def reserved(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,~Ops:Type -> Type,~A:Data,~plan:Q.Plan,~body:@-H:Type -> @-caps:Ops(H) -> L -> A -> H -> H & (L & (T.Outcome & Out)),args:A,cursor:Maybe<&2,Tick.Tick>,capture:L,result:W.World & List<&2,W.Handle>) -> Executed,L,Q.Error,Out>: 47 (world,handles)=result 48 reserved_scoped(~S,~C,~R,~E,~L,~U,~Out,~Ops,~A,~plan,~body,args,cursor,capture,handles,W.ensure_run(~S,~C,~R,~E,world)) 49 50 def each_since(~S:Data,~C:Type,~R:Type,~E:Data,~L:Type,~U:Data,~Out:Data,~Ops:Type -> Type,~A:Data,~plan:Q.Plan,~body:@-H:Type -> @-caps:Ops(H) -> L -> A -> H -> H & (L & (T.Outcome & Out)),args:A,cursor:Maybe<&2,Tick.Tick>,capture:L,world:W.World) -> Executed,L,Q.Error,Out>: 51 reserved(~S,~C,~R,~E,~L,~U,~Out,~Ops,~A,~plan,~body,args,cursor,capture,W.handles(~S,~C,~R,~E,world))