Giter VIP home page Giter VIP logo

petrol's Introduction

Petrol

Petrol is a Free software library that provides a high-level OCaml API for interacting with SQL databases. The aim of this interface is to provide a type-safe API to allow developers to define their SQL tables and queries directly in OCaml, thereby avoiding the impedence mismatch and fragility that comes with having to directly write SQL code, as is typical in a normal Caqti-based project.

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
    ]

Petrol's DSL allows you to express complex SQL queries as simple OCaml function compositions:

open Petrol.Sqlite3

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

See the rest of the documentation at here.

petrol's People

Contributors

bclement-ocp avatar gopiandcode 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  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

petrol's Issues

Complete example?

It would be very helpful to relative newbies to OCaml, such as myself if you had a single complete example of using Petrol. For instance, you have:

(* ... somewhere at the entry point *)
let () =
   let open Lwt_result.Syntax in
   (* ... *)
   let* conn = Caqti_lwt.connect url in
   let* () =
      Petrol.VersionedSchema.initialise
        DB.db conn in
   (* ... *)

I'm not sure what go in the line that is commented after let open Lwt_result.Syntax in or what would go after

Petrol.VersionedSchema.initialise
        DB.db conn in

in order to get a basic working example. To explain more concretely what problem I'm having in my newbie state: if I wanted to use your insert_text function after the line mentioned above, I don't know what argument I would pass to it to represent the db parameter. Would it be conn? DB.db? It would just be nice if it was made completely clear how to create a db variable that could be passed to a function like insert_text.

I realize that if I wasn't a newbie to OCaml I would probably have no issues. But I'd like to use Petrol in the course of my early learning; I'd like to be able to use a sqlite database as a starting point, and play to learn. Also, something very high-level like Petrol (compared to Caqti) seems like it would be especially advantageous to newbies. So it seems like giving newbies something that worked would make a great starting point.

Of course, you may find this training use-case to be outside the scope of what you want to do. That would be completely understandable, and I certainly wouldn't blame you in any way for simply closing this issue with no action. But, on the other hand, it doesn't seem like it would be very difficult to provide an example source file that would be a complete working example that could be run after doing opam install petrol, and it would be helpful to OCaml newbies. So, I didn't think it was completely out of line to mention it as a possibility.

Please take all this as just a friendly suggestion, with no expectations.

I did try cloning the github project and doing dune runtest, but I got all kinds of errors. This is on macos, and you mention issues with run-time loadable extensions that I'm hoping only apply when working with your project source rather than using the packaged library via opam and dune. Although I don't know that.

Thanks for listening to this particular newbie!

sqlite3: `expected BOOLEAN got BOOLEAN`

Inserting a boolean value into an sqlite3 database throws an exception. Removing the boolean field fixes the problem.

Error message

Fatal error: exception Failure("wrapped value list did not conform to specification - expected BOOLEAN got BOOLEAN")

Example program

open Petrol
open Petrol.Sqlite3

let db = StaticSchema.init ()

let todo, Expr.[title; desc; finished] =
  StaticSchema.declare_table db ~name:"todo"
    Schema.
      [ field "title" ~ty:Type.text
      ; field "desc" ~ty:Type.text
      ; field "finished" ~ty:Type.bool ]

let insert_todo ~title:t ~desc:d ~finished:fn db =
  Query.insert ~table:todo
    ~values:Expr.[title := s t; desc := s d; finished := bl fn]
  |> Request.make_zero |> Petrol.exec db

let test_insert =
  let open Lwt_result.Syntax in
  let* conn = Caqti_lwt.connect (Uri.of_string "sqlite3://::memory:") in
  let* _ = Petrol.StaticSchema.initialise db conn in
  insert_todo ~title:"use petrol" ~desc:"it seems amazing" ~finished:true conn

let () =
  match Lwt_main.run test_insert with
  | Ok _ ->
      print_endline "ok"
  | Error err ->
      print_endline (Caqti_error.show err)

Dune

(executable
 (name todo)
 (libraries petrol caqti-driver-sqlite3))

Setup

  • petrol v1.2.0
  • ocaml v5.0.0
  • caqti-driver-sqlite3 v1.9.0
  • sqlite3 v3.31

Consider dual license

Would you consider / be open to dual licensing this project to also be available under a more permissive license like MIT / Apache?

Iโ€™m interested in using it (and contributed the necessary changes for #2, to make it work for my use-case), but having a less restrictive license would make it much easier for me to integrate with my existing projects ๐Ÿ˜…

Isolate Lwt/Async stuff

Hi there, thanks for this project.
I'm personally using Core/Async and Postgres_async, I might try it but in the meantime, is it possible that Lwt specific code be well isolated within its own module?

Update opam package

Hello! I'm incredibly new to OCaml so if anything I've said here is completely wrong I apologize in advance.

I recently started using Petrol and was having trouble with the join alias not being applied in my project, even though it appeared that I was on the latest version (1.2.0 according to opam). I looked through the tags and it appears that there is newer versions (up to 1.2.3?) which do not show up in opam.

So I cloned and built the repo by hand to see if that fixed things and it does. It seems as though the version of Petrol being served by opam is out of date.

You may already know this, so feel free to close this issue if that's the case, I just wanted to bring it to your attention if not.

Example of join

Not sure if it's a bug of me just misunderstanding how to use joins.

Assuming the following tables:

let (person, Expr.[id; name]) = StaticSchema.declare_table schema ~name:"person"
Schema.[field "id" ~ty:Type.int; field "name" ~ty:Type.text];;

let (pet, Expr.[pet_id; pet_name; owner_id]) = StaticSchema.declare_table schema ~name:"pet"
Schema.[field "id" ~ty:Type.int; field "name" ~ty:Type.text; field "owner" ~ty:Type.int];;

Then I'd assume I could write a join query as follow:

Query.select ~from:person Expr.[id; name; pet_name]
|> Query.join ~on:Expr.(id = owner_id) (Query.select ~from:pet Expr.[owner_id; pet_name])
|> Format.asprintf "%a" Query.pp;;

This produces:

SELECT person.id, person.name, pet.name
FROM person INNER JOIN (SELECT pet.owner, pet.name
FROM pet) AS join_tmp_0 ON person.id = pet.owner

So the inner select on the pet table has been aliased to join_tmp_0 but the outer select and the on clause still use the pet prefix.

I assume I misundertood something in the join API, but I could find any relevant example.

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.