Giter VIP home page Giter VIP logo

ocaml-mariadb's People

Contributors

andreas avatar andrenth avatar apeschar avatar cyberhuman avatar emillon avatar fdopen avatar kit-ty-kate avatar leonidas-from-xiv avatar nymphium avatar paurkedal avatar poeschko avatar rr0gi avatar ygrek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ocaml-mariadb's Issues

"Commands out of sync" error from MariaDB when executing statements in parallel with Lwt

When I have multiple queries executed in parallel using something like Lwt.join I run into this error:

Fatal error: exception Failure("prepare: (2014) Commands out of sync; you can't run this command now")

I've created a gist to reproduce the problem: https://gist.github.com/donut/080ce76cf0dab97f5dc6e933d3f58daf

Key code:

let execute_query conn query values yield =
  Lwt_io.printlf "Executing query %s" query >>= fun () ->
  Mdb.prepare conn query >>= or_die "prepare" >>= fun stmt ->
  Lwt_io.printlf "prepared query" >>= fun () ->
  Mdb.Stmt.execute stmt values >>= or_die "exec" >>= fun result ->
  Lwt_io.printlf "executed query, yielding" >>= fun () ->
  yield result >>= fun return -> 
  Lwt_io.printlf "yielded, closing statement" >>= fun () ->
  Mdb.Stmt.close stmt >>= or_die "stmt close" >>= fun () ->
  Lwt_io.printlf "returning value from yield" >>= fun () ->
  Lwt.return return


