10 let parse_one_exn (sql
,props
) =
11 if Sqlgg_config.debug1
() then Printf.eprintf
"------\n%s\n%!" sql
;
12 let (sql
,schema
,params
,kind
) = Syntax.parse sql
in
13 begin match kind
, !Gen.params_mode
with
14 | Insert
(Some _
,_
), None
-> Error.log
"Cannot use `-params none` with autogenerated parameters"
17 let props = Props.set
props "sql" sql
in
18 { Gen.schema
; params
; kind
; props }
20 let parse_one (sql
, props as x
) =
22 Some
(parse_one_exn x
)
24 | Parser_utils.Error
(exn
,(line
,cnum
,tok
,tail
)) ->
26 let extra = match exn
with
27 | Sql.Schema.Error
(_
,msg
) -> msg
28 | exn
-> Printexc.to_string exn
30 Error.log
"==> %s" sql
;
31 if cnum
= String.length sql
&& tok
= "" then
32 Error.log
"Error: %s" extra
34 Error.log
"Position %u:%u Tokens: %s%s\nError: %s" line cnum tok
(String.slice ~last
:32 tail
) extra;
38 Error.log
"Failed %s: %s" (Option.default
"" @@ Props.get
props "name") sql
;
41 let parse_one (sql
,props as x
) =
42 match Props.get
props "noparse" with
43 | Some _
-> Some
{ Gen.schema
=[]; params
=[]; kind
=Stmt.Other
; props=Props.set
props "sql" sql
}
47 while Option.map p
(Enum.peek e
) = Some
true do
51 type token
= [`Comment
of string | `Token
of string | `Char
of char
|
52 `Space
of string | `Prop
of string * string | `Semicolon
]
54 let get_statements ch
=
55 let lexbuf = Lexing.from_channel ch
in
56 let tokens = Enum.from
(fun () ->
57 if lexbuf.Lexing.lex_eof_reached
then raise
Enum.No_more_elements
else
58 match Sql_lexer.ruleStatement
lexbuf with
59 | `Eof
-> raise
Enum.No_more_elements
63 let b = Buffer.create
1024 in
64 let props = ref Props.empty
in
65 let answer () = Buffer.contents
b, !props in
67 match Enum.get
tokens with
68 | None
-> if smth
then Some
(answer ()) else None
71 | `Comment s
-> ignore s
; loop smth
(* do not include comments (option?) *)
72 | `Char c
-> Buffer.add_char
b c
; loop true
73 | `Space _
when smth
= false -> loop smth
(* drop leading whitespaces *)
74 | `Token s
| `Space s
-> Buffer.add_string
b s
; loop true
75 | `Prop
(n
,v
) -> props := Props.set
!props n v
; loop smth
76 | `Semicolon
-> Some
(answer ())
80 let extract () = try extract () with e
-> Error.log
"lexer failed (%s)" (Printexc.to_string e
); None
in
83 | None
-> raise
Enum.No_more_elements
85 begin match parse_one sql
with
88 if not
(Sql.Schema.is_unique stmt
.schema
) then
89 Error.log
"Error: this SQL statement will produce rowset with duplicate column names:\n%s\n" (fst sql
);
93 Enum.from
next |> List.of_enum
95 let with_channel filename f
=
96 match try Some
(open_in filename
) with _
-> None
with
97 | None
-> Error.log
"cannot open file : %s" filename
; f None
98 | Some ch
-> Std.finally
(fun () -> close_in_noerr ch
) f
(Some ch
)