package mssql
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=4c1bba6dd0fc6be8a5a370050400192dbe54706e7c070b4d2ddce5845d5239e2
sha512=d2dd16f9bd0df3dac374d218fd8359e9a04cafabb47057dcafce9424abe624256e41b495b8b178a804f982c87c92f5f9244bae5601a937b554e61e0eaf447931
Description
Mssql wraps FreeTDS in a nicer and safer interface, with support for parameterized queries, thread-based async IO, and a thread pool.
Published: 05 Mar 2021
README
README.md
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)
Dependencies (9)
Dev Dependencies (4)
-
bisect_ppx
dev & >= "2.0.0"
-
odoc
with-doc
-
alcotest-async
with-test & >= "1.0.1"
-
alcotest
with-test & >= "1.0.1"
Used by
None
Conflicts
None