1 (* OCaml code generation *)
12 let inline_values = String.concat
" "
14 let quote = String.replace_chars
(function '
\n'
-> "\\n\\\n" | '
\r'
-> "" | '
"' -> "\\\"" | c -> String.make 1 c)
15 let quote s = "\"" ^ quote s ^ "\""
17 let rec replace_all ~str ~sub ~by =
18 match String.replace ~str ~sub ~by with
19 | (true,s) -> replace_all ~str:s ~sub ~by
22 let quote_comment_inline str =
23 let str = replace_all ~str ~sub:"*)
" ~by:"* )" in
24 replace_all ~str ~sub:"(*" ~by:"( *"
26 let make_comment str = "(* " ^ (quote_comment_inline str) ^ " *)"
27 let comment () fmt = Printf.kprintf (indent_endline & make_comment) fmt
29 let empty_line () = print_newline ()
31 let get_column attr index =
32 output "(T.get_column_%s stmt %u
)"
33 (Type.to_string attr.RA.domain)
36 let param_type_to_string t = Option.map_default Type.to_string "Any
" t
38 let set_param index param =
40 output "T.set_param_%s stmt %u %s
;"
41 (param_type_to_string t)
43 (param_name_to_string id index)
45 let output_schema_binder index schema =
46 let name = "invoke_callback
" in
47 output "let %s stmt
=" name;
51 List.iteri (fun index attr -> get_column attr index) schema;
57 let output_schema_binder index schema =
60 | _ -> Some (output_schema_binder index schema)
62 let params_to_values = List.mapi (fun i (n,_) -> param_name_to_string n i)
63 let params_to_values = List.unique & params_to_values
65 let output_params_binder index params =
66 output "let set_params stmt
=";
68 List.iteri set_param params;
74 let output_params_binder index params =
76 | [] -> "(fun _
-> ())"
77 | _ -> output_params_binder index params
79 let prepend prefix = function s -> prefix ^ s
85 let generate_stmt index stmt =
86 let name = choose_name stmt.props stmt.kind index >> String.uncapitalize in
87 let values = params_to_values stmt.params >> List.map (prepend "~
") >> inline_values in
88 let all_params = match stmt.schema with [] -> values | _ -> "callback
" ^ values in
89 output "let %s db %s
=" name all_params;
91 let sql = quote (get_sql stmt) in
92 let schema_binder_name = output_schema_binder index stmt.schema in
93 let params_binder_name = output_params_binder index stmt.params in
94 begin match schema_binder_name with
96 output "T.execute db %s %s
" sql params_binder_name
97 | Some schema_binder_name ->
98 output "T.select db %s %s %s
" sql schema_binder_name params_binder_name
103 let generate () name stmts =
104 output "module %s
(T
: Sqlgg_traits.M
) = struct" (String.capitalize name);
107 Enum.iteri generate_stmt stmts;
109 output "end (* module %s *)" (String.capitalize name)