mssql

Async SQL Server client using FreeTDS
README




Mssql is an Async OCaml SQL Server
library, currently using FreeTDS.

Features

  • Queries run in a background thread and play nicely with Async (assuming
    you're pinning freetds so it releases the runtime lock)

  • Supports single connections or connection pools

  • Supports automatic conversions for common data types

  • Supports parameterized queries (although internally it's not very nice;
    we parse the query for $ parameters and then insert quoted params)

  • We have workarounds for FreeTDS madness, like how there's no simple way to
    know what date format FreeTDS was configured with

  • Intellegently handles concurrent usage for both executing queries and with
    transactions

  • Heavily tested

Regarding concurrent usage, the following code is safe:

let%map res1 = Mssql.execute db "SELECT * FROM table_a"
and res2 = Mssql.execute db "SELECT * FROM table_b"
in
...

Since we don't support actual concurrency, this will run one query and then
the other (order is not defined).

This is also safe and will never cause a duplicate primary key error, since
we prevent concurrent usage of a connection outside of a transactio if a
transaction is in progress on that connection:

Mssql.execute_unit "CREATE TABLE x (id INT PRIMARY KEY)"
>>= fun () ->
let%map () =
  Mssql.with_transaction db (fun db ->
    Mssql.execute_unit db "INSERT INTO x (id) VALUES (1)"
    >>= fun ()->
    Mssql.execute_unit db ~params:Mssql.Param.[Some (Int 1)]
      "DELETE FROM x WHERE id = $1")
and Mssql.execute db "INSERT INTO x (id) VALUES (1)"

Obviously this only works if we know about the transaction, so using
Mssql.begin_transaction or Mssql.execute_unit "begin" won't have this
feature.

Contributions

This library is heavily optimized for our use-case, but we would love to see
contributions to:

  • Support Lwt and blocking IO

  • Support parameterized queries in a better way

  • Switch to pure OCaml and not use FreeTDS

This is not an exhaustive list -- feel free to create an issue if you're
considering making a new feature and want to know if we'll accept it, or just
open a pull request.

Installation

You can find mssql on opam:

opam install mssql

Or you can pin this repo if you want:

opam pin add mssql https://github.com/arenadotio/ocaml-mssql.git

Usage

The tests are full of examples and you can find
documentation here.

Example

Mssql.with_conn ~host ~db ~user ~password (fun db ->
  Mssql.execute_unit db
    "CREATE TABLE example (id INT NOT NULL, value INT NOT NULL)"
  >>= fun () ->
  Mssql.execute_unit db "INSERT INTO example (id, value) VALUES (1, 2)"
  >>= fun () ->
  Mssql.execute db ~params:Mssql.Param.[Some (Int 1)]
    "SELECT id FROM example WHERE id = $1"
  >>| function
  | [ row ] ->
    let id = Mssql.Row.int_exn row "id"
    and value = Mssql.Row.int_exn row "value" in
    printf "Got row with id=%d value=%d" id value
  | _ -> assert false)
Install
Sources
mssql-2.2.0.tbz
sha256=4c1bba6dd0fc6be8a5a370050400192dbe54706e7c070b4d2ddce5845d5239e2
sha512=d2dd16f9bd0df3dac374d218fd8359e9a04cafabb47057dcafce9424abe624256e41b495b8b178a804f982c87c92f5f9244bae5601a937b554e61e0eaf447931
Dependencies
dune
>= "1.11"
bisect_ppx
dev & >= "2.0.0"
freetds
>= "0.7"
text
>= "0.8.0"
odoc
with-doc
ocaml
>= "4.06.1"
iter
>= "1.2"
ppx_jane
< "v0.15"
bignum
< "v0.15"
async_unix
< "v0.15"
alcotest-async
with-test & >= "1.0.1"
alcotest
with-test & >= "1.0.1"
Reverse Dependencies