comparison lib/ur/top.ur @ 682:5bbb542243e8

Redo channels, making them single-client
author Adam Chlipala <adamc@hcoop.net>
date Sun, 29 Mar 2009 11:37:29 -0400
parents e5894f0e541a
children 9a2c18dab11d
comparison
equal deleted inserted replaced
681:6c9b8875f347 682:5bbb542243e8
141 (fn (nm :: Name) (t :: K) (rest :: {K}) [[nm] ~ rest] 141 (fn (nm :: Name) (t :: K) (rest :: {K}) [[nm] ~ rest]
142 r1 r2 acc => 142 r1 r2 acc =>
143 <xml>{f [nm] [t] [rest] ! r1 r2}{acc}</xml>) 143 <xml>{f [nm] [t] [rest] ! r1 r2}{acc}</xml>)
144 <xml/> 144 <xml/>
145 145
146 fun queryI (tables ::: {{Type}}) (exps ::: {Type})
147 [tables ~ exps] (q : sql_query tables exps)
148 (f : $(exps ++ map (fn fields :: {Type} => $fields) tables)
149 -> transaction unit) =
150 query q
151 (fn fs _ => f fs)
152 ()
153
146 fun queryX (tables ::: {{Type}}) (exps ::: {Type}) (ctx ::: {Unit}) 154 fun queryX (tables ::: {{Type}}) (exps ::: {Type}) (ctx ::: {Unit})
147 [tables ~ exps] (q : sql_query tables exps) 155 [tables ~ exps] (q : sql_query tables exps)
148 (f : $(exps ++ map (fn fields :: {Type} => $fields) tables) 156 (f : $(exps ++ map (fn fields :: {Type} => $fields) tables)
149 -> xml ctx [] []) = 157 -> xml ctx [] []) =
150 query q 158 query q
186 (e1 : sql_exp tables agg exps (option t)) 194 (e1 : sql_exp tables agg exps (option t))
187 (e2 : option t) = 195 (e2 : option t) =
188 case e2 of 196 case e2 of
189 None => (SQL {e1} IS NULL) 197 None => (SQL {e1} IS NULL)
190 | Some _ => sql_binary sql_eq e1 (sql_inject e2) 198 | Some _ => sql_binary sql_eq e1 (sql_inject e2)
199
200
201 functor Broadcast(M : sig type t end) = struct
202 sequence s
203 table t : {Id : int, Client : option client, Channel : option (channel M.t)}
204
205 type topic = int
206
207 val inj : sql_injectable topic = _
208
209 val create = nextval s
210
211 val cleanup =
212 dml (DELETE FROM t WHERE Client IS NULL)
213
214 fun subscribe id =
215 cli <- self;
216 cleanup;
217 ro <- oneOrNoRows (SELECT t.Channel FROM t WHERE t.Id = {[id]} AND t.Client = {[Some cli]});
218 case ro of
219 None =>
220 ch <- channel;
221 dml (INSERT INTO t (Id, Client, Channel) VALUES ({[id]}, {[Some cli]}, {[Some ch]}));
222 return ch
223 | Some r =>
224 case r.T.Channel of
225 None => error <xml>Broadcast.subscribe: Got null result</xml>
226 | Some ch => return ch
227
228 fun send id msg =
229 cleanup;
230 queryI (SELECT t.Channel FROM t WHERE t.Id = {[id]})
231 (fn r => case r.T.Channel of
232 None => error <xml>Broadcast.send: Got null result</xml>
233 | Some ch => Basis.send ch msg)
234 end