This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
141
unikernel/duniverse/pgx/pgx_async/bin/pgx_async_example.ml
Normal file
141
unikernel/duniverse/pgx/pgx_async/bin/pgx_async_example.ml
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
(* A basic example of Pgx_async usage *)
|
||||
open Core_kernel
|
||||
open Async_kernel
|
||||
open Async_unix
|
||||
|
||||
module Employee = struct
|
||||
let create db =
|
||||
Pgx_async.simple_query
|
||||
db
|
||||
{|
|
||||
CREATE TEMPORARY TABLE Employee (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL UNIQUE);
|
||||
|}
|
||||
|> Deferred.ignore_m
|
||||
;;
|
||||
|
||||
(* This function lets us insert multiple users relatively efficiently *)
|
||||
let insert_many db names =
|
||||
let params = List.map names ~f:(fun name -> Pgx_async.Value.[ of_string name ]) in
|
||||
Pgx_async.execute_many
|
||||
db
|
||||
~params
|
||||
~query:
|
||||
{|
|
||||
INSERT INTO Employee (name)
|
||||
VALUES ($1)
|
||||
RETURNING id
|
||||
|}
|
||||
>>| List.map ~f:(function
|
||||
| [ [ id ] ] -> Pgx.Value.to_int_exn id
|
||||
| _ -> assert false)
|
||||
;;
|
||||
|
||||
let insert ~name db = insert_many db [ name ] >>| List.hd_exn
|
||||
end
|
||||
|
||||
module Facility = struct
|
||||
let create db =
|
||||
Pgx_async.simple_query
|
||||
db
|
||||
{|
|
||||
CREATE TEMPORARY TABLE Facility (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL UNIQUE,
|
||||
director_id INT REFERENCES Employee(id) ON DELETE SET NULL);
|
||||
|
||||
CREATE INDEX facility_director_id ON Facility (director_id);
|
||||
|}
|
||||
|> Deferred.ignore_m
|
||||
;;
|
||||
|
||||
let insert ~name ?director_id db =
|
||||
let params = Pgx_async.Value.[ of_string name; opt of_int director_id ] in
|
||||
Pgx_async.execute
|
||||
db
|
||||
~params
|
||||
{|
|
||||
INSERT INTO Facility (name, director_id)
|
||||
VALUES ($1, $2)
|
||||
RETURNING id
|
||||
|}
|
||||
>>| function
|
||||
| [ [ id ] ] -> Pgx.Value.to_int_exn id
|
||||
| _ -> assert false
|
||||
;;
|
||||
|
||||
let all_name_and_director_name db =
|
||||
Pgx_async.execute
|
||||
db
|
||||
{|
|
||||
SELECT f.name, e.name
|
||||
FROM Facility f
|
||||
LEFT JOIN Employee e ON e.id = f.director_id
|
||||
|}
|
||||
>>| List.map ~f:(function
|
||||
| [ name; director_name ] ->
|
||||
Pgx.Value.(to_string_exn name, to_string director_name)
|
||||
| _ -> assert false)
|
||||
;;
|
||||
|
||||
let reassign_director db ~director_id ~from_facility_id ~to_facility_id =
|
||||
(* Note: with_transaction doesn't currently have any special handling
|
||||
for concurrent queries *)
|
||||
Pgx_async.with_transaction db
|
||||
@@ fun db ->
|
||||
let params = Pgx.Value.[ of_int director_id; of_int from_facility_id ] in
|
||||
Pgx_async.execute
|
||||
db
|
||||
~params
|
||||
{|
|
||||
UPDATE Facility SET director_id = NULL WHERE id = $2 AND director_id = $1
|
||||
|}
|
||||
>>= fun _ ->
|
||||
let params = Pgx.Value.[ of_int director_id; of_int to_facility_id ] in
|
||||
Pgx_async.execute
|
||||
db
|
||||
~params
|
||||
{|
|
||||
UPDATE Facility SET director_id = $1 WHERE id = $2
|
||||
|}
|
||||
|> Deferred.ignore_m
|
||||
;;
|
||||
end
|
||||
|
||||
let setup db = Employee.create db >>= fun () -> Facility.create db
|
||||
|
||||
let main () =
|
||||
Pgx_async.with_conn
|
||||
@@ fun db ->
|
||||
setup db
|
||||
>>= fun () ->
|
||||
Employee.insert ~name:"Steve" db
|
||||
>>= fun steve_id ->
|
||||
(* Parallel queries are not an error, but will execute in serial *)
|
||||
[ Facility.insert ~name:"Headquarters" ~director_id:steve_id db
|
||||
; Facility.insert ~name:"New Office" db
|
||||
]
|
||||
|> Deferred.all
|
||||
>>= function
|
||||
| [ headquarters_id; new_office_id ] ->
|
||||
Facility.all_name_and_director_name db
|
||||
>>| List.iter ~f:(fun (name, director_name) ->
|
||||
let director_name = Option.value director_name ~default:"(none)" in
|
||||
printf "The director of %s is %s\n" name director_name)
|
||||
>>= fun () ->
|
||||
print_endline "Re-assigning Steve to the New Office";
|
||||
Facility.reassign_director
|
||||
db
|
||||
~director_id:steve_id
|
||||
~from_facility_id:headquarters_id
|
||||
~to_facility_id:new_office_id
|
||||
>>= fun () ->
|
||||
Facility.all_name_and_director_name db
|
||||
>>| List.iter ~f:(fun (name, director_name) ->
|
||||
let director_name = Option.value director_name ~default:"(none)" in
|
||||
printf "The director of %s is %s\n" name director_name)
|
||||
| _ -> assert false
|
||||
;;
|
||||
|
||||
let () = Thread_safe.block_on_async_exn main
|
||||
Loading…
Add table
Add a link
Reference in a new issue