PG’OCaml is a type-safe macro binding to PostgreSQL from OCaml that I wrote many moons ago.
You can write code like:
let hostid = 33 in let name = "john.smith" in let rows = PGSQL(dbh) "select id, subject from contacts where hostid = $hostid and name = $name"
and the compiler checks (at compile time) that hostid
and name
have the correct types in the program to match the database schema. And it’ll ensure that the type of rows
is something like (int * string) list
, and integrate that with type inference in the rest of the program.
The program won’t compile if you use the wrong types. It integrates OCaml’s type safety and type inference with the PostgreSQL database engine.
It also avoids SQL injection by automatically creating a safe prepared statement. What is executed when the program runs will have: ... where hostid = ? and name = ?
.
As a side-effect of the type checking, it also verifies that the SQL code is syntactically correct.
How hard is it to make it work with any other DB engine?
Infeasible I’d say.
How does the compiler know what the PG schema is? How do you know the schema won’t change at run time?
It asks the database (at compile time) using PostgreSQL’s DESCRIBE command. This does require an active database connection at compile time, which means you need to engineer your dev environment for that. We did this at my former company and it wasn’t too much trouble.
If the schema changes at runtime then you will get a runtime error, so it’s still safe (as in, doesn’t do Bad Stuff), but it’s recommended obviously that you either don’t change the schema, or if you do change the schema you should recompile the program to ensure continued compile-time type safety.
Cool, thanks for explaining.