1 (* C# code generation *)
14 module Values
= G.Values
16 let comment = G.comment
17 let empty_line = G.empty_line
21 output_l
(List.map
(fun str
-> Gen_caml.replace_all ~sub
:"*/" ~by
:"* /" ~str
) sl
);
24 let comment_xml summary params
=
25 let summary = String.nsplit
summary "\n" in
26 let params = List.map
(fun (n
,s
) -> sprintf
"<param name=\"%s\">%s</param>" n s
) params in
27 comment_doc ("<summary>" :: summary @ ("</summary>" :: params))
29 let (start_class
,end_class
) = J.start_class
,J.end_class
30 let (start_ns
,end_ns
) = J.start_
"namespace"
36 let as_api_type = function
38 | Type.Text
-> "String"
39 | Type.Float
-> "Float"
40 | Type.Blob
-> "String"
41 | Type.Bool
-> "Boolean"
42 | Type.Datetime
-> "Datetime"
43 | Type.Any
-> "String"
45 let as_lang_type = as_api_type
49 module T
= Translate
(L
)
54 let get_column attr index
=
55 sprintf
"reader.Get%s(%u)"
56 (attr
.RA.domain
>> as_api_type)
59 let schema_to_string = G.Values.to_string
& schema_to_values
61 let output_schema_binder index schema
=
62 let name = "callback" in
63 output
"public delegate void %s(%s);" name (schema_to_string schema
);
67 let output_schema_binder index schema
=
70 | _
-> Some
(output_schema_binder index schema
)
72 let set_param index param
=
74 let name = default_name
"param" index
in
75 output
"IDbDataParameter %s = _cmd.CreateParameter();" name;
76 output
"%s.ParameterName = \"@%s\";" name (param_name_to_string id index
);
77 output
"%s.DbType = DbType.%s;" name (param_type_to_string t
);
78 output
"_cmd.Parameters.Add(%s);" name
80 let output_params_binder params =
81 List.iteri
set_param params;
82 output
"_cmd.Prepare();"
88 let func_execute index stmt
=
89 let values = params_to_values stmt
.params in
90 let schema_binder_name = output_schema_binder index stmt
.schema
in
91 let is_select = Option.is_some
schema_binder_name in
92 let doc = if is_select then ["result", schema_to_string stmt
.schema
] else [] in
93 comment_xml "execute query" doc;
94 let func_name = if is_select then "execute_reader" else "execute" in
95 let result = "public " ^
if is_select then "IEnumerable<IDataReader>" else "int" in
96 G.func
result func_name values (fun () ->
97 output
"if (null == _cmd)";
99 output
"_cmd = _conn.CreateCommand();";
100 output
"_cmd.CommandText = sql;";
101 output_params_binder stmt
.params;
103 output
"if (null != CommandTimeout) _cmd.CommandTimeout = CommandTimeout.Value;";
105 (fun i
(name,_
) -> output
"((IDbDataParameter)_cmd.Parameters[%u]).Value = %s;" i
name)
107 begin match schema_binder_name with
108 | None
-> output
"return _cmd.ExecuteNonQuery();"
110 output
"IDataReader reader = _cmd.ExecuteReader();";
111 output
"while (reader.Read())";
113 output
"yield return reader;";
115 output
"reader.Close();";
120 let result = match schema_binder_name with None
-> [] | Some
name -> ["result",name] in
121 let all_params = values @ result in
122 G.func
"public int" "execute" all_params (fun () ->
123 let args = List.mapi
(fun index attr
-> get_column attr index
) stmt
.schema
in
124 output
"int count = 0;";
125 output
"foreach (var reader in execute_reader(%s))" (Values.inline
values);
127 output
"result(%s);" (Values.join
args);
130 output
"return count;"
133 match stmt
.schema
with
135 let t = as_lang_type attr
.RA.domain
in
136 G.func
("public IEnumerable<" ^
t ^
">") "rows" values (fun () ->
137 output
"foreach (var reader in execute_reader(%s))" (Values.inline
values);
139 output
"yield return %s;" (get_column attr
0);
144 List.iteri
(fun index attr
->
145 output
"public readonly %s %s;"
146 (as_lang_type attr
.RA.domain
)
150 G.func
"public" "row" ["reader","IDataReader"] (fun () ->
151 List.iteri
(fun i attr
-> output
"%s = %s;" (name_of attr i
) (get_column attr i
)) stmt
.schema
;
154 G.func
"public IEnumerable<row>" "rows" values (fun () ->
155 output
"foreach (var reader in execute_reader(%s))" (Values.inline
values);
157 output
"yield return new row(reader);";
162 else (* not is_select *)
165 | Insert _
when List.length
values > 1 ->
166 G.func
"public int" "execute<T>" ["v","T"] (fun () ->
167 output
"return execute(%s);" (values >> Values.names
>> List.map
((^
) "v.") >> Values.join
)
173 let generate_code index stmt
=
174 let name = choose_name stmt
.props stmt
.kind index
in
175 let sql = quote (get_sql stmt
) in
177 output
"IDbCommand _cmd;";
178 output
"IDbConnection _conn;";
179 output
"public int? CommandTimeout;";
180 output
"static string sql = %s;" sql;
182 G.func
"public" name ["db","IDbConnection"] (fun () ->
183 output
"_cmd = null;";
184 output
"_conn = db;";
187 func_execute index stmt
;
191 let generate_all names
=
193 output
"public readonly IDbConnection db;";
194 List.iter
(fun s
-> output
"public %s %s;" s s
) names
;
196 G.func
"public" "all" ["db","IDbConnection"] (fun () ->
197 output
"this.db = db;";
198 List.iter
(fun name -> output
"%s = new %s(db);" name name) names
202 let generate () name stmts
=
203 params_mode
:= Some Named
; (* only named params allowed *)
204 let using = ["System";"System.Data";"System.Collections.Generic"] in
205 List.iter
(fun s
-> output
"using %s;" s
) using;
208 let names = List.mapi
generate_code (List.of_enum stmts
) in