adamc@1004
|
1 open Meta
|
adamc@1004
|
2
|
adamc@1004
|
3 functor Make(M : sig
|
adamc@1004
|
4 con keyName :: Name
|
adamc@1004
|
5 con keyType :: Type
|
adamc@1004
|
6 val showKey : show keyType
|
adamc@1005
|
7 val readKey : read keyType
|
adamc@1005
|
8 val injKey : sql_injectable keyType
|
adamc@1004
|
9
|
adamc@1004
|
10 con visible :: {(Type * Type)}
|
adamc@1004
|
11 constraint [keyName] ~ visible
|
adamc@1004
|
12 val folder : folder visible
|
adamc@1004
|
13 val visible : $(map Meta.meta visible)
|
adamc@1004
|
14
|
adamc@1004
|
15 con invisible :: {Type}
|
adamc@1004
|
16 constraint [keyName] ~ invisible
|
adamc@1004
|
17 constraint visible ~ invisible
|
adamc@1004
|
18
|
adamc@1004
|
19 val title : string
|
adamc@1004
|
20 val isAllowed : transaction bool
|
adamc@1004
|
21 table t : ([keyName = keyType] ++ map fst visible ++ invisible)
|
adamc@1004
|
22 end) = struct
|
adamc@1004
|
23
|
adamc@1004
|
24 open M
|
adamc@1004
|
25
|
adamc@1005
|
26 fun ensql [avail] (r : $(map snd visible)) : $(map (sql_exp avail [] []) (map fst visible)) =
|
adamc@1005
|
27 map2 [meta] [snd] [fn ts :: (Type * Type) => sql_exp avail [] [] ts.1]
|
adamc@1005
|
28 (fn [ts] meta v => @sql_inject meta.Inject (meta.Parse v))
|
adamc@1005
|
29 [_] folder visible r
|
adamc@1005
|
30
|
adamc@1004
|
31 fun main () =
|
adamc@1004
|
32 items <- queryX (SELECT t.{keyName}, t.{{map fst visible}} FROM t)
|
adamc@1004
|
33 (fn r => <xml><entry><tr>
|
adamc@1004
|
34 <hidden{keyName} value={show r.T.keyName}/>
|
adamc@1004
|
35 {useMore (foldR2 [meta] [fst] [fn cols :: {(Type * Type)} =>
|
adamc@1004
|
36 xml [Body, Form, Tr] [] (map snd cols)]
|
adamc@1004
|
37 (fn [nm :: Name] [p :: (Type * Type)] [rest :: {(Type * Type)}] [[nm] ~ rest]
|
adamc@1004
|
38 (m : meta p) v (acc : xml [Body, Form, Tr] [] (map snd rest)) =>
|
adamc@1004
|
39 <xml>
|
adamc@1004
|
40 <td>{m.WidgetPopulated [nm] v}</td>
|
adamc@1004
|
41 {useMore acc}
|
adamc@1004
|
42 </xml>)
|
adamc@1004
|
43 <xml/>
|
adamc@1004
|
44 [_] folder visible (r.T -- keyName))}
|
adamc@1004
|
45 </tr></entry></xml>);
|
adamc@1004
|
46
|
adamc@1004
|
47 return <xml><body>
|
adamc@1004
|
48 <h1>{[title]}</h1>
|
adamc@1004
|
49
|
adamc@1004
|
50 <form><table>
|
adamc@1004
|
51 <tr>{foldRX [meta] [_]
|
adamc@1004
|
52 (fn [nm :: Name] [p :: (Type * Type)] [rest :: {(Type * Type)}] [[nm] ~ rest] m =>
|
adamc@1004
|
53 <xml><th>{[m.Nam]}</th></xml>) [_] folder visible}</tr>
|
adamc@1004
|
54 <subforms{#Users}>{items}</subforms>
|
adamc@1005
|
55 <tr> <td><submit value="Save" action={save}/></td> </tr>
|
adamc@1004
|
56 </table></form>
|
adamc@1004
|
57 </body></xml>
|
adamc@1004
|
58
|
adamc@1005
|
59 and save r =
|
adamc@1005
|
60 List.app (fn user => dml (update [map fst visible] !
|
adamc@1005
|
61 (ensql (user -- keyName))
|
adamc@1005
|
62 t
|
adamc@1005
|
63 (WHERE t.{keyName} = {[readError user.keyName]}))) r.Users;
|
adamc@1005
|
64 main ()
|
adamc@1005
|
65
|
adamc@1004
|
66 end
|