1 (* C++ code generation *)
12 module Values = struct
15 String.concat ", " (List.map (fun (n,t) -> t ^ " " ^ n) x)
18 String.concat ", " (List.map (fun (n,t) -> n) x)
22 let quote = String.replace_chars (function '\n' -> "\\n\\\n" | '\r' -> "" | '"' -> "\\\"" | c -> String.make 1 c)
23 let quote s = "\"" ^ quote s ^ "\""
26 let rec replace_all ~str ~sub ~by
=
27 match String.replace ~str ~sub ~by
with
28 | (true,s
) -> replace_all ~str
:s ~sub ~by
31 let quote_comment_inline str
=
32 let str = replace_all ~
str ~sub
:"*)" ~by
:"* )" in
33 replace_all ~
str ~sub
:"(*" ~by
:"( *"
35 let make_comment str = "(* " ^
(quote_comment_inline str) ^
" *" ^
")"
36 let comment fmt
= Printf.kprintf
(indent_endline
& make_comment) fmt
39 let start_struct name =
40 output "struct %s" name;
43 close_curly "; // struct %s" name;
46 let name_of attr index =
47 match attr.RA.name with
48 | "" -> sprintf "_%u" index
51 let set_column attr index =
52 output "Traits::set_column_%s(stmt, %u, obj.%s);"
53 (Type.to_string attr.RA.domain)
57 let get_column attr index =
58 output "Traits::get_column_%s(stmt, %u, obj.%s);"
59 (Type.to_string attr.RA.domain)
61 (name_of attr (index+1))
63 let param_type_to_string t = Option.map_default Type.to_string "Any" t
64 let as_cxx_type str = "typename Traits::" ^ str
66 let set_param index param =
68 output "Traits::set_param_%s(stmt, %s, %u);"
69 (param_type_to_string t)
70 (param_name_to_string id index)
73 let output_scheme_binder index scheme =
75 let name = default_name "output" index in
76 output "template <class T>";
79 output "static void of_stmt(typename Traits::statement stmt, T& obj)";
81 List.iteri (fun index attr -> get_column attr index) scheme;
87 let output_scheme_binder index scheme =
90 | _ -> Some (output_scheme_binder index scheme)
92 let params_to_values = List.mapi (fun i (n,t) -> param_name_to_string n i, t >> param_type_to_string >> as_cxx_type)
93 let params_to_values = List.unique & params_to_values
94 let make_const_values = List.map (fun (name,t) -> name, sprintf "%s const&" t)
96 let output_value_defs vals =
97 vals >> List.iter (fun (name,t) -> output "%s %s;" t name)
99 let scheme_to_values = List.mapi (fun i attr -> name_of attr i, attr.RA.domain >> Type.to_string >> as_cxx_type)
101 let output_scheme_data index scheme =
103 let name = default_name "data" index in
105 scheme >> scheme_to_values >> output_value_defs;
108 let output_value_inits vals =
113 (String.concat "," (List.map (fun (name,_) -> sprintf "%s(%s)" name name) vals))
115 let output_params_binder index params =
117 let name = default_name "params" index in
119 let values = params_to_values params in
120 values >> make_const_values >> output_value_defs;
122 output "%s(%s)" name (values >> make_const_values >> Cxx.to_string);
123 output_value_inits values;
127 output "void set_params(typename Traits::statement stmt)";
129 List.iteri set_param params;
135 let output_params_binder index params =
137 | [] -> "typename Traits::no_params"
138 | _ -> output_params_binder index params
140 let generate_code index scheme params kind props
=
143 let scheme_binder_name = output_scheme_binder index scheme in
144 let params_binder_name = output_params_binder index params in
145 if (Option.is_some scheme_binder_name) then output_scheme_data index scheme;
147 if (Option.is_some scheme_binder_name) then output "template<class T>";
148 let values = params_to_values params in
149 let result = match scheme_binder_name with None -> [] | Some _ -> ["result","T&"] in
150 let all_params = Cxx.to_string
151 (["db","typename Traits::connection"] @ result @ (make_const_values values))
153 let name = choose_name props kind index in
154 let sql = Props.get props "sql" >> Option.get in
156 let sql = match kind
with
157 | Insert _
-> sql ^
" (" ^
(String.concat
"," (List.map
(fun _
-> "?") params
)) ^
")"
158 | Select
| Update _
| Delete _
| Create _
-> sql
160 let sql = Cxx.quote sql in
161 let inline_params = Cxx.inline (make_const_values values) in
162 output
"static bool %s(%s)" name all_params;
164 begin match scheme_binder_name with
165 | None
-> output
"return Traits::do_execute(db,_T(%s),%s(%s));" sql params_binder_name inline_params
166 | Some scheme_name
->output
"return Traits::do_select(db,result,_T(%s),%s(),%s(%s));"
167 sql (scheme_name ^
"<typename T::value_type>") params_binder_name inline_params
172 let start_output () =
173 output
"module Sqlgg (T : Sqlgg_traits) = struct"
175 let finish_output () = output
"end (* module Sqlgg *)"