let test db_conn index =
  let query =
    "SELECT id FROM url WHERE id = ? ORDER BY id ASC LIMIT 1" in
  
  execute_query db_conn query [| `Int 1 |] (function
  | None -> Lwt_io.printlf "[%d] nothing found" index
  | Some result -> stream result >>= stream_next_opt >>= function
    | None -> Lwt_io.printlf "[%d] no rows returned" index
    | Some row -> Lwt_io.printlf "[%d] row found" index
  )

let main () =
  let db_connect =
    Mdb.connect ~host:"localhost" ~user:"root" ~pass:"" ~db:"rtmDOTtv" in
  db_connect () >>= or_die "connect" >>= fun db_conn ->
  
  let mkt index = test db_conn index in
  Lwt.join [ mkt 0; mkt 1; mkt 2; ] >>= fun () ->

  Mdb.close db_conn

let () =
  Lwt_main.run @@ main ()

Am I doing something wrong? I was hoping to use this library for a web app, but I'm guessing parallel requests would run into this issue as well.

installing mariadb on mac

I am trying to install mariadb on mac and get the following error:

~/git/ocaml-caqti master
❯ opam install mariadb
The following actions will be performed:
  βˆ— install mariadb 1.1.4

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><>  🐫
⬇ retrieved mariadb.1.1.4  (cached)
[ERROR] The compilation of mariadb.1.1.4 failed at "./configure
        --prefix=/Users/zish/.opam/4.12.1".

#=== ERROR while compiling mariadb.1.1.4 ======================================#
# context     2.1.2 | macos/arm64 | ocaml-base-compiler.4.12.1 | https://opam.ocaml.org#71d8d30e
# path        ~/.opam/4.12.1/.opam-switch/build/mariadb.1.1.4
# command     ~/.opam/opam-init/hooks/sandbox.sh build ./configure --prefix=/Users/zish/.opam/4.12.1
# exit-code   1
# env-file    ~/.opam/log/mariadb-55095-0e674d.env
# output-file ~/.opam/log/mariadb-55095-0e674d.out
### output ###
# Could not detect a MariaDB client library



<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><>  🐫
β”Œβ”€ The following actions failed
β”‚ Ξ» build mariadb 1.1.4
└─
╢─ No changes have been performed

~/git/ocaml-caqti master                                                ✘ 31 10s
❯ which mariadb
/opt/homebrew/bin/mariadb

 ~/git/ocaml-caqti ξ‚Ό master ξ‚° 

I have run opam update and opam upgrade. I have mariadb installed via brew.

Any suggestions on resolving this error would be greatly appreciated. Thank you.

#UPDATE

I had been meaning to factory reset my machine so I went ahead and did that to erase the possibility that I had some config that was interfering. I get the same error:

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
-> retrieved mariadb.1.1.4  (cached)
-> removed   conf-mariadb.2
-> removed   conf-pkg-config.2
-> installed conf-pkg-config.2
-> installed conf-mariadb.2
[ERROR] The compilation of mariadb.1.1.4 failed at "./configure
        --prefix=/Users/mando/.opam/default".

#=== ERROR while compiling mariadb.1.1.4 ======================================#
# context     2.1.2 | macos/arm64 | ocaml.4.13.1 | https://opam.ocaml.org#28fab8d8
# path        ~/.opam/default/.opam-switch/build/mariadb.1.1.4
# command     ~/.opam/opam-init/hooks/sandbox.sh build ./configure --prefix=/Users/mando/.opam/default
# exit-code   1
# env-file    ~/.opam/log/mariadb-28306-488530.env
# output-file ~/.opam/log/mariadb-28306-488530.out
### output ###
# Could not detect a MariaDB client library



<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
+- The following actions failed
| - build mariadb 1.1.4
+- 
+- The following changes have been performed
| - recompile conf-mariadb    2
| - recompile conf-pkg-config 2
+- 

Thanks

./configure is not mentioned in README

it is required to call ./configure to build successfully, not ocaml setup.ml -configure as README advertises, which results in confusing :

E: Failure("No variable mariadb_include_base defined when trying to expand \"let _ =\\n  let prefix = \\\"mariadb_stub\\\" in\\n  let generate_ml, generate_c = ref false, ref false in\\n  Arg.parse\\n    [(\\\"-ml\\\", Arg.Set generate_ml, \\\"Generate ML\\\");\\n     (\\\"-c\\\",  Arg.Set generate_c,  \\\"Generate C\\\")]\\n    (fun _ -> failwith \\\"unexpected anonymous argument\\\")\\n    \\\"stubgen [-ml|-c]\\\";\\n  match !generate_ml, !generate_c with\\n  | false, false | true, true ->\\n      failwith \\\"Exactly one of -ml and -c must be specified\\\"\\n  | true, false ->\\n      Cstubs.write_ml\\n        Format.std_formatter ~prefix (module Ffi_bindings.Bindings)\\n  | false, true ->\\n      print_endline \\\"#include <$(mariadb_include_base)/mysql.h>\\\";\\n      Cstubs.write_c\\n        Format.std_formatter ~prefix (module Ffi_bindings.Bindings)\\n\".")

Corruption of data received from DB

I made the following adjustment to run the non-blocking lwt test repeatedly:

diff --git a/examples/lwt/nonblocking_lwt_example.ml b/examples/lwt/nonblocking_lwt_example.ml
index 4602598..d718b96 100644
--- a/examples/lwt/nonblocking_lwt_example.ml
+++ b/examples/lwt/nonblocking_lwt_example.ml
@@ -96,8 +96,12 @@ let main () =
   Lwt_stream.iter_s print_row s >>= fun () ->
   M.Stmt.close stmt >>= or_die "stmt close" >>= fun () ->
   M.close mariadb >>= fun () ->
-  M.library_end ();
   Lwt.return_unit
 
+let rec repeat_main n =
+  if n = 0 then Lwt.return_unit else
+  main () >>= fun () -> repeat_main (n - 1)
+
 let () =
-  Lwt_main.run @@ main ()
+  Lwt_main.run @@ repeat_main 1000;
+  M.library_end ()

With a simplified OCAML_MARIADB_QUERY='SELECT ?', I get Fatal error: exception Failure("connect: (1300) Invalid utf8mb4 character string: '0h\\x88\\x83bU'") and similar for the default query. But this only happens after an amount of data is returned, which I guess could correspond to a buffer size.

I am using Ubuntu 16.04, MariaDB 2.3.2, OCaml 4.05.0, and the master branch of ocaml-mariadb.


There may be another issue, but hopefully it is related to the above: I am trying to make test_parallel_lwt.ml from the Caqti testsuite work with MariaDB. This test invokes parallel connect, so I first tried to reproduce the issue with:

let rec repeat_main n =
  if n = 0 then Lwt.return_unit else
  main () <&> repeat_main (n - 1)

This modification gives me either a segment fault, and abort with additional message

unknown: debugger aborting because missing DBUG_RETURN or DBUG_VOID_RETURN macro in function "vio_read"

and a core file which given an uninformative backtrace, or sometimes a more informative:

*** Error in `./_build/examples/lwt/nonblocking_lwt_example.native': corrupted double-linked list: 0x0000562b449db6b0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7908b)[0x7fc35e00908b]
/lib/x86_64-linux-gnu/libc.so.6(+0x810c3)[0x7fc35e0110c3]
/lib/x86_64-linux-gnu/libc.so.6(+0x8462f)[0x7fc35e01462f]
/lib/x86_64-linux-gnu/libc.so.6(__libc_calloc+0x27b)[0x7fc35e0177cb]
/usr/lib/x86_64-linux-gnu/libmariadb.so.2(+0x307de)[0x7fc35ecba7de]
/usr/lib/x86_64-linux-gnu/libmariadb.so.2(mysql_init+0xd7)[0x7fc35ecb3387]
./_build/examples/lwt/nonblocking_lwt_example.native(+0x163651)[0x562b3e211651]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xbb21d)[0x562b3e16921d]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xc322e)[0x562b3e17122e]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xc6af7)[0x562b3e174af7]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb316c)[0x562b3e16116c]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3785)[0x562b3e161785]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
./_build/examples/lwt/nonblocking_lwt_example.native(+0xb3775)[0x562b3e161775]
======= Memory map: ========
562b3e0ae000-562b3e28d000 r-xp 00000000 fd:08 32244554                   /home/urkedal/proj-ext/ocaml-mariadb/_build/examples/lwt/nonblocking_lwt_example.native
562b3e48d000-562b3e48e000 r--p 001df000 fd:08 32244554                   /home/urkedal/proj-ext/ocaml-mariadb/_build/examples/lwt/nonblocking_lwt_example.native
562b3e48e000-562b3e537000 rw-p 001e0000 fd:08 32244554                   /home/urkedal/proj-ext/ocaml-mariadb/_build/examples/lwt/nonblocking_lwt_example.native
562b3e537000-562b3e54f000 rw-p 00000000 00:00 0 
562b402fe000-562b449e4000 rw-p 00000000 00:00 0                          [heap]
7fc358000000-7fc358021000 rw-p 00000000 00:00 0 
7fc358021000-7fc35c000000 ---p 00000000 00:00 0 
7fc35cc88000-7fc35cc9e000 r-xp 00000000 fd:05 392973                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7fc35cc9e000-7fc35ce9d000 ---p 00016000 fd:05 392973                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7fc35ce9d000-7fc35ce9e000 r--p 00015000 fd:05 392973                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7fc35ce9e000-7fc35ce9f000 rw-p 00016000 fd:05 392973                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7fc35ce9f000-7fc35ceaa000 r-xp 00000000 fd:05 396534                     /lib/x86_64-linux-gnu/libnss_files-2.24.so
7fc35ceaa000-7fc35d0a9000 ---p 0000b000 fd:05 396534                     /lib/x86_64-linux-gnu/libnss_files-2.24.so
7fc35d0a9000-7fc35d0aa000 r--p 0000a000 fd:05 396534                     /lib/x86_64-linux-gnu/libnss_files-2.24.so
7fc35d0aa000-7fc35d0ab000 rw-p 0000b000 fd:05 396534                     /lib/x86_64-linux-gnu/libnss_files-2.24.so
7fc35d0ab000-7fc35d0b1000 rw-p 00000000 00:00 0 
7fc35d103000-7fc35d6c7000 rw-p 00000000 00:00 0 
7fc35d6c7000-7fc35d8e0000 r-xp 00000000 fd:05 391463                     /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
7fc35d8e0000-7fc35dae0000 ---p 00219000 fd:05 391463                     /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
7fc35dae0000-7fc35dafc000 r--p 00219000 fd:05 391463                     /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
7fc35dafc000-7fc35db08000 rw-p 00235000 fd:05 391463                     /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
7fc35db08000-7fc35db0b000 rw-p 00000000 00:00 0 
7fc35db0b000-7fc35db69000 r-xp 00000000 fd:05 396126                     /lib/x86_64-linux-gnu/libssl.so.1.0.0
7fc35db69000-7fc35dd69000 ---p 0005e000 fd:05 396126                     /lib/x86_64-linux-gnu/libssl.so.1.0.0
7fc35dd69000-7fc35dd6d000 r--p 0005e000 fd:05 396126                     /lib/x86_64-linux-gnu/libssl.so.1.0.0
7fc35dd6d000-7fc35dd74000 rw-p 00062000 fd:05 396126                     /lib/x86_64-linux-gnu/libssl.so.1.0.0
7fc35dd74000-7fc35dd8f000 r-xp 00000000 fd:05 391974                     /lib/x86_64-linux-gnu/libz.so.1.2.11
7fc35dd8f000-7fc35df8e000 ---p 0001b000 fd:05 391974                     /lib/x86_64-linux-gnu/libz.so.1.2.11
7fc35df8e000-7fc35df8f000 r--p 0001a000 fd:05 391974                     /lib/x86_64-linux-gnu/libz.so.1.2.11
7fc35df8f000-7fc35df90000 rw-p 0001b000 fd:05 391974                     /lib/x86_64-linux-gnu/libz.so.1.2.11
7fc35df90000-7fc35e14e000 r-xp 00000000 fd:05 396376                     /lib/x86_64-linux-gnu/libc-2.24.so
7fc35e14e000-7fc35e34d000 ---p 001be000 fd:05 396376                     /lib/x86_64-linux-gnu/libc-2.24.so
7fc35e34d000-7fc35e351000 r--p 001bd000 fd:05 396376                     /lib/x86_64-linux-gnu/libc-2.24.so
7fc35e351000-7fc35e353000 rw-p 001c1000 fd:05 396376                     /lib/x86_64-linux-gnu/libc-2.24.so
7fc35e353000-7fc35e357000 rw-p 00000000 00:00 0 
7fc35e357000-7fc35e35a000 r-xp 00000000 fd:05 396393                     /lib/x86_64-linux-gnu/libdl-2.24.so
7fc35e35a000-7fc35e559000 ---p 00003000 fd:05 396393                     /lib/x86_64-linux-gnu/libdl-2.24.so
7fc35e559000-7fc35e55a000 r--p 00002000 fd:05 396393                     /lib/x86_64-linux-gnu/libdl-2.24.so
7fc35e55a000-7fc35e55b000 rw-p 00003000 fd:05 396393                     /lib/x86_64-linux-gnu/libdl-2.24.so
7fc35e55b000-7fc35e663000 r-xp 00000000 fd:05 396411                     /lib/x86_64-linux-gnu/libm-2.24.so
7fc35e663000-7fc35e862000 ---p 00108000 fd:05 396411                     /lib/x86_64-linux-gnu/libm-2.24.so
7fc35e862000-7fc35e863000 r--p 00107000 fd:05 396411                     /lib/x86_64-linux-gnu/libm-2.24.so
7fc35e863000-7fc35e864000 rw-p 00108000 fd:05 396411                     /lib/x86_64-linux-gnu/libm-2.24.so
7fc35e864000-7fc35e86b000 r-xp 00000000 fd:05 131522                     /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4
7fc35e86b000-7fc35ea6a000 ---p 00007000 fd:05 131522                     /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4
7fc35ea6a000-7fc35ea6b000 r--p 00006000 fd:05 131522                     /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4
7fc35ea6b000-7fc35ea6c000 rw-p 00007000 fd:05 131522                     /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4
7fc35ea6c000-7fc35ea84000 r-xp 00000000 fd:05 396923                     /lib/x86_64-linux-gnu/libpthread-2.24.so
7fc35ea84000-7fc35ec84000 ---p 00018000 fd:05 396923                     /lib/x86_64-linux-gnu/libpthread-2.24.so
7fc35ec84000-7fc35ec85000 r--p 00018000 fd:05 396923                     /lib/x86_64-linux-gnu/libpthread-2.24.so
7fc35ec85000-7fc35ec86000 rw-p 00019000 fd:05 396923                     /lib/x86_64-linux-gnu/libpthread-2.24.so
7fc35ec86000-7fc35ec8a000 rw-p 00000000 00:00 0 
7fc35ec8a000-7fc35ecdd000 r-xp 00000000 fd:05 141829                     /usr/lib/x86_64-linux-gnu/libmariadb.so.2
7fc35ecdd000-7fc35eedd000 ---p 00053000 fd:05 141829                     /usr/lib/x86_64-linux-gnu/libmariadb.so.2
7fc35eedd000-7fc35eee3000 r--p 00053000 fd:05 141829                     /usr/lib/x86_64-linux-gnu/libmariadb.so.2
7fc35eee3000-7fc35eee5000 rw-p 00059000 fd:05 141829                     /usr/lib/x86_64-linux-gnu/libmariadb.so.2
7fc35eee5000-7fc35eeec000 rw-p 00000000 00:00 0 
7fc35eeec000-7fc35ef12000 r-xp 00000000 fd:05 392200                     /lib/x86_64-linux-gnu/ld-2.24.so
7fc35ef33000-7fc35f0bc000 rw-p 00000000 00:00 0 
7fc35f0cc000-7fc35f111000 rw-p 00000000 00:00 0 
7fc35f111000-7fc35f112000 r--p 00025000 fd:05 392200                     /lib/x86_64-linux-gnu/ld-2.24.so
7fc35f112000-7fc35f113000 rw-p 00026000 fd:05 392200                     /lib/x86_64-linux-gnu/ld-2.24.so
7fc35f113000-7fc35f114000 rw-p 00000000 00:00 0 
7ffe94221000-7ffe94243000 rw-p 00000000 00:00 0                          [stack]
7ffe9428d000-7ffe9428f000 r--p 00000000 00:00 0                          [vvar]
7ffe9428f000-7ffe94291000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

