Mercurial > urweb
comparison demo/batchFun.ur @ 650:fcf0bd3d1667
BatchG demo
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 10 Mar 2009 16:38:38 -0400 |
parents | |
children | 1fb318c17546 |
comparison
equal
deleted
inserted
replaced
649:96ebc6bdb5a0 | 650:fcf0bd3d1667 |
---|---|
1 con colMeta = fn t_state :: (Type * Type) => | |
2 {Nam : string, | |
3 Show : t_state.1 -> xbody, | |
4 Inject : sql_injectable t_state.1, | |
5 | |
6 NewState : transaction t_state.2, | |
7 Widget : t_state.2 -> xbody, | |
8 ReadState : t_state.2 -> transaction t_state.1} | |
9 con colsMeta = fn cols :: {(Type * Type)} => $(map colMeta cols) | |
10 | |
11 fun default (t ::: Type) (sh : show t) (rd : read t) (inj : sql_injectable t) | |
12 name : colMeta (t, source string) = | |
13 {Nam = name, | |
14 Show = txt, | |
15 Inject = _, | |
16 | |
17 NewState = source "", | |
18 Widget = fn s => <xml><ctextbox source={s}/></xml>, | |
19 ReadState = fn s => v <- get s; return (readError v)} | |
20 | |
21 val int = default | |
22 val float = default | |
23 val string = default | |
24 | |
25 functor Make(M : sig | |
26 con cols :: {(Type * Type)} | |
27 constraint [Id] ~ cols | |
28 val fl : folder cols | |
29 | |
30 val tab : sql_table ([Id = int] ++ map fst cols) | |
31 | |
32 val title : string | |
33 | |
34 val cols : colsMeta cols | |
35 end) = struct | |
36 | |
37 open constraints M | |
38 val t = M.tab | |
39 | |
40 datatype list t = Nil | Cons of t * list t | |
41 | |
42 fun allRows () = | |
43 query (SELECT * FROM t) | |
44 (fn r acc => return (Cons (r.T, acc))) | |
45 Nil | |
46 | |
47 fun add r = | |
48 dml (insert t | |
49 (foldR2 [fst] [colMeta] | |
50 [fn cols => $(map (fn t :: (Type * Type) => | |
51 sql_exp [] [] [] t.1) cols)] | |
52 (fn (nm :: Name) (t :: (Type * Type)) (rest :: {(Type * Type)}) | |
53 [[nm] ~ rest] input col acc => | |
54 acc ++ {nm = @sql_inject col.Inject input}) | |
55 {} [M.cols] M.fl (r -- #Id) M.cols | |
56 ++ {Id = (SQL {[r.Id]})})) | |
57 | |
58 fun doBatch ls = | |
59 case ls of | |
60 Nil => return () | |
61 | Cons (r, ls') => | |
62 add r; | |
63 doBatch ls' | |
64 | |
65 fun del id = | |
66 dml (DELETE FROM t WHERE t.Id = {[id]}) | |
67 | |
68 fun show withDel lss = | |
69 let | |
70 fun show' ls = | |
71 case ls of | |
72 Nil => <xml/> | |
73 | Cons (r, ls) => <xml> | |
74 <tr> | |
75 <td>{[r.Id]}</td> | |
76 {foldRX2 [colMeta] [fst] [_] | |
77 (fn (nm :: Name) (p :: (Type * Type)) (rest :: {(Type * Type)}) | |
78 [[nm] ~ rest] m v => | |
79 <xml><td>{m.Show v}</td></xml>) | |
80 [M.cols] M.fl M.cols (r -- #Id)} | |
81 {if withDel then | |
82 <xml><td><button value="Delete" onclick={del r.Id}/></td></xml> | |
83 else | |
84 <xml/>} | |
85 </tr> | |
86 {show' ls} | |
87 </xml> | |
88 in | |
89 <xml><dyn signal={ls <- signal lss; return <xml><table> | |
90 <tr> | |
91 <th>Id</th> | |
92 {foldRX [colMeta] [_] | |
93 (fn (nm :: Name) (p :: (Type * Type)) (rest :: {(Type * Type)}) | |
94 [[nm] ~ rest] m => | |
95 <xml><th>{[m.Nam]}</th></xml>) | |
96 [M.cols] M.fl M.cols} | |
97 </tr> | |
98 {show' ls} | |
99 </table></xml>}/></xml> | |
100 end | |
101 | |
102 fun main () = | |
103 lss <- source Nil; | |
104 batched <- source Nil; | |
105 | |
106 id <- source ""; | |
107 inps <- foldR [colMeta] [fn r => transaction ($(map snd r))] | |
108 (fn (nm :: Name) (p :: (Type * Type)) (rest :: {(Type * Type)}) [[nm] ~ rest] m acc => | |
109 s <- m.NewState; | |
110 r <- acc; | |
111 return ({nm = s} ++ r)) | |
112 (return {}) | |
113 [M.cols] M.fl M.cols; | |
114 | |
115 let | |
116 fun add () = | |
117 id <- get id; | |
118 vs <- foldR2 [colMeta] [snd] [fn r => transaction ($(map fst r))] | |
119 (fn (nm :: Name) (p :: (Type * Type)) (rest :: {(Type * Type)}) | |
120 [[nm] ~ rest] m s acc => | |
121 v <- m.ReadState s; | |
122 r <- acc; | |
123 return ({nm = v} ++ r)) | |
124 (return {}) | |
125 [M.cols] M.fl M.cols inps; | |
126 ls <- get batched; | |
127 | |
128 set batched (Cons ({Id = readError id} ++ vs, ls)) | |
129 | |
130 fun exec () = | |
131 ls <- get batched; | |
132 | |
133 doBatch ls; | |
134 set batched Nil | |
135 in | |
136 return <xml><body> | |
137 <h2>Rows</h2> | |
138 | |
139 {show True lss} | |
140 | |
141 <button value="Update" onclick={ls <- allRows (); set lss ls}/><br/> | |
142 <br/> | |
143 | |
144 <h2>Batch new rows to add</h2> | |
145 | |
146 <table> | |
147 <tr> <th>Id:</th> <td><ctextbox source={id}/></td> </tr> | |
148 {foldRX2 [colMeta] [snd] [_] | |
149 (fn (nm :: Name) (p :: (Type * Type)) (rest :: {(Type * Type)}) | |
150 [[nm] ~ rest] m s => | |
151 <xml><tr> <th>{[m.Nam]}:</th> <td>{m.Widget s}</td> </tr></xml>) | |
152 [M.cols] M.fl M.cols inps} | |
153 <tr> <th/> <td><button value="Batch it" onclick={add ()}/></td> </tr> | |
154 </table> | |
155 | |
156 <h2>Already batched:</h2> | |
157 {show False batched} | |
158 <button value="Execute" onclick={exec ()}/> | |
159 </body></xml> | |
160 end | |
161 | |
162 end |