Mercurial > urweb
comparison demo/crud.ur @ 823:669ac5e9a69e
Demo compiles with pattern-matching-fu
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Thu, 28 May 2009 10:35:25 -0400 |
parents | 5819fb63c93a |
children | 74e9e7642f08 |
comparison
equal
deleted
inserted
replaced
822:d4e811beb8eb | 823:669ac5e9a69e |
---|---|
6 Parse : t_formT.2 -> t_formT.1, | 6 Parse : t_formT.2 -> t_formT.1, |
7 Inject : sql_injectable t_formT.1 | 7 Inject : sql_injectable t_formT.1 |
8 } | 8 } |
9 con colsMeta = fn cols :: {(Type * Type)} => $(map colMeta cols) | 9 con colsMeta = fn cols :: {(Type * Type)} => $(map colMeta cols) |
10 | 10 |
11 fun default (t ::: Type) (sh : show t) (rd : read t) (inj : sql_injectable t) | 11 fun default [t] (sh : show t) (rd : read t) (inj : sql_injectable t) |
12 name : colMeta (t, string) = | 12 name : colMeta (t, string) = |
13 {Nam = name, | 13 {Nam = name, |
14 Show = txt, | 14 Show = txt, |
15 Widget = fn nm :: Name => <xml><textbox{nm}/></xml>, | 15 Widget = fn [nm :: Name] => <xml><textbox{nm}/></xml>, |
16 WidgetPopulated = fn (nm :: Name) n => | 16 WidgetPopulated = fn [nm :: Name] n => |
17 <xml><textbox{nm} value={show n}/></xml>, | 17 <xml><textbox{nm} value={show n}/></xml>, |
18 Parse = readError, | 18 Parse = readError, |
19 Inject = _} | 19 Inject = _} |
20 | 20 |
21 val int = default | 21 val int = default |
22 val float = default | 22 val float = default |
23 val string = default | 23 val string = default |
24 | 24 |
25 fun bool name = {Nam = name, | 25 fun bool name = {Nam = name, |
26 Show = txt, | 26 Show = txt, |
27 Widget = fn nm :: Name => <xml><checkbox{nm}/></xml>, | 27 Widget = fn [nm :: Name] => <xml><checkbox{nm}/></xml>, |
28 WidgetPopulated = fn (nm :: Name) b => | 28 WidgetPopulated = fn [nm :: Name] b => |
29 <xml><checkbox{nm} checked={b}/></xml>, | 29 <xml><checkbox{nm} checked={b}/></xml>, |
30 Parse = fn x => x, | 30 Parse = fn x => x, |
31 Inject = _} | 31 Inject = _} |
32 | 32 |
33 functor Make(M : sig | 33 functor Make(M : sig |
51 rows <- queryX (SELECT * FROM tab AS T) | 51 rows <- queryX (SELECT * FROM tab AS T) |
52 (fn (fs : {T : $([Id = int] ++ map fst M.cols)}) => <xml> | 52 (fn (fs : {T : $([Id = int] ++ map fst M.cols)}) => <xml> |
53 <tr> | 53 <tr> |
54 <td>{[fs.T.Id]}</td> | 54 <td>{[fs.T.Id]}</td> |
55 {foldRX2 [fst] [colMeta] [tr] | 55 {foldRX2 [fst] [colMeta] [tr] |
56 (fn (nm :: Name) (t :: (Type * Type)) (rest :: {(Type * Type)}) | 56 (fn [nm :: Name] [t :: (Type * Type)] [rest :: {(Type * Type)}] |
57 [[nm] ~ rest] v col => <xml> | 57 [[nm] ~ rest] v col => <xml> |
58 <td>{col.Show v}</td> | 58 <td>{col.Show v}</td> |
59 </xml>) | 59 </xml>) |
60 [M.cols] M.fl (fs.T -- #Id) M.cols} | 60 [M.cols] M.fl (fs.T -- #Id) M.cols} |
61 <td> | 61 <td> |
67 return <xml> | 67 return <xml> |
68 <table border={1}> | 68 <table border={1}> |
69 <tr> | 69 <tr> |
70 <th>ID</th> | 70 <th>ID</th> |
71 {foldRX [colMeta] [tr] | 71 {foldRX [colMeta] [tr] |
72 (fn (nm :: Name) (t :: (Type * Type)) (rest :: {(Type * Type)}) | 72 (fn [nm :: Name] [t :: (Type * Type)] [rest :: {(Type * Type)}] |
73 [[nm] ~ rest] col => <xml> | 73 [[nm] ~ rest] col => <xml> |
74 <th>{cdata col.Nam}</th> | 74 <th>{cdata col.Nam}</th> |
75 </xml>) | 75 </xml>) |
76 [M.cols] M.fl M.cols} | 76 [M.cols] M.fl M.cols} |
77 </tr> | 77 </tr> |
80 | 80 |
81 <br/><hr/><br/> | 81 <br/><hr/><br/> |
82 | 82 |
83 <form> | 83 <form> |
84 {foldR [colMeta] [fn cols :: {(Type * Type)} => xml form [] (map snd cols)] | 84 {foldR [colMeta] [fn cols :: {(Type * Type)} => xml form [] (map snd cols)] |
85 (fn (nm :: Name) (t :: (Type * Type)) (rest :: {(Type * Type)}) | 85 (fn [nm :: Name] [t :: (Type * Type)] [rest :: {(Type * Type)}] |
86 [[nm] ~ rest] (col : colMeta t) (acc : xml form [] (map snd rest)) => <xml> | 86 [[nm] ~ rest] (col : colMeta t) (acc : xml form [] (map snd rest)) => <xml> |
87 <li> {cdata col.Nam}: {col.Widget [nm]}</li> | 87 <li> {cdata col.Nam}: {col.Widget [nm]}</li> |
88 {useMore acc} | 88 {useMore acc} |
89 </xml>) | 89 </xml>) |
90 <xml/> | 90 <xml/> |
98 id <- nextval seq; | 98 id <- nextval seq; |
99 dml (insert tab | 99 dml (insert tab |
100 (foldR2 [snd] [colMeta] | 100 (foldR2 [snd] [colMeta] |
101 [fn cols => $(map (fn t :: (Type * Type) => | 101 [fn cols => $(map (fn t :: (Type * Type) => |
102 sql_exp [] [] [] t.1) cols)] | 102 sql_exp [] [] [] t.1) cols)] |
103 (fn (nm :: Name) (t :: (Type * Type)) (rest :: {(Type * Type)}) | 103 (fn [nm :: Name] [t :: (Type * Type)] [rest :: {(Type * Type)}] |
104 [[nm] ~ rest] => | 104 [[nm] ~ rest] => |
105 fn input col acc => acc ++ {nm = @sql_inject col.Inject (col.Parse input)}) | 105 fn input col acc => acc ++ {nm = @sql_inject col.Inject (col.Parse input)}) |
106 {} [M.cols] M.fl inputs M.cols | 106 {} [M.cols] M.fl inputs M.cols |
107 ++ {Id = (SQL {[id]})})); | 107 ++ {Id = (SQL {[id]})})); |
108 ls <- list (); | 108 ls <- list (); |
119 (foldR2 [snd] [colMeta] | 119 (foldR2 [snd] [colMeta] |
120 [fn cols => $(map (fn t :: (Type * Type) => | 120 [fn cols => $(map (fn t :: (Type * Type) => |
121 sql_exp [T = [Id = int] | 121 sql_exp [T = [Id = int] |
122 ++ map fst M.cols] | 122 ++ map fst M.cols] |
123 [] [] t.1) cols)] | 123 [] [] t.1) cols)] |
124 (fn (nm :: Name) (t :: (Type * Type)) (rest :: {(Type * Type)}) | 124 (fn [nm :: Name] [t :: (Type * Type)] [rest :: {(Type * Type)}] |
125 [[nm] ~ rest] => | 125 [[nm] ~ rest] => |
126 fn input col acc => acc ++ {nm = | 126 fn input col acc => acc ++ {nm = |
127 @sql_inject col.Inject (col.Parse input)}) | 127 @sql_inject col.Inject (col.Parse input)}) |
128 {} [M.cols] M.fl inputs M.cols) | 128 {} [M.cols] M.fl inputs M.cols) |
129 tab (WHERE T.Id = {[id]})); | 129 tab (WHERE T.Id = {[id]})); |
137 fso <- oneOrNoRows (SELECT tab.{{map fst M.cols}} FROM tab WHERE tab.Id = {[id]}); | 137 fso <- oneOrNoRows (SELECT tab.{{map fst M.cols}} FROM tab WHERE tab.Id = {[id]}); |
138 case fso : (Basis.option {Tab : $(map fst M.cols)}) of | 138 case fso : (Basis.option {Tab : $(map fst M.cols)}) of |
139 None => return <xml><body>Not found!</body></xml> | 139 None => return <xml><body>Not found!</body></xml> |
140 | Some fs => return <xml><body><form> | 140 | Some fs => return <xml><body><form> |
141 {foldR2 [fst] [colMeta] [fn cols :: {(Type * Type)} => xml form [] (map snd cols)] | 141 {foldR2 [fst] [colMeta] [fn cols :: {(Type * Type)} => xml form [] (map snd cols)] |
142 (fn (nm :: Name) (t :: (Type * Type)) (rest :: {(Type * Type)}) | 142 (fn [nm :: Name] [t :: (Type * Type)] [rest :: {(Type * Type)}] |
143 [[nm] ~ rest] (v : t.1) (col : colMeta t) | 143 [[nm] ~ rest] (v : t.1) (col : colMeta t) |
144 (acc : xml form [] (map snd rest)) => | 144 (acc : xml form [] (map snd rest)) => |
145 <xml> | 145 <xml> |
146 <li> {cdata col.Nam}: {col.WidgetPopulated [nm] v}</li> | 146 <li> {cdata col.Nam}: {col.WidgetPopulated [nm] v}</li> |
147 {useMore acc} | 147 {useMore acc} |