ctypes.foreign dependency is not needed

it brings in libffi runtime dependency which is totally unnecessary

fix:

diff --git a/_oasis b/_oasis
index 3fd581c..9d913b9 100644
--- a/_oasis
+++ b/_oasis
@@ -54,7 +54,7 @@ Library "mariadb_bindings"
   Modules:          Ffi_bindings
   ByteOpt:          -warn-error +1..45
   NativeOpt:        -warn-error +1..45
-  BuildDepends:     ctypes.stubs, ctypes.foreign
+  BuildDepends:     ctypes.stubs
 
 Executable "ffi_stubgen"
   Install:          false

followed by oasis setup

empty error string for prepared statements

Looks like it is a simple typo :

diff --git a/lib/common.ml b/lib/common.ml
index dcc8b98..89cbcce 100644
--- a/lib/common.ml
+++ b/lib/common.ml
@@ -278,7 +278,7 @@ module Stmt = struct
     | Prefetch_rows of int
 
   let error stmt =
-    (B.mysql_stmt_errno stmt.raw, B.mysql_error stmt.raw)
+    (B.mysql_stmt_errno stmt.raw, B.mysql_stmt_error stmt.raw)
 
   let fetch_field res i =
     coerce (ptr void) (ptr T.Field.t) (B.mysql_fetch_field_direct res i)

