Markus Mottl avatar Markus Mottl committed 933419f Merge

Merged two newest patches

Comments (0)

Files changed (3)

lib/postgresql.ml

     connection -> string -> string array -> bool array -> result
     = "PQexecParams_stub"
 
+  external prepare : connection -> string -> string -> result = "PQprepare_stub"
+
+  external exec_prepared :
+    connection -> string -> string array -> bool array -> result
+    = "PQexecPrepared_stub"
+
   external describe_prepared :
     connection -> string -> result = "PQdescribePrepared_stub"
 
       raise (Error (Unexpected_status (stat, res#error, expect)))
     else res
 
+  method prepare stm_name query =
+    new result (
+      wrap_conn (fun conn ->
+        let r = Stub.prepare conn stm_name query in
+        if Stub.result_isnull r then signal_error conn
+        else r))
+
+  method exec_prepared
+    ?(expect = []) ?(params = [||]) ?(binary_params = [||]) stm_name =
+    let r =
+      wrap_conn (fun conn ->
+        let r = Stub.exec_prepared conn stm_name params binary_params in
+        if Stub.result_isnull r then signal_error conn
+        else r)
+    in
+    let res = new result r in
+    let stat = res#status in
+    if not (expect = []) && not (List.mem stat expect) then
+      raise (Error (Unexpected_status (stat, res#error, expect)))
+    else res
+
   method describe_prepared query =
     new result (
       wrap_conn (fun conn ->

lib/postgresql.mli

       @raise Error if there is an unexpected result status.
   *)
 
+  method prepare : string -> string -> result
+  (** [prepare stm_name query] creates a prepared query named [stm_name]
+      which will execute the query or command [query] when passed to
+      [#exec_prepared]. *)
+
+  method exec_prepared :
+    ?expect : result_status list -> ?params : string array ->
+    ?binary_params : bool array -> string -> result
+  (** [exec_prepared ?expect ?params ?binary_params stm_name] acts as
+      [#exec], except executes the prepared query [stm_name]. *)
+
   method describe_prepared : string -> result
   (** [#describe_prepared stm_name] submits a request to obtain
       information about the specified prepared statement, and waits for

lib/postgresql_stubs.c

 }
 
 #ifdef PG_OCAML_8_2
+CAMLprim value PQprepare_stub(value v_conn, value v_stm_name, value v_query)
+{
+  CAMLparam1(v_conn);
+  PGconn *conn = get_conn(v_conn);
+  np_callback *np_cb = get_conn_cb(v_conn);
+  PGresult *res;
+  int stm_name_len = caml_string_length(v_stm_name) + 1;
+  int query_len = caml_string_length(v_query) + 1;
+  char *stm_name = caml_stat_alloc(stm_name_len);
+  char *query = caml_stat_alloc(query_len);
+  memcpy(stm_name, String_val(v_stm_name), stm_name_len);
+  memcpy(query, String_val(v_query), query_len);
+  caml_enter_blocking_section();
+    res = PQprepare(conn, stm_name, query, 0, NULL);
+    free(stm_name);
+    free(query);
+  caml_leave_blocking_section();
+  CAMLreturn(alloc_result(res, np_cb));
+#else
+CAMLprim value PQprepare_stub(
+  value __unused v_conn, value __unused v_stm_name, value __unused v_query)
+{
+  caml_failwith("Postgresql.prepare: not supported");
+  return Val_unit;
+#endif
+}
+
+#ifdef PG_OCAML_8_2
+CAMLprim value PQexecPrepared_stub(
+  value v_conn, value v_stm_name, value v_params, value v_binary_params)
+{
+  CAMLparam1(v_conn);
+  PGconn *conn = get_conn(v_conn);
+  np_callback *np_cb = get_conn_cb(v_conn);
+  PGresult *res;
+  int len = caml_string_length(v_stm_name) + 1;
+  char *stm_name = caml_stat_alloc(len);
+  int nparams = Wosize_val(v_params);
+  const char * const *params = copy_params(v_params, nparams);
+  int *formats, *lengths;
+  copy_binary_params(v_params, v_binary_params, nparams, &formats, &lengths);
+  memcpy(stm_name, String_val(v_stm_name), len);
+  caml_enter_blocking_section();
+    res = PQexecPrepared(conn, stm_name, nparams, params, lengths, formats, 0);
+    free(stm_name);
+    free_params(params, nparams);
+    free_binary_params(formats, lengths);
+  caml_leave_blocking_section();
+  CAMLreturn(alloc_result(res, np_cb));
+#else
+CAMLprim value PQexecPrepared_stub(
+  value __unused v_conn, value __unused v_stm_name, value __unused v_params,
+  value __unused v_binary_params)
+{
+  caml_failwith("Postgresql.exec_prepared: not supported");
+  return Val_unit;
+#endif
+}
+
+#ifdef PG_OCAML_8_2
 CAMLprim value PQdescribePrepared_stub(value v_conn, value v_query)
 {
   CAMLparam1(v_conn);
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.