7 type value_t
= string * Sql.Type.t
(** name and type *)
10 type values
= value_t list
15 type param_id
= | Named
of string | Numbered
of int | Next deriving
(Show
)
16 type param_type
= Sql.Type.t
option deriving
(Show
)
17 type param
= param_id
* param_type deriving
(Show
)
18 type params
= param list deriving
(Show
)
20 let to_string ps
= Show.show
<params
>(ps
)
23 type kind = | Select of column_list
24 | Insert of column_list
25 | Create of Sql.Table.t
26 | Update of column_list
31 * string (** table name as string *)
32 * values
(** placeholders for input parameters *)
36 * string (** table name as string *)
37 * values
(** placeholders for input parameters *)
38 * Props.t
(** some user directives *)
39 * string (** raw sql untouched *)
42 let to_sql k table sql
=
47 (String.concat
"," (List.map
(fun _
-> "?") table
.Sql.Table.cols
))
48 | Insert
(Cols cols
) ->
51 (String.concat
"," (List.map
(fun _
-> "?") cols
))
57 let to_sql k table sql
=
60 | c
-> String.make
1 c
62 String.replace_chars
escape (to_sql k table sql
)
68 type column = Sql.Col.t * Sql.Table.t
71 type kind = | Select of column list (** rowset *)
72 * values
(** rowset expressions *)
73 * values
(** input parameters *)
75 | Modify
of column list
(** modified columns *)
76 * values
(** input parameters *)
77 | Delete
of values
(** input parameters *)
81 * Sql.Table.t
(** this is temporary workaround *)
82 * Props.t
(** some user directives *)
83 * string (** corresponding SQL query *)
86 exception Bad_column
of Sql.Table.t
* string
88 (** resolve all names given as strings to corresponding values *)
90 let tables = ref [] in
91 let get_table name
= List.find_option
(fun table
-> table
.Sql.Table.name
= name
) !tables in
92 let get_column table name
= List.find_option
(fun col
-> col
.Sql.Col.name
= name
) table
.Sql.Table.cols
in
93 (* fix here for multiple tables *)
94 let resolve_columns table columns
=
96 | Raw.All
-> List.map
(fun col
-> col
,table
) table
.Sql.Table.cols
98 List.map
(fun colname
-> match get_column table colname
with
99 | Some col
-> col
, table
100 | None
-> raise
(Bad_column
(table
,colname
))) cols
102 let resolve_one stmt
=
103 let (kind
,name
,inputs
,props
,raw_sql
) = stmt
in
104 let sql table
= Raw.to_sql kind table raw_sql
in
105 match get_table name
with
107 begin match kind
with
108 | Raw.Create table
->
109 tables := table
::!tables;
110 assert (List.length inputs
= 0);
111 Some
(Create
, table
, props
, sql table
)
112 | _
-> Error.log
"No such table %s" name
; None
117 | Raw.Create _
-> Error.log
"Duplicate CREATE for table %s" name
; None
118 | Raw.Select colnames
->
119 let outputs = resolve_columns table colnames
in
120 Some
(Select
(outputs,[],inputs
), table
, props
, sql table
)
121 | Raw.Insert colnames
122 | Raw.Update colnames
->
123 let cols = resolve_columns table colnames
in
124 Some
(Modify
(cols,inputs
), table
, props
, sql table
)
125 | Raw.Delete
-> Some
(Delete inputs
, table
, props
, sql table
))
127 Bad_column
(table
,column
) ->
128 Error.log
"Column %s not found in %s" column table
.Sql.Table.name
;
132 List.filter_map
resolve_one stmts