macOS: Could not detect a MariaDB client library

When trying to install mariadb I get this:

β†ͺ  opam install mariadb                                                                                     0@10:17:33
The following actions will be performed:
  βˆ— install mariadb 1.1.1

<><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><>  🐫
[mariadb.1.1.1] found in cache

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><>  🐫
[ERROR] The compilation of mariadb failed at "/Users/serveradmin/.opam/opam-init/hooks/sandbox.sh build ./configure
        --prefix=/Users/serveradmin/Projects/OVPSync/_opam".

#=== ERROR while compiling mariadb.1.1.1 ======================================#
# context     2.0.0 | macos/x86_64 | ocaml-system.4.05.0 | https://opam.ocaml.org#b1ac8b1e
# path        ~/Projects/OVPSync/_opam/.opam-switch/build/mariadb.1.1.1
# command     ~/.opam/opam-init/hooks/sandbox.sh build ./configure --prefix=/Users/serveradmin/Projects/OVPSync/_opam
# exit-code   1
# env-file    ~/.opam/log/mariadb-57057-ffb3fd.env
# output-file ~/.opam/log/mariadb-57057-ffb3fd.out
### output ###
# Could not detect a MariaDB client library

I put together this command from looking at configure

gcc ~/Projects/OVPSync/_opam/.opam-switch/build/mariadb.1.1.1/detect/detect.c -lmysqlclient -DMARIADB_CLIENT

That works on another macOS computer (running Mojave) but on the target system I get:

/Users/serveradmin/Projects/OVPSync/_opam/.opam-switch/build/mariadb.1.1.1/detect/detect.c:3:10: fatal error:
      'mysql/mysql.h' file not found
#include <mysql/mysql.h>
         ^
1 error generated.

I've installed mariadb using brew install mariadb and that worked fine on my other system. mysql.sh exists at /usr/local/include/mysql just as it does on the working system.

If I add the options -I /usr/local/include -L /usr/local/lib the gcc command, it succeeds:

gcc -I /usr/local/include -L /usr/local/lib ~/Projects/OVPSync/_opam/.opam-switch/build/mariadb.1.1.1/detect/detect.c -lmysqlclient -DMARIADB_CLIENT

But I don't know how to do that with opam install mariadb and I suspect this hints at some deeper issue.

Running gcc -x c++ -v -E /dev/null to list the include paths, I get:

β†ͺ  gcc -x c++ -v -E /dev/null                                                                               0@13:53:49
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin16.0.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -E -disable-free -disable-llvm-verifier -discard-value-names -main-file-name null -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu penryn -target-linker-version 274.1 -v -dwarf-column-info -debugger-tuning=lldb -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -stdlib=libc++ -fdeprecated-macro -fdebug-compilation-dir /Users/serveradmin/Projects/OVPSync -ferror-limit 19 -fmessage-length 118 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.12.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o - -x c++ /dev/null
clang -cc1 version 8.0.0 (clang-800.0.38) default target x86_64-apple-darwin16.0.0
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/c++/v1"
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/local/include"
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks (framework directory)
End of search list.
# 1 "/dev/null"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 337 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "/dev/null" 2

On the working system, "/usr/local/include" is listed as the first line under "#include <...> search starts here:".

The target system is running macOS Sierra 10.12.

Building on macOS fails

Hi,

I am trying to build things on macOS and the configure script fails. This is due to neither mysqlclient nor mariadb usually being in the library path (at least not when installing the connector via brew). The way to build things is to use mysql_config --cflags or mariadb_config --cflags, which will return the correct locations for building on both macOS as well as GNU/Linux systems, so I think it is better to use that than to attempt to compile a detect.c.

Installing/building on OSX

I'm running OSX 10.11.6 (El Capitan) and OCaml 4.03.0. I've installed MariaDB Connector/C 2.2.2 via Homebrew (brew install mariadb-connector-c).

When trying to install mariadb via opam, I get the following error:

> opam install mariadb
The following actions will be performed:
  βˆ—  install mariadb 0.5.1

=-=- Gathering sources =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=  🐫
[mariadb] Archive in cache

