ocaml-caqti icon indicating copy to clipboard operation
ocaml-caqti copied to clipboard

Support user functions in Sqlite3 driver

Open bcc32 opened this issue 3 years ago • 1 comments

Sqlite supports a notion of "application-defined SQL functions", namely, functions that can be used in SQL expressions but which are implemented by the user of the database driver (in this case, in OCaml). sqlite3-ocaml supports the necessary bindings already.

I understand that this probably wouldn't apply to the other database drivers, and it seems like quite a substantial task to make it work with the rest of the API, but I thought it might be reasonable to open this as a tracking issue. Please close if you disagree.

bcc32 avatar Jan 22 '21 22:01 bcc32

I think a way to support this and some other RDBMS specific features would be to make the underlying connection object available, e.g. using an extensible variant which can be accessed from a constructor defined by the driver module. Code which uses this would need to link against the driver (instead of relying on dynamic loading), but that's probably acceptable in this case.

paurkedal avatar Jan 23 '21 20:01 paurkedal

Sorry for the long wait. The solution isn't ideal, but commit a04466f78e33724f3dc0cbef794a73918102005b provides access to the connection handle for sqlite3. It requires linking against the caqti-driver-sqlite3 library. The test shows how it can be used:

let test_fun (module C : Caqti_blocking.CONNECTION) =
  (match C.driver_connection with
   | Some Caqti_driver_sqlite3.Driver_connection db ->
      Sqlite3.create_fun1 db "trim" begin function
       | TEXT s -> TEXT (String.trim s)
       | x -> x
      end;
      assert (C.find trim_req "  . " = Ok ".")
   | Some _ -> assert false
   | None -> assert false)

paurkedal avatar Sep 06 '22 14:09 paurkedal

Thanks so much! I finally got around to working on the project that needed this and it worked perfectly. I like the new infix Caqti_request interface too; it's very intuitive :)

bcc32 avatar Oct 27 '22 00:10 bcc32