[ANN] Petrol 1.2.0 release - Postgres Support + User-extensible types

Heyo all!

I’m pleased to announce the latest release of Petrol - A high level typed SQL API for OCaml (in the process of being published to opam).

This latest release is exciting as it now adds Postgresql support (previously Petrol only supported Sqlite3).

Petrol makes using SQL from OCaml a breeze:

open Petrol
open Petrol.Sqlite3

(* define a new schema *)
let schema = StaticSchema.init ()

(* declare a table *)
let example_table, Expr.[name; age] =
    StaticSchema.declare_table schema ~name:"example"
    Schema.[
        field "name" ~ty:Type.text;
        field "age" ~ty:Type.int
    ]

and here’s how you write queries:

(* create a query *)
let insert_person ~name:n ~age:a db =
    Query.insert ~table:example_table
        ~values:Expr.[
            name := s n;
            age := i a
         ]
    |> Request.make_zero
    |> Petrol.exec db

Petrol compiles down to Caqti queries under the hood, and comes with a nifty migration system built-in, so you can seamlesly update your database tables without disrupting end users:

(* declare a table with a migration for a new [age] column in version 1.2.0 *)
let t, Expr.[id;age;url] =
   VersionedSchema.declare_table db ~name:"person"
     Schema.[
       field ~constraints:[primary_key ~name:"bookmark_id" ()] "id" ~ty:Type.int;
       field "age" ~ty:Type.int;
       field "url" ~ty:Type.text;
     ]
     ~migrations:[v_1_2_0, [
       Caqti_request.Infix.(Caqti_type.unit ->. Caqti_type.unit)
         {sql|ALTER TABLE person ADD COLUMN age INTEGER DEFAULT 1000|sql}
     ]]

This and more is explained in the documentation, along with a nifty quick-starter guide: index (petrol.index)

I’ve spent some time tuning the documentation to make it easy to pick up!

You may also want to check out the tests to see it in action: petrol/test at master · Gopiandcode/petrol · GitHub

Previous discussion: [ANN] Petrol 1.0.0 - A high-level typed SQL API for OCaml designed to go fast!

22 Likes

Hello, this sounds nice,

Any plan to add type safety for foreign key ? Can not be 100% safe, but the only runtime error should be when
save a row id, remove the row, use the row id in some table, which should violate a foreign row constraint.

1 Like

Are there any plans for async support (as opposed to lwt)?

Thanks!

Ah, good idea – I think that should be fairly straightforward to add for column constraints – it would just be a matter of extending the foreign table constraint [`Column] constraint to also include a parameter indicating the type of column it applies to — if something like [`Column of 'a] constraint would work, there wouldn’t even need to be a need to split it from the table constraints.

I think for table constraints (i.e constraints over more than one column), then it might not be possible without adding overly verbose boilerplate.

Yes, that is planned for future releases. The lwt integration is not that integral to the internals of the project — it should be straightforward to swap to Async.

1 Like