=-=- Processing actions -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=  🐫
[ERROR] The compilation of mariadb failed at "make".
Processing  1/1: [mariadb: ocamlfind remove]
#=== ERROR while installing mariadb.0.5.1 =====================================#
# opam-version 1.2.2
# os           darwin
# command      make
# path         /Users/agarnaes/.opam/4.03.0/build/mariadb.0.5.1
# compiler     4.03.0
# exit-code    2
# env-file     /Users/agarnaes/.opam/4.03.0/build/mariadb.0.5.1/mariadb-86521-58c514.env
# stdout-file  /Users/agarnaes/.opam/4.03.0/build/mariadb.0.5.1/mariadb-86521-58c514.out
# stderr-file  /Users/agarnaes/.opam/4.03.0/build/mariadb.0.5.1/mariadb-86521-58c514.err
### stdout ###
# [...]
# /Users/agarnaes/.opam/4.03.0/bin/ocamlfind ocamlc -c -g -annot -bin-annot -I bindings -warn-error +1..45 -warn-error +1..45 -package ctypes.stubs -package ctypes.foreign -I stubgen -I bindings -o stubgen/ffi_stubgen.cmo stubgen/ffi_stubgen.ml
# /Users/agarnaes/.opam/4.03.0/bin/ocamlfind ocamlc -linkpkg -g -warn-error +1..45 -linkpkg -package ctypes.stubs -package ctypes.foreign bindings/mariadb_bindings.cma stubgen/ffi_stubgen.cmo -o stubgen/ffi_stubgen.byte
# stubgen/ffi_stubgen.byte -c > lib/ffi_generated_stubs.c
# /Users/agarnaes/.opam/4.03.0/bin/ocamlfind ocamlc -g -I lib -package ctypes -ccopt -I -ccopt /Users/agarnaes/.opam/4.03.0/lib/ctypes -package unix -package ctypes.stubs -package ctypes.foreign -c lib/ffi_generated_stubs.c
# + /Users/agarnaes/.opam/4.03.0/bin/ocamlfind ocamlc -g -I lib -package ctypes -ccopt -I -ccopt /Users/agarnaes/.opam/4.03.0/lib/ctypes -package unix -package ctypes.stubs -package ctypes.foreign -c lib/ffi_generated_stubs.c
# lib/ffi_generated_stubs.c:1:10: fatal error: 'mysql/mysql.h' file not found
# #include <mysql/mysql.h>
#          ^
# 1 error generated.
# Command exited with code 2.
### stderr ###
# W: Cannot find source file matching module 'Ffi_generated' in library mariadb
# W: Cannot find source file matching module 'Ffi_generated_types' in library mariadb
# E: Failure("Command ''/Users/agarnaes/.opam/4.03.0/bin/ocamlbuild' bindings/mariadb_bindings.cma bindings/mariadb_bindings.cmxa bindings/mariadb_bindings.a bindings/mariadb_bindings.cmxs lib/libmariadb_stubs.a lib/dllmariadb_stubs.so lib/mariadb.cma lib/mariadb.cmxa lib/mariadb.a lib/mariadb.cmxs stubgen/ffi_stubgen.byte stubgen/ffi_types_stubgen.byte examples/select/nonblocking_select_example.native examples/blocking/blocking_example.native -use-ocamlfind -tag debug' terminated with error code 10")
# make: *** [build] Error 1

It seems like mysql.h is under mariadb/mysql.h in my setup. If I create a symlink to remedy this, I get the following error instead:

> opam install mariadb
The following actions will be performed:
  βˆ—  install mariadb 0.5.1

=-=- Gathering sources =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=  🐫
[mariadb] Archive in cache

=-=- Processing actions -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=  🐫
[ERROR] The compilation of mariadb failed at "make".
Processing  1/1: [mariadb: ocamlfind remove]
#=== ERROR while installing mariadb.0.5.1 =====================================#
# opam-version 1.2.2
# os           darwin
# command      make
# path         /Users/agarnaes/.opam/4.03.0/build/mariadb.0.5.1
# compiler     4.03.0
# exit-code    2
# env-file     /Users/agarnaes/.opam/4.03.0/build/mariadb.0.5.1/mariadb-87151-58c514.env
# stdout-file  /Users/agarnaes/.opam/4.03.0/build/mariadb.0.5.1/mariadb-87151-58c514.out
# stderr-file  /Users/agarnaes/.opam/4.03.0/build/mariadb.0.5.1/mariadb-87151-58c514.err
### stdout ###
# stubgen/ffi_ml_types_stubgen.c:466:71: error: use of undeclared identifier 'MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS'
# [...]
# stubgen/ffi_ml_types_stubgen.c:467:15: error: use of undeclared identifier 'MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS'; did you mean 'check_MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS_const'?
#      int v = (MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS);
#               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#               check_MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS_const
# stubgen/ffi_ml_types_stubgen.c:466:13: note: 'check_MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS_const' declared here
#      enum { check_MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS_const = (int)MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS };
#             ^
# 6 errors generated.
# Command exited with code 1.
### stderr ###
# W: Cannot find source file matching module 'Ffi_generated' in library mariadb
# W: Cannot find source file matching module 'Ffi_generated_types' in library mariadb
# E: Failure("Command ''/Users/agarnaes/.opam/4.03.0/bin/ocamlbuild' bindings/mariadb_bindings.cma bindings/mariadb_bindings.cmxa bindings/mariadb_bindings.a bindings/mariadb_bindings.cmxs lib/libmariadb_stubs.a lib/dllmariadb_stubs.so lib/mariadb.cma lib/mariadb.cmxa lib/mariadb.a lib/mariadb.cmxs stubgen/ffi_stubgen.byte stubgen/ffi_types_stubgen.byte examples/select/nonblocking_select_example.native examples/blocking/blocking_example.native -use-ocamlfind -tag debug' terminated with error code 10")
# make: *** [build] Error 1

i.e. the constant MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS is not defined. To investigate this further, I checked out the repo and looked into this missing constant. As far as I can tell, the constants MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS and MYSQL_OPT_USE_THREAD_SPECIFIC_MEMORY are not defined in any header files in MariaDB Connector/C 2.2.2, nor in any other version I can find on the releases homepage.

So to make it build, I tried removing use of those constants (and also changed the mysql/mysql.h to mariadb/mysql.h): https://gist.github.com/andreas/0e580b19df542f1dbe1ee2676a2c6768

With the above patch, I got a little further, but sadly still an error when trying to build:

