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
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