[Pkg-ocaml-maint-commits] [mysql-ocaml] 01/05: Imported Upstream version 1.1.2
Stéphane Glondu
glondu at moszumanska.debian.org
Thu Nov 28 07:16:07 UTC 2013
This is an automated email from the git hooks/post-receive script.
glondu pushed a commit to branch master
in repository mysql-ocaml.
commit 0d5af89d7a44c958114586b1370e046d8fc2c0f4
Author: Stephane Glondu <steph at glondu.net>
Date: Thu Nov 28 08:05:08 2013 +0100
Imported Upstream version 1.1.2
---
.gitignore | 17 ++++++++++
CHANGES | 3 ++
Makefile.in | 4 +--
Makefile.msvc | 1 +
VERSION | 2 +-
demo2.ml | 24 +++++++-------
mysql.ml | 104 ++++++++++++++++++++++++++--------------------------------
mysql.mli | 99 +++++++++++++++++++++++++++++--------------------------
mysql_stubs.c | 46 +++++++++++++++++++-------
9 files changed, 170 insertions(+), 130 deletions(-)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6bc8797
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+doc/
+._d/
+._bcdi/
+._ncdi/
+Makefile
+config.log
+config.status
+*.byte
+*.native
+*.cm[aiox]
+*.cmxa
+*.o
+*.obj
+*.so
+*.dll
+*.lib
+*.a
diff --git a/CHANGES b/CHANGES
index 0a59451..149730f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+* Tue Nov 19 2013 (1.1.2)
+ * Mysql.Prepared.execute_null (Gregory Bellier)
+
* Sat May 19 2012 (1.1.1)
* Support build with ocaml/msvc and ocaml/mingw (Dmitry Grebeniuk)
* Update build tools (Dmitry Grebeniuk)
diff --git a/Makefile.in b/Makefile.in
index bff0a29..457f27b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -13,6 +13,7 @@ LDFLAGS=@LDFLAGS@
export OCAMLMKLIB_FLAGS=@LDFLAGS@
export OCAMLFIND_INSTFLAGS=-patch-version "$(VERSION)"
+build: all opt
all: byte-code-library
opt: native-code-library
reallyall: byte-code-library native-code-library htdoc
@@ -37,6 +38,5 @@ NAME=ocaml-mysql-$(VERSION)
.PHONY: release
release:
git tag -a -m $(VERSION) v$(VERSION)
- git archive --prefix=$(NAME)/ v$(VERSION) | tar --delete $(NAME)/web | gzip > $(NAME).tar.gz
+ git archive --prefix=$(NAME)/ v$(VERSION) | gzip > $(NAME).tar.gz
gpg -a -b $(NAME).tar.gz
-
diff --git a/Makefile.msvc b/Makefile.msvc
index ba4107e..cdba215 100644
--- a/Makefile.msvc
+++ b/Makefile.msvc
@@ -13,6 +13,7 @@ LIBINSTALL_FILES=$(wildcard mysql.mli mysql.cm* mysql.a libmysql_stubs.a dllmysq
OCAMLMKLIB=ocamlmklib -ocamlc ocamlc -ocamlopt ocamlopt -verbose
+build: all
all: mysql.cma mysql.cmxa
mysql.cma mysql.cmxa: mysql.ml mysql.mli mysql_stubs.c
diff --git a/VERSION b/VERSION
index 9fdd21e..8ba0ac1 100644
--- a/VERSION
+++ b/VERSION
@@ -2,5 +2,5 @@
VERSION -- Version Information for mysql (syntax: Text)
[automatically generated and maintained by GNU shtool]
- This is mysql, Version 1.1.1 (19-May-2012)
+ This is mysql, Version 1.1.2 (19-Nov-2013)
diff --git a/demo2.ml b/demo2.ml
index a2c1782..5616ce6 100644
--- a/demo2.ml
+++ b/demo2.ml
@@ -9,7 +9,7 @@ module P = Mysql.Prepared
Verify safe GC interaction (see CAML_TEST_GC_SAFE in mysql_stubs.c)
For such test need strings on heap, not statically allocated atoms, hence String.copy
*)
-let _ = Thread.create (fun () ->
+let (_:Thread.t) = Thread.create (fun () ->
let i = ref 0 in
while true do Gc.compact(); incr i; if !i mod 100 = 0 then (print_char '.'; flush stdout) done) ()
@@ -17,11 +17,14 @@ let s = String.copy
let db = Mysql.quick_connect ~database:(s "test") ~user:(s "root") ()
-let _ = Mysql.exec db (s "CREATE TABLE IF NOT EXISTS test(id INT) ENGINE=MEMORY")
+let (_:Mysql.result) = Mysql.exec db (s "CREATE TABLE test(id INT, v VARCHAR(10)) ENGINE=MEMORY")
let () =
- let insert = P.create db (s "INSERT INTO test VALUES (?)") in
- for i = 10 to 20 do
- ignore (P.execute insert [|string_of_int i|])
+ let insert = P.create db (s "INSERT INTO test VALUES (?,?)") in
+ for i = 10 to 15 do
+ ignore (P.execute insert [|string_of_int i; sprintf "value %d" i|])
+ done;
+ for i = 16 to 20 do
+ ignore (P.execute_null insert [|Some (string_of_int i); None|])
done;
P.close insert
@@ -32,17 +35,16 @@ let () =
| None -> ()
in
let select = P.create db (s "SELECT * FROM test WHERE id > ?") in
- print_endline "> 15";
- loop (P.execute select [|s "15"|]);
- print_endline "> 20";
- loop (P.execute select [|s "20"|]);
+ print_endline "> 13";
+ loop (P.execute select [|s "13"|]);
print_endline "> 19";
loop (P.execute select [|s "19"|]);
+ print_endline "> 20";
+ loop (P.execute select [|s "20"|]);
P.close select;
print_endline "done all";
()
-let _ = Mysql.exec db (s "DROP TABLE test")
+let (_:Mysql.result) = Mysql.exec db (s "DROP TABLE test")
let () = Mysql.disconnect db
-
diff --git a/mysql.ml b/mysql.ml
index 36b8d48..6d66b00 100644
--- a/mysql.ml
+++ b/mysql.ml
@@ -249,28 +249,27 @@ let error_of_int code = match code with
(* Status of MySQL database after an operation. Especially indicates empty
result sets *)
-
-type status =
- | StatusOK
- | StatusEmpty
- | StatusError of error_code
+type status =
+| StatusOK
+| StatusEmpty
+| StatusError of error_code
(* database field type *)
-
-type dbty = IntTy (* 0 *)
- | FloatTy (* 1 *)
- | StringTy (* 2 *)
- | SetTy (* 3 *)
- | EnumTy (* 4 *)
- | DateTimeTy (* 5 *)
- | DateTy (* 6 *)
- | TimeTy (* 7 *)
- | YearTy (* 8 *)
- | TimeStampTy (* 9 *)
- | UnknownTy (* 10 *)
- | Int64Ty (* 11 *)
- | BlobTy (* 12 *)
- | DecimalTy (* 13 *)
+type dbty =
+| IntTy (* 0 *)
+| FloatTy (* 1 *)
+| StringTy (* 2 *)
+| SetTy (* 3 *)
+| EnumTy (* 4 *)
+| DateTimeTy (* 5 *)
+| DateTy (* 6 *)
+| TimeTy (* 7 *)
+| YearTy (* 8 *)
+| TimeStampTy (* 9 *)
+| UnknownTy (* 10 *)
+| Int64Ty (* 11 *)
+| BlobTy (* 12 *)
+| DecimalTy (* 13 *)
let pretty_type = function
| IntTy -> "integer"
@@ -351,8 +350,7 @@ let quick_connect ?options ?host ?database ?port ?password ?user ?socket () =
external change_user : dbd -> db -> unit = "db_change_user"
let quick_change ?user ?password ?database conn =
- change_user conn { defaults with
- dbuser = user; dbpwd = password; dbname = database }
+ change_user conn { defaults with dbuser = user; dbpwd = password; dbname = database }
external select_db : dbd -> string -> unit = "db_select_db"
external list_dbs : dbd -> ?pat:string -> unit -> string array option = "db_list_dbs"
@@ -381,7 +379,7 @@ external fetch_field_dir : result -> int -> field option = "db_fetch_field_dir"
let status dbd =
let x = real_status dbd in
match x with
- 0 -> StatusOK
+ | 0 -> StatusOK
| 1065 -> StatusEmpty
| _ -> StatusError (error_of_int x)
@@ -389,20 +387,20 @@ let errno dbd = error_of_int (real_status dbd)
(* [sub start len str] returns integer obtained from substring of length
[len] from [str] *)
-
+
let sub start len str = int_of_string (String.sub str ~pos:start ~len)
(* xxx2ml parses a string returned from a MySQL field typed xxx and turns it into a
corresponding OCaml value.
MySQL uses the following representations for date/time values
-
+
DATETIME yyyy-mm-dd hh:mm:ss
DATE yyyy-mm-dd'
TIME hh:mm:ss'
YEAR yyyy'
TIMESTAMP YYYYMMDDHHMMSS'
-*)
+*)
let int2ml str = int_of_string str
@@ -424,7 +422,7 @@ let set2ml str =
let tokens = lexer(Stream.of_string str) in
let rec list = parser
| [< 'Ident i; t = tail >] -> i :: t
- | [< >] -> []
+ | [< >] -> []
and tail = parser
| [< 'Kwd ","; l = list >] -> l
| [< >] -> [] in
@@ -446,30 +444,25 @@ let datetime2ml str =
let date2ml str =
assert (String.length str = 10);
-
let year = sub 0 4 str in
let month = sub 5 2 str in
let day = sub 8 2 str in
(year,month,day)
-
let time2ml str =
assert (String.length str = 8);
-
+
let hour = sub 0 2 str in
let minute = sub 3 2 str in
let second = sub 6 2 str in
(hour,minute,second)
-
-
+
let year2ml str =
assert (String.length str = 4);
sub 0 4 str
-
let timestamp2ml str =
assert (String.length str = 14);
-
let year = sub 0 4 str in
let month = sub 4 2 str in
let day = sub 6 2 str in
@@ -479,20 +472,16 @@ let timestamp2ml str =
(year,month,day,hour,minute,second)
-
-
(* [opt f v] applies [f] to optional value [v]. Use this to fetch
data of known type from database fields which might be NULL:
[opt int2ml str] *)
-
let opt f arg = match arg with
| None -> None
| Some x -> Some (f x)
-
+
(* [not_null f v] applies [f] to [Some v]. Use this to fetch data of known
type from database fields which never can be NULL: [not_null int2ml str]
*)
-
let not_null f arg = match arg with
| None -> fail "not_null was applied to None"
| Some x -> f x
@@ -501,19 +490,19 @@ let not_null f arg = match arg with
let names result =
Array.init (fields result) ~f:(function offset ->
match fetch_field_dir result offset with
- Some field -> field.name
+ | Some field -> field.name
| None -> "")
-
+
let types result =
Array.init (fields result) ~f:(function offset ->
match fetch_field_dir result offset with
- Some field -> field.ty
+ | Some field -> field.ty
| None -> (fail "Unknown type in field"))
(* [column result] returns a function [col] which fetches columns from
results by column name. [col] has type string -> 'a array -> 'b.
Where the first argument is the name of the column.
-
+
let r = exec dbd "select * from table" in
let col = col r in
@@ -522,10 +511,9 @@ let types result =
Some a -> not_null int2ml (col "label" a) :: loop (fetch r)
in
loop (fetch r)
-
+
*)
-
let column result =
let names = names result in
let map = (* maps names to positions *)
@@ -541,11 +529,11 @@ let column result =
let col ~key ~row =
row.(StrMap.find key map)
in
- col
+ col
(* ml2xxx encodes OCaml values into strings that match the MysQL syntax of
the corresponding type *)
-
+
let ml2str str = "'" ^ escape str ^ "'"
let ml2rstr conn str = "'" ^ real_escape conn str ^ "'"
let ml2blob = ml2str
@@ -609,10 +597,11 @@ let iter res ~f =
if size res > Int64.zero then
let rec loop () =
match fetch res with
- Some row -> f row; loop ()
- | None -> () in
- to_row res Int64.zero;
- loop ()
+ | Some row -> f row; loop ()
+ | None -> ()
+ in
+ to_row res Int64.zero;
+ loop ()
let iter_col res ~key ~f =
let col = column res ~key in
@@ -626,13 +615,14 @@ let map res ~f =
if size res > Int64.zero then
let rec loop lst =
match fetch res with
- Some row -> loop (f row :: lst)
- | None -> lst in
- to_row res Int64.zero;
- List.rev (loop [])
+ | Some row -> loop (f row :: lst)
+ | None -> lst
+ in
+ to_row res Int64.zero;
+ List.rev (loop [])
else
[]
-
+
let map_col res ~key ~f =
let col = column res ~key in
map res ~f:(function row -> f (col ~row))
@@ -648,6 +638,7 @@ type stmt_result
external create : dbd -> string -> stmt = "caml_mysql_stmt_prepare"
external execute : stmt -> string array -> stmt_result = "caml_mysql_stmt_execute"
+external execute_null : stmt -> string option array -> stmt_result = "caml_mysql_stmt_execute_null"
external affected : stmt -> int64 = "caml_mysql_stmt_affected"
external insert_id : stmt -> int64 = "caml_mysql_stmt_insert_id"
external real_status : stmt -> int = "caml_mysql_stmt_status"
@@ -656,4 +647,3 @@ external result_metadata : stmt -> result = "caml_mysql_stmt_result_metadata"
external close : stmt -> unit = "caml_mysql_stmt_close"
end
-
diff --git a/mysql.mli b/mysql.mli
index 99397c9..53a8a74 100644
--- a/mysql.mli
+++ b/mysql.mli
@@ -19,9 +19,7 @@
*)
(**
-
This module provides access to MySQL databases, roughly following the C API
-
*)
(** {1 Database connections} *)
@@ -32,13 +30,14 @@
type dbd
(** Login information for a database. Use [None] for default values *)
-type db = { dbhost : string option; (** database server host *)
- dbname : string option; (** database name *)
- dbport : int option; (** port *)
- dbpwd : string option; (** user password *)
- dbuser : string option; (** database user *)
- dbsocket : string option; (** unix socket path *)
- }
+type db = {
+ dbhost : string option; (** database server host *)
+ dbname : string option; (** database name *)
+ dbport : int option; (** port *)
+ dbpwd : string option; (** user password *)
+ dbuser : string option; (** database user *)
+ dbsocket : string option; (** unix socket path *)
+}
(** Login information using all defaults *)
val defaults: db
@@ -76,8 +75,7 @@ type db_option =
| SHARED_MEMORY_BASE_NAME of string (** The name of the shared-memory object for communication to the server
on Windows, if the server supports shared-memory connections *)
-(** [connect ?options db] connects to the database [db] and returns a handle for
- further use
+(** [connect ?options db] connects to the database [db] and returns a handle for further use
@param options connection specific options, default empty list
*)
val connect : ?options:db_option list -> db -> dbd
@@ -100,15 +98,13 @@ val change_user : dbd -> db -> unit
(** Another shortcut *)
val quick_change: ?user:string -> ?password:string -> ?database:string -> dbd -> unit
-(** [select_db] Switch to a new db, using the current user and password. *)
+(** [select_db] switches to a new db, using the current user and password. *)
val select_db : dbd -> string -> unit
-(** [disconnect dbd] releases a database connection [dbd]. The handle [dbd]
- becomes invalid *)
+(** [disconnect dbd] releases a database connection [dbd]. The handle [dbd] becomes invalid *)
val disconnect : dbd -> unit
-(** [ping dbd] makes sure the connection to the server is up, and
- re-establishes it if needed. *)
+(** [ping dbd] makes sure the connection to the server is up, and re-establishes it if needed. *)
val ping : dbd -> unit
(** {2 Information about a connection} *)
@@ -138,9 +134,10 @@ exception Error of string
type error_code = Aborting_connection | Access_denied_error | Alter_info | Bad_db_error | Bad_field_error | Bad_host_error | Bad_null_error | Bad_table_error | Blob_cant_have_default | Blob_key_without_length | Blob_used_as_key | Blobs_and_no_terminated | Cant_create_db | Cant_create_file | Cant_create_table | Cant_create_thread | Cant_delete_file | Cant_drop_field_or_key | Cant_find_dl_entry | Cant_find_system_rec | Cant_find_udf | Cant_get_stat | Cant_get_wd | Cant_initialize_udf | Can [...]
(** The status of a query *)
-type status = StatusOK (** The query was successful *)
- | StatusEmpty (** The query was successful, but found no results *)
- | StatusError of error_code (** There was some problem with the query *)
+type status =
+| StatusOK (** The query was successful *)
+| StatusEmpty (** The query was successful, but found no results *)
+| StatusError of error_code (** There was some problem with the query *)
(** [status dbd] returns the status of the last action on [dbd] *)
val status : dbd -> status
@@ -158,7 +155,7 @@ val errmsg : dbd -> string option
(** {2 Making a query} *)
(** handle to access the result of a query *)
-type result
+type result
(** [exec dbd str] executes a SQL statement and returns a handle to obtain
the result. Check [status] for errors! *)
@@ -184,8 +181,8 @@ val to_row : result -> int64 -> unit
val size : result -> int64
(** [iter result f] applies f to each row of result in turn, starting
-from the first. iter_col applies f to the value of the named column
-in every row.
+ from the first. iter_col applies f to the value of the named column
+ in every row.
The iter versions return unit, the map versions return a list of
the results of all the function applications. If there were no rows
@@ -205,24 +202,24 @@ val map_cols : result -> key:string array -> f:(string option array -> 'a) -> 'a
(** Returns one field of a result row based on column name. *)
val column : result -> key:string -> row:string option array -> string option
-
(** {2 Metainformation about a result set} *)
(** The type of a database field. Each of these represents one or more MySQL data types. *)
-type dbty = IntTy
- | FloatTy
- | StringTy
- | SetTy
- | EnumTy
- | DateTimeTy
- | DateTy
- | TimeTy
- | YearTy
- | TimeStampTy
- | UnknownTy
- | Int64Ty
- | BlobTy
- | DecimalTy
+type dbty =
+| IntTy
+| FloatTy
+| StringTy
+| SetTy
+| EnumTy
+| DateTimeTy
+| DateTy
+| TimeTy
+| YearTy
+| TimeStampTy
+| UnknownTy
+| Int64Ty
+| BlobTy
+| DecimalTy
(** The type that describes a field of a table or result *)
type field = { name : string; (** Name of the field *)
@@ -243,19 +240,17 @@ val pretty_type: dbty -> string
val affected : dbd -> int64
(** [insert_id result] returns the ID generated by the last INSERT
-query in a table with an AUTO_INCREMENT column. See the MySQL
-documentation for caveats. *)
+ query in a table with an AUTO_INCREMENT column. See the MySQL
+ documentation for caveats. *)
val insert_id: dbd -> int64
-
+
(** [fields result] returns the number of fields in a row *)
val fields : result -> int
-(** [names result] returns an array of the field names for the current result
- *)
+(** [names result] returns an array of the field names for the current result *)
val names : result -> string array
-(** [types result] returns an array with the MySQL types of the current
- result *)
+(** [types result] returns an array with the MySQL types of the current result *)
val types : result -> dbty array
(** Returns the information on the next field *)
@@ -270,15 +265,19 @@ val fetch_field_dir : result -> int -> field option
(** {1 Working with MySQL data types} *)
(** [escape str] returns the same string as [str] in MySQL syntax with
- special characters quoted to not confuse the MySQL parser *)
+ special characters quoted to not confuse the MySQL parser.
+
+ at deprecated This function poses a security risk (doesn't take into consideration
+ the character set of the current connection and may allow SQL injection pass through).
+ Use {!real_escape} instead.
+*)
val escape : string -> string
(** [real_escape dbd str] returns [str] encoded
to an escaped SQL string according to the current character set of [dbd] *)
val real_escape : dbd -> string -> string
-(** [xxx2ml str] decodes a MySQL value of type xxx into a corresponding
- OCaml value *)
+(** [xxx2ml str] decodes a MySQL value of type xxx into a corresponding OCaml value *)
(** Use for all MySQL signed integer types but BIGINT *)
val int2ml : string -> int
@@ -325,8 +324,11 @@ val not_null : ('a -> 'b) -> 'a option -> 'b
[ml2rxxx v] encodes [v] into MySQL syntax using [real_escape].
*)
+(** @deprecated This function uses {!escape} which poses a security risk. Use {!ml2rstr} instead. *)
val ml2str : string -> string
val ml2rstr : dbd -> string -> string
+
+(** @deprecated This function uses {!escape} which poses a security risk. Use {!ml2rblob} instead. *)
val ml2blob : string -> string
val ml2rblob : dbd -> string -> string
val ml2int : int -> string
@@ -375,6 +377,9 @@ val create : dbd -> string -> stmt
(** Execute the prepared statement with the specified values for parameters. *)
val execute : stmt -> string array -> stmt_result
+(** Same as {!execute}, but with support for NULL values. *)
+val execute_null : stmt -> string option array -> stmt_result
+
(** @return Number of rows affected by the last execution of this statement. *)
val affected : stmt -> int64
diff --git a/mysql_stubs.c b/mysql_stubs.c
index 0520560..574a3fb 100644
--- a/mysql_stubs.c
+++ b/mysql_stubs.c
@@ -965,15 +965,25 @@ row_t* create_row(MYSQL_STMT* stmt, size_t count)
return row;
}
-void set_param(row_t *r, char* str, size_t len, int index)
+void set_param_string(row_t *r, value v, int index)
{
MYSQL_BIND* bind = &r->bind[index];
+ size_t len = caml_string_length(v);
r->length[index] = len;
bind->length = &r->length[index];
bind->buffer_length = len;
bind->buffer_type = MYSQL_TYPE_STRING;
- bind->buffer = (void*)str;
+ bind->buffer = malloc(len);
+ memcpy(bind->buffer, String_val(v), len);
+}
+
+void set_param_null(row_t *r, int index)
+{
+ MYSQL_BIND* bind = &r->bind[index];
+
+ bind->buffer_type = MYSQL_TYPE_NULL;
+ bind->buffer = NULL;
}
void bind_result(row_t* r, int index)
@@ -1044,45 +1054,47 @@ struct custom_operations stmt_result_ops = {
#endif
};
-EXTERNAL value
-caml_mysql_stmt_execute(value v_stmt, value v_params)
+value
+caml_mysql_stmt_execute_gen(value v_stmt, value v_params, int with_null)
{
CAMLparam2(v_stmt,v_params);
CAMLlocal2(res,v);
unsigned int i = 0;
unsigned int len = Wosize_val(v_params);
int err = 0;
- char* bufs[256];
row_t* row = NULL;
MYSQL_STMT* stmt = STMTval(v_stmt);
check_stmt(stmt,"execute");
if (len != mysql_stmt_param_count(stmt))
mysqlfailmsg("Prepared.execute : Got %i parameters, but expected %i", len, mysql_stmt_param_count(stmt));
- if (len > 256)
- mysqlfailwith("Prepared.execute : too many parameters");
row = create_row(stmt, len);
if (!row)
mysqlfailwith("Prepared.execute : create_row for params");
for (i = 0; i < len; i++)
{
v = Field(v_params,i);
- bufs[i] = malloc(caml_string_length(v));
- memcpy(bufs[i],String_val(v),caml_string_length(v));
- set_param(row,bufs[i],caml_string_length(v),i);
+ if (with_null)
+ if (Val_none == v)
+ set_param_null(row, i);
+ else
+ set_param_string(row, Some_val(v), i);
+ else
+ set_param_string(row, v, i);
}
err = mysql_stmt_bind_param(stmt, row->bind);
if (err)
{
+ for (i = 0; i < len; i++) free(row->bind[i].buffer);
destroy_row(row);
- for (i = 0; i < len; i++) free(bufs[i]);
mysqlfailmsg("Prepared.execute : mysql_stmt_bind_param = %i",err);
}
caml_enter_blocking_section();
err = mysql_stmt_execute(stmt);
caml_leave_blocking_section();
+ for (i = 0; i < len; i++) free(row->bind[i].buffer);
destroy_row(row);
- for (i = 0; i < len; i++) free(bufs[i]);
+
if (err)
{
mysqlfailmsg("Prepared.execute : mysql_stmt_execute = %i, %s",err,mysql_stmt_error(stmt));
@@ -1109,6 +1121,16 @@ caml_mysql_stmt_execute(value v_stmt, value v_params)
CAMLreturn(res);
}
+EXTERNAL value caml_mysql_stmt_execute(value v_stmt, value v_param)
+{
+ return caml_mysql_stmt_execute_gen(v_stmt, v_param, 0);
+}
+
+EXTERNAL value caml_mysql_stmt_execute_null(value v_stmt, value v_param)
+{
+ return caml_mysql_stmt_execute_gen(v_stmt, v_param, 1);
+}
+
EXTERNAL value
caml_mysql_stmt_fetch(value result)
{
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ocaml-maint/packages/mysql-ocaml.git
More information about the Pkg-ocaml-maint-commits
mailing list