> ocaml setup.ml -build
W: Cannot find source file matching module 'Ffi_generated' in library mariadb
W: Cannot find source file matching module 'Ffi_generated_types' in library mariadb
Finished, 0 targets (0 cached) in 00:00:00.
+ /Users/agarnaes/.opam/4.03.0/bin/ocamlfind ocamlopt -linkpkg -g -I lib -warn-error +1..45 -linkpkg -package unix -package ctypes.stubs -package ctypes.foreign bindings/mariadb_bindings.cmxa lib/mariadb.cmxa examples/select/nonblocking_select_example.cmx -o examples/select/nonblocking_select_example.native
Undefined symbols for architecture x86_64:
  "_ASN1_STRING_data", referenced from:
      _my_ssl_verify_server_cert in libmysqlclient.a(ma_secure.c.o)
  "_ASN1_STRING_length", referenced from:
      _my_ssl_verify_server_cert in libmysqlclient.a(ma_secure.c.o)
  "_CONF_modules_free", referenced from:
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
  "_CONF_modules_unload", referenced from:
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
  "_CRYPTO_THREADID_set_callback", referenced from:
      _my_ssl_start in libmysqlclient.a(ma_secure.c.o)
  "_CRYPTO_THREADID_set_numeric", referenced from:
      _my_cb_threadid in libmysqlclient.a(ma_secure.c.o)
  "_CRYPTO_cleanup_all_ex_data", referenced from:
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
  "_CRYPTO_num_locks", referenced from:
      _my_ssl_start in libmysqlclient.a(ma_secure.c.o)
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
  "_CRYPTO_set_id_callback", referenced from:
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
  "_CRYPTO_set_locking_callback", referenced from:
      _my_ssl_start in libmysqlclient.a(ma_secure.c.o)
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
  "_ERR_free_strings", referenced from:
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
  "_ERR_get_error", referenced from:
      _my_SSL_error in libmysqlclient.a(ma_secure.c.o)
  "_ERR_reason_error_string", referenced from:
      _my_SSL_error in libmysqlclient.a(ma_secure.c.o)
  "_ERR_remove_state", referenced from:
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
      _my_thread_end in libmysqlclient.a(my_thr_init.c.o)
  "_EVP_MD_size", referenced from:
      _ma_ssl_verify_fingerprint in libmysqlclient.a(ma_secure.c.o)
  "_EVP_cleanup", referenced from:
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
  "_EVP_sha1", referenced from:
      _ma_ssl_verify_fingerprint in libmysqlclient.a(ma_secure.c.o)
  "_OPENSSL_add_all_algorithms_noconf", referenced from:
      _my_ssl_start in libmysqlclient.a(ma_secure.c.o)
  "_OPENSSL_config", referenced from:
      _my_ssl_start in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CIPHER_get_name", referenced from:
      _mysql_get_ssl_cipher in libmysqlclient.a(libmariadb.c.o)
  "_SSL_COMP_get_compression_methods", referenced from:
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CTX_check_private_key", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CTX_free", referenced from:
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CTX_get_cert_store", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CTX_load_verify_locations", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CTX_new", referenced from:
      _my_ssl_start in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CTX_set_cipher_list", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CTX_set_default_verify_paths", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CTX_set_verify", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CTX_set_verify_depth", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CTX_use_PrivateKey_file", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_SSL_CTX_use_certificate_file", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_SSL_SESSION_set_timeout", referenced from:
      _my_ssl_connect in libmysqlclient.a(ma_secure.c.o)
  "_SSL_clear", referenced from:
      _my_ssl_connect in libmysqlclient.a(ma_secure.c.o)
  "_SSL_connect", referenced from:
      _my_ssl_connect in libmysqlclient.a(ma_secure.c.o)
  "_SSL_free", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
      _my_ssl_close in libmysqlclient.a(ma_secure.c.o)
      _client_mpvio_write_packet in libmysqlclient.a(my_auth.c.o)
  "_SSL_get_current_cipher", referenced from:
      _mysql_get_ssl_cipher in libmysqlclient.a(libmariadb.c.o)
  "_SSL_get_error", referenced from:
      _my_ssl_async_check_result in libmysqlclient.a(mysql_async.c.o)
  "_SSL_get_ex_data", referenced from:
      _my_verify_callback in libmysqlclient.a(ma_secure.c.o)
      _my_ssl_connect in libmysqlclient.a(ma_secure.c.o)
      _ma_ssl_verify_fingerprint in libmysqlclient.a(ma_secure.c.o)
      _my_ssl_verify_server_cert in libmysqlclient.a(ma_secure.c.o)
  "_SSL_get_ex_data_X509_STORE_CTX_idx", referenced from:
      _my_verify_callback in libmysqlclient.a(ma_secure.c.o)
  "_SSL_get_peer_certificate", referenced from:
      _ma_ssl_verify_fingerprint in libmysqlclient.a(ma_secure.c.o)
      _my_ssl_verify_server_cert in libmysqlclient.a(ma_secure.c.o)
  "_SSL_get_session", referenced from:
      _my_ssl_connect in libmysqlclient.a(ma_secure.c.o)
  "_SSL_get_verify_result", referenced from:
      _my_ssl_connect in libmysqlclient.a(ma_secure.c.o)
  "_SSL_library_init", referenced from:
      _my_ssl_start in libmysqlclient.a(ma_secure.c.o)
  "_SSL_load_error_strings", referenced from:
      _my_ssl_start in libmysqlclient.a(ma_secure.c.o)
  "_SSL_new", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_SSL_read", referenced from:
      _my_ssl_read_async in libmysqlclient.a(mysql_async.c.o)
      _my_ssl_read in libmysqlclient.a(ma_secure.c.o)
  "_SSL_set_ex_data", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_SSL_set_fd", referenced from:
      _my_ssl_connect in libmysqlclient.a(ma_secure.c.o)
  "_SSL_set_quiet_shutdown", referenced from:
      _my_ssl_close in libmysqlclient.a(ma_secure.c.o)
  "_SSL_shutdown", referenced from:
      _my_ssl_close in libmysqlclient.a(ma_secure.c.o)
  "_SSL_write", referenced from:
      _my_ssl_write_async in libmysqlclient.a(mysql_async.c.o)
      _my_ssl_write in libmysqlclient.a(ma_secure.c.o)
  "_TLSv1_client_method", referenced from:
      _my_ssl_start in libmysqlclient.a(ma_secure.c.o)
  "_X509_NAME_ENTRY_get_data", referenced from:
      _my_ssl_verify_server_cert in libmysqlclient.a(ma_secure.c.o)
  "_X509_NAME_get_entry", referenced from:
      _my_ssl_verify_server_cert in libmysqlclient.a(ma_secure.c.o)
  "_X509_NAME_get_index_by_NID", referenced from:
      _my_ssl_verify_server_cert in libmysqlclient.a(ma_secure.c.o)
  "_X509_STORE_CTX_get_current_cert", referenced from:
      _my_verify_callback in libmysqlclient.a(ma_secure.c.o)
  "_X509_STORE_CTX_get_error_depth", referenced from:
      _my_verify_callback in libmysqlclient.a(ma_secure.c.o)
  "_X509_STORE_CTX_get_ex_data", referenced from:
      _my_verify_callback in libmysqlclient.a(ma_secure.c.o)
  "_X509_STORE_load_locations", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_X509_STORE_set_flags", referenced from:
      _my_ssl_init in libmysqlclient.a(ma_secure.c.o)
  "_X509_digest", referenced from:
      _ma_ssl_verify_fingerprint in libmysqlclient.a(ma_secure.c.o)
  "_X509_free", referenced from:
      _my_ssl_verify_server_cert in libmysqlclient.a(ma_secure.c.o)
  "_X509_get_subject_name", referenced from:
      _my_ssl_verify_server_cert in libmysqlclient.a(ma_secure.c.o)
  "_X509_verify_cert_error_string", referenced from:
      _my_ssl_connect in libmysqlclient.a(ma_secure.c.o)
  "_iconv", referenced from:
      _mariadb_convert_string in libmysqlclient.a(my_charset.c.o)
     (maybe you meant: _camlCamlinternalFormat__format_of_iconv_62392, _camlCamlinternalFormat__bprint_iconv_flag_1425 , _camlCamlinternalFormat__char_of_iconv_1354 , _camlCamlinternalFormat__format_of_iconvL_62394 , _camlCamlinternalFormat__format_of_iconvn_62398 , _camlCamlinternalFormat__format_of_iconvl_62396 )
  "_iconv_close", referenced from:
      _mariadb_convert_string in libmysqlclient.a(my_charset.c.o)
  "_iconv_open", referenced from:
      _mariadb_convert_string in libmysqlclient.a(my_charset.c.o)
  "_sk_free", referenced from:
      _my_ssl_end in libmysqlclient.a(ma_secure.c.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
File "caml_startup", line 1:
Error: Error during linking
Command exited with code 2.
Compilation unsuccessful after building 68 targets (65 cached) in 00:00:01.
E: Failure("Command ''/Users/agarnaes/.opam/4.03.0/bin/ocamlbuild' bindings/mariadb_bindings.cma bindings/mariadb_bindings.cmxa bindings/mariadb_bindings.a bindings/mariadb_bindings.cmxs lib/libmariadb_stubs.a lib/dllmariadb_stubs.so lib/mariadb.cma lib/mariadb.cmxa lib/mariadb.a lib/mariadb.cmxs stubgen/ffi_stubgen.byte stubgen/ffi_types_stubgen.byte examples/select/nonblocking_select_example.native examples/blocking/blocking_example.native -use-ocamlfind -tag debug' terminated with error code 10")

It seems the problem is that brew puts .dylib's in /usr/local/lib/mariadb/. I was able to fix it by symlinking libmysqlclient.dylib, libmariadb.dylib and libmariadb.2.dylib into /usr/local/lib.

As such, I got it working in the end, but it took quite some hairpulling πŸ˜„ It would be great if the library installed cleanly via opam on OSX.

Timestamps are marked unsigned

When selecting from a timestamp column, the result is marked unsigned, triggering failwith "unexpected unsigned type" in Field.convert_unsigned. To reproduce it, create a table:

create table test (t timestamp);
insert into test values (now());

and run

OCAML_MARIADB_QUERY="SELECT ?, t FROM test" _build/examples/blocking/blocking_example.native

This would solve this case at least,

diff --git a/lib/field.ml b/lib/field.ml
index 73eca28..cbb0488 100644
--- a/lib/field.ml
+++ b/lib/field.ml
@@ -90,6 +90,7 @@ let convert_unsigned field = function
   | `Short -> `Int (Unsigned.UInt.to_int (cast_to uint field))
   | `Int24 | `Long -> `Int (Unsigned.UInt32.to_int (cast_to uint32_t field))
   | `Long_long -> `Int (Unsigned.UInt64.to_int (cast_to uint64_t field))
+  | `Timestamp as kind -> `Time (to_time field kind)
   | _ -> failwith "unexpected unsigned type"
 
 let value field =

though maybe it would be better to dispatch on both datatype and signedness in one, or datatype optionally followed by signedness.

Memory leak

There seems to be a memory leak apparent by the stress tests from the example directory. To make the issue clear, I elevated the iteration counts,

diff --git a/examples/blocking/blocking_stress_test.ml b/examples/blocking/blocking_stress_test.ml
index 022e872..0ac77d4 100644
--- a/examples/blocking/blocking_stress_test.ml
+++ b/examples/blocking/blocking_stress_test.ml
@@ -41,4 +41,4 @@ let test () =
   M.Stmt.close !stmt |> or_die "Stmt.close";
   M.close dbh
 
-let () = for _ = 1 to 500 do test () done
+let () = for _ = 1 to 20000 do test () done
diff --git a/examples/nonblocking/nonblocking_stress_test.ml b/examples/nonblocking/nonblocking_stress_test.ml
index 8ba5807..bfda03a 100644
--- a/examples/nonblocking/nonblocking_stress_test.ml
+++ b/examples/nonblocking/nonblocking_stress_test.ml
@@ -163,5 +163,5 @@ module Make (W : Mariadb.Nonblocking.Wait) = struct
       stmt_cache (return ()) >>= fun () ->
     M.close dbh
 
-  let main () = repeat 500 test
+  let main () = repeat 5000 test
 end

and monitored it with top. For all three concurrency variants, the memory usage starts around 40 MiB and climbs steadily to around 160--180 MiB during the run on Ubuntu 18.04 with OCaml 4.07.1.

Mariadb 10.5 Insert ... Returning

Hi, I'm new to Ocaml and have been experimenting with this, but can't seem to figure out what I'm doing wrong.

The query I'm using is "INSERT INTO users VALUES (NULL) RETURNING id" just to insert an empty user and get the insert ID.

If I call Res.num_rows and pass the result it returns that there is 1 result row, but when I try to use Res.fetch to get the resulting ID I'm not able to, it always seems to return an Ok but with None instead of Some row.

Apologies if there's a simple solution to this or something I'm misunderstanding.

`Res.affected_rows` not available where it's needed

I think there is a design flaw in the way mysql_stmt_affected_rows is exposed. Stmt.execute returns None : Res.t option for INSERT or UPDATE statements, making Res.affected_rows unavailable. I can see the logic of placing this function there, though. I guess the options are to move the function to Stmt.t or synthesising a Res.t with num_rows = 0 and a fetch consistent with it?

Support for syntax not allowed as prepared statements

MariaDB/MySQL does not allow certain syntax in prepared statements, so it seems, at least for now, the mysql_query and the related async functions are needed to support the full SQL language.

I had a look at it in connection with paurkedal/ocaml-caqti#42, but if I've understood the MariaDB documentation correctly, the result processing of the non-prepared API is quite orthogonal to that of the prepared API. I suspect it would require significant refactoring or split of the result handling.

Segmentation fault when binding string parameters

The following program fails with a segmentation fault on my end (Ubuntu 16.04, opam switch 4.04.0):

open Printf

module M = Mariadb.Blocking

let env var def =
  try Sys.getenv var
  with Not_found -> def

let or_die where = function
  | Ok r -> r
  | Error (i, e) -> ksprintf failwith "%s: (%d) %s" where i e

let connect () =
  M.connect
    ~host:(env "OCAML_MARIADB_HOST" "localhost")
    ~user:(env "OCAML_MARIADB_USER" "root")
    ~pass:(env "OCAML_MARIADB_PASS" "")
    ~db:(env "OCAML_MARIADB_DB" "mysql") ()

let test dbh =
  for i = 0 to 19999 do
    let n = Random.int (1 lsl Random.int 8) in
    let s = String.init n (fun i -> "ACGT".[Random.int 4]) in
    (*Printf.printf "%s\n%!" s;*)
    let stmt = M.prepare dbh "SELECT ?" |> or_die "prepare" in
    (match M.Stmt.execute stmt [|`String s|] |> or_die "execute" with
     | Some res ->
        assert (M.Res.num_rows res = 1);
        (match M.Res.fetch (module M.Row.Array) res |> or_die "fetch" with
         | None -> assert false
         | Some row -> assert (M.Field.string row.(0) = s))
     | None -> assert false);
    M.Stmt.close stmt |> or_die "close"
  done

let () = test (connect () |> or_die "connect")

I think I've tracked the issue down to the allocation of the buffer storing the parameter value. The documentation of Ctypes.allocate says that "the value will be automatically freed after no references to the pointer remain within the calling OCaml program", and the buffers are only stored in another allocated fragment, which I presume is not scanned by the ocaml garbage collector.

Error 1264 Out of range value with Docker/Alpine

After some investigation of paurkedal/ocaml-caqti#23, it is clear that the issue is at a level below caqti, so I'm promoting the issue, as I'm suspecting some memory or compatibility issue with the C bindings, esp. considering the randomness seen for the DELETE statement in the original report.

I made a Docker build mariadb-alpine-issue.tar.gz to remove Caqti and node.js from the equation. In addition to the supplied test, the failures for blocking_stress_test and nonblocking_select_stress_test mentioned in the original bug report can also be reproduced in the same opam environment using a Git checkout of the current master.

Prepare of CREATE TABLE and INSERT fails without error details

The command

OCAML_MARIADB_QUERY='CREATE TABLE test (i INTEGER)' ./blocking_example.native

gives

Fatal error: exception Failure("prepare: (0) ")

The query INSERT INTO test VALUES (1) gives the same error, so it's probably related to statements returning empty results.

INT fields with NULL value returned as (`Int 0) instead of (`Null)

I have a table with the field:

`port` int(11) unsigned DEFAULT NULL

When queried with ocaml-mariadb, `Int 0 is returned for that field instead of `Null when its value in MariaDB is NULL.

Abridged code:

module Mdb = Mariadb.Blocking

let stream res =
  let module M = Mariadb.Blocking in
  let module F = struct exception E of M.error end in
  let next _ =
    match M.Res.fetch (module M.Row.Map) res with
    | Ok (Some _ as row) -> row
    | Ok None -> None
    | Error e -> raise (F.E e) in
  try Ok (Stream.from next)
  with F.E e -> Error e

let or_die where = function
  | Ok x -> x
  | Error (num, msg) -> failwith @@ sprintf "%s #%d: %s" where num msg 

let execute_query connection query values yield =
  let stmt = Mdb.prepare connection query |> or_die "prepare" in
  let result = Mdb.Stmt.execute stmt values |> or_die "execute" in
  let return = yield result in
  Mdb.Stmt.close stmt |> or_die "close statement";
  return

let first_row_of_result = function
  | None -> None
  | Some res -> match Mdb.Res.num_rows res with 
    | 0 -> None
    | _ -> Some (Stream.next (stream res |> or_die "stream"))

exception Unexpected_type_for_key of string

let maybe_int_of_map row key =
   match find_map_value row key with
   | `Null -> None
   | `Int value -> Some value
   | x -> raise (Unexpected_type_for_key key ^ " expected to be int or null")

let () =
  let query = "SELECT port FROM url" in

  let port = execute_query connection query [|  |] (fun result ->
    match first_row_of_result result with
    | None -> None
    | Some row -> maybe_int_of_map row "port"
  in

  let string = match port with
  | None -> "No port"
  | Some p -> "The port is " ^ (string_of_int p) in

  print_endline string

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.