From 77735d02654fc3e00e3a5031507e5b3e20b1ceca Mon Sep 17 00:00:00 2001 From: Christian Ulrich Date: Mon, 27 Apr 2026 00:38:42 +0200 Subject: [PATCH 1/5] fix tests - make tests compile with caqti >= 2.0.0 - fix an sqlite error message - use postgresql's peer authentication method - allow running 'dune test' without the --profile=test flag --- test/dune | 6 ++---- test/postgres_static/dune | 3 +-- test/postgres_static/test-insert-duplicate.t | 2 +- test/postgres_versioned/dune | 4 +--- test/static/dune | 3 +-- test/static/test-insert-duplicate.t | 2 +- test/test_postgres_static.ml | 2 +- test/test_static_person.ml | 2 +- test/test_utils.ml | 8 ++++---- test/versioned/dune | 3 +-- 10 files changed, 14 insertions(+), 21 deletions(-) diff --git a/test/dune b/test/dune index 37daa87..6bcbc51 100644 --- a/test/dune +++ b/test/dune @@ -1,11 +1,9 @@ (executables (names test_static_person test_versioned_bookmark test_postgres_static test_postgres_versioned) (modules (:standard \ "test_utils")) - (enabled_if (= %{profile} test)) - (libraries test_utils petrol caqti caqti-lwt caqti-driver-sqlite3 caqti-driver-postgresql)) + (libraries test_utils petrol caqti caqti-lwt.unix caqti-driver-sqlite3 caqti-driver-postgresql)) (library (name test_utils) (modules "test_utils") - (enabled_if (= %{profile} test)) - (libraries petrol caqti caqti-lwt caqti-driver-sqlite3 caqti-driver-postgresql)) + (libraries petrol caqti caqti-lwt.unix caqti-driver-sqlite3 caqti-driver-postgresql)) diff --git a/test/postgres_static/dune b/test/postgres_static/dune index 5d0f18f..7c4fecd 100644 --- a/test/postgres_static/dune +++ b/test/postgres_static/dune @@ -1,2 +1 @@ -(cram (deps ../test_postgres_static.exe) - (enabled_if (= %{profile} test))) +(cram (deps ../test_postgres_static.exe)) diff --git a/test/postgres_static/test-insert-duplicate.t b/test/postgres_static/test-insert-duplicate.t index 4f9c971..b58a1c7 100644 --- a/test/postgres_static/test-insert-duplicate.t +++ b/test/postgres_static/test-insert-duplicate.t @@ -6,7 +6,7 @@ $ ../test_postgres_static.exe testing_insert_duplicate add bob 20 $ ../test_postgres_static.exe testing_insert_duplicate add harry 10 $ ../test_postgres_static.exe testing_insert_duplicate add harry 10 - Fatal error: exception Request to failed: ERROR: duplicate key value violates unique constraint "unique_names" + Fatal error: exception Request to failed: ERROR: duplicate key value violates unique constraint "unique_names" DETAIL: Key (name)=(harry) already exists. Query: "INSERT INTO person (name, age) VALUES ($1, $2)". [2] diff --git a/test/postgres_versioned/dune b/test/postgres_versioned/dune index 5399341..624527c 100644 --- a/test/postgres_versioned/dune +++ b/test/postgres_versioned/dune @@ -1,3 +1 @@ -(cram - (deps ../test_postgres_versioned.exe) - (enabled_if (= %{profile} test))) +(cram (deps ../test_postgres_versioned.exe)) diff --git a/test/static/dune b/test/static/dune index 98bc068..4f105fd 100644 --- a/test/static/dune +++ b/test/static/dune @@ -1,2 +1 @@ -(cram (deps ../test_static_person.exe) - (enabled_if (= %{profile} test))) +(cram (deps ../test_static_person.exe)) diff --git a/test/static/test-insert-duplicate.t b/test/static/test-insert-duplicate.t index 832089d..d16903c 100644 --- a/test/static/test-insert-duplicate.t +++ b/test/static/test-insert-duplicate.t @@ -10,5 +10,5 @@ $ ../test_static_person.exe add test.db harry 10 - id: 5 $ ../test_static_person.exe add test.db harry 10 - Fatal error: exception Response from failed: UNIQUE constraint failed: person.name. Query: "INSERT INTO person (name, age) VALUES (?1, ?2)\nRETURNING person.id". + Fatal error: exception Request to failed: UNIQUE constraint failed: person.name (ERC#2067). Query: "INSERT INTO person (name, age) VALUES (?1, ?2)\nRETURNING person.id". [2] diff --git a/test/test_postgres_static.ml b/test/test_postgres_static.ml index 2165c70..5b443fa 100644 --- a/test/test_postgres_static.ml +++ b/test/test_postgres_static.ml @@ -117,7 +117,7 @@ let () = Lwt.return_ok () | "insert-random" :: _ -> let fname = Sys.argv.(2) in - let* conn = Caqti_lwt.connect (Uri.of_string ("sqlite3://:" ^ fname)) in + let* conn = Caqti_lwt_unix.connect (Uri.of_string ("sqlite3://:" ^ fname)) in let* _ = Petrol.StaticSchema.initialise db conn in let person = Person.random () in let* _ = Person.Sql.insert person conn in diff --git a/test/test_static_person.ml b/test/test_static_person.ml index 85c7aa5..368c352 100644 --- a/test/test_static_person.ml +++ b/test/test_static_person.ml @@ -116,7 +116,7 @@ let () = Lwt.return_ok () | "insert-random", _ -> let fname = Sys.argv.(2) in - let* conn = Caqti_lwt.connect (Uri.of_string ("sqlite3://:" ^ fname)) in + let* conn = Caqti_lwt_unix.connect (Uri.of_string ("sqlite3://:" ^ fname)) in let* _ = Petrol.StaticSchema.initialise db conn in let person = Person.random () in let* (pid, ()) = Person.Sql.insert person conn in diff --git a/test/test_utils.ml b/test/test_utils.ml index e460056..87303ff 100644 --- a/test/test_utils.ml +++ b/test/test_utils.ml @@ -16,7 +16,7 @@ let main f = let open Lwt_result.Syntax in let fname = Sys.argv.(2) in run begin - let* conn = Caqti_lwt.connect (Uri.of_string ("sqlite3://:" ^ fname)) in + let* conn = Caqti_lwt_unix.connect (Uri.of_string ("sqlite3://:" ^ fname)) in let args = List.init (Array.length Sys.argv - 3) (fun ind -> Sys.argv.(3 + ind)) in match f conn (Sys.argv.(1), args) with | computation -> @@ -30,17 +30,17 @@ let main_postgres f = let args = List.init (Array.length Sys.argv - 1) (fun ind -> Sys.argv.(1 + ind)) in match[@warning "-8"] args with | ["createdb"; name] -> - let* (module DB) = Caqti_lwt.connect (Uri.of_string "postgresql://localhost:5432") in + let* (module DB) = Caqti_lwt_unix.connect (Uri.of_string "postgresql://") in Lwt.bind (DB.exec (Caqti_request.Infix.(Caqti_type.unit ->. Caqti_type.unit) (Format.sprintf {sql| CREATE DATABASE %s |sql} name)) ()) @@ fun err -> Lwt.bind (DB.disconnect ()) @@ fun () -> Lwt.return err | ["dropdb"; name] -> - let* (module DB) = Caqti_lwt.connect (Uri.of_string "postgresql://localhost:5432") in + let* (module DB) = Caqti_lwt_unix.connect (Uri.of_string "postgresql://") in Lwt.bind (DB.exec (Caqti_request.Infix.(Caqti_type.unit ->. Caqti_type.unit) (Format.sprintf {sql| DROP DATABASE IF EXISTS %s WITH (FORCE) |sql} name)) ()) @@ fun err -> Lwt.bind (DB.disconnect ()) @@ fun () -> Lwt.return err | name :: args -> - let* ((module DB) as conn) = Caqti_lwt.connect (Uri.of_string (Format.sprintf "postgresql://localhost:5432/%s" name)) in + let* ((module DB) as conn) = Caqti_lwt_unix.connect (Uri.of_string (Format.sprintf "postgresql:///%s" name)) in try Lwt.bind begin match f conn args with | computation -> computation diff --git a/test/versioned/dune b/test/versioned/dune index 1c1355e..843a89f 100644 --- a/test/versioned/dune +++ b/test/versioned/dune @@ -1,3 +1,2 @@ (cram - (deps ../test_versioned_bookmark.exe) - (enabled_if (= %{profile} test))) + (deps ../test_versioned_bookmark.exe)) From b5854b9b6e6700c3650d14caa61d4f80ff68ef6d Mon Sep 17 00:00:00 2001 From: Christian Ulrich Date: Wed, 22 Apr 2026 22:05:35 +0200 Subject: [PATCH 2/5] Revert "aliases for inner joins?" This reverts commit cbb7453e89805b3ad1e3d68eea55a5ed412bd54c. --- lib/types.ml | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/types.ml b/lib/types.ml index 34d7e61..435c4cf 100644 --- a/lib/types.ml +++ b/lib/types.ml @@ -271,25 +271,18 @@ and pp_query: 'a 'b. Format.formatter -> (pp_opt pp_on_conflict) on_conflict pp_returning returning ) -and pp_join : int -> Format.formatter -> join -> unit = - fun n fmt (MkJoin { table; on; join_op }) -> - Format.fprintf fmt "%a (%a) AS join_tmp_%d ON %a" +and pp_join : Format.formatter -> join -> unit = + fun fmt (MkJoin { table; on; join_op }) -> + Format.fprintf fmt "%a (%a) ON %a" pp_join_op join_op - pp_query table n + pp_query table pp_expr on and pp_join_list : Format.formatter -> join list -> unit = fun fmt ls -> match ls with | [] -> () | h :: t -> - Format.fprintf fmt " %a%a" (pp_join 0) h (pp_join_list_inner 1) t -and pp_join_list_inner : int -> Format.formatter -> join list -> unit = - fun n fmt ls -> - match ls with - | [] -> () - | h :: t -> - Format.fprintf fmt " %a%a" (pp_join n) h (pp_join_list_inner (n + 1)) t - + Format.fprintf fmt " %a%a" pp_join h pp_join_list t and pp_wrapped_assign: Format.formatter -> wrapped_assign -> unit = fun fmt (ASSIGN ((_, field_name, _), expr)) -> Format.fprintf fmt "%s = %a" field_name pp_expr expr From 9133a266000b990f32576ad1c30c58a30b352319 Mon Sep 17 00:00:00 2001 From: Christian Ulrich Date: Wed, 13 May 2026 12:22:35 +0200 Subject: [PATCH 3/5] allow passing subquery aliases or tables to join and select - add Query.as_ - replace table_name with table_ref in the public API - join and select accept a [< `TABLE | `SUBQUERY] table_ref - all other functions require a [`TABLE] table_ref --- lib/expr.ml | 4 +-- lib/petrol.ml | 22 ++++++------ lib/petrol.mli | 40 ++++++++++++++------- lib/query.ml | 33 +++++++++++++---- lib/schema.ml | 16 +++++---- lib/types.ml | 96 +++++++++++++++++++++++++++++++------------------- 6 files changed, 136 insertions(+), 75 deletions(-) diff --git a/lib/expr.ml b/lib/expr.ml index 14aae93..72f1584 100644 --- a/lib/expr.ml +++ b/lib/expr.ml @@ -53,8 +53,8 @@ module Common = struct let unset l = match l with - | Types.FIELD (tbl, fld, ty) -> - Types.ASSIGN ((tbl, fld, (null ty)), Types.NULL (null ty)) + | Types.FIELD ({ty; _} as f) -> + Types.ASSIGN ({f with ty = (null ty)}, Types.NULL (null ty)) | _ -> invalid_arg "LHS of an unset must be a field" let (+) l r = Types.Common.ADD (Type.Numeric.Int, l, r) diff --git a/lib/petrol.ml b/lib/petrol.ml index e05bace..b012d15 100644 --- a/lib/petrol.ml +++ b/lib/petrol.ml @@ -9,7 +9,7 @@ module Type = struct end -type table_name = Types.table_name +type 'kind table_ref = 'kind Types.table_ref type ('ret_ty, 'query_kind) query = ('ret_ty, 'query_kind) Types.query @@ -143,10 +143,10 @@ module StaticSchema = struct match table with | [] -> [] | (field_name, field_ty, _) :: rest -> - ((Types.FIELD ((id, name), field_name,field_ty)) : _ Expr.t) + (Types.FIELD {table_name = name; name = field_name; ty = field_ty}) :: to_table name rest in let table = to_table name tbl in - (id, name), table + Types.TABLE name, table let initialise tables (module DB: Caqti_lwt.CONNECTION) = let open Lwt_result.Syntax in @@ -182,7 +182,7 @@ module VersionedSchema = struct tables: (int, wrapped_table) Hashtbl.t; migrations: (version * migration list) list; version_db: StaticSchema.t; - version_table_name: table_name; + version_table: [ `TABLE ] table_ref; version_table_field: string Expr.t; } @@ -198,7 +198,7 @@ module VersionedSchema = struct let init ?(migrations=[]) version ~name = let migrations = order_by_version migrations in let version_db = StaticSchema.init () in - let version_table_name, Expr.[version_table_field] = + let version_table, Expr.[version_table_field] = StaticSchema.declare_table version_db ~name:("petrol_" ^ name ^ "_version_db") Schema.[ field ~constraints:[primary_key (); not_null ()] "version" ~ty:Type.TEXT ] in @@ -207,7 +207,7 @@ module VersionedSchema = struct tables=Hashtbl.create 10; migrations; version_db; - version_table_name; version_table_field; + version_table; version_table_field; } let declare_table t ?since ?(constraints : _ list =[]) ?(migrations=[]) ~name tbl = @@ -220,10 +220,10 @@ module VersionedSchema = struct match table with | [] -> [] | (field_name, field_ty, _) :: rest -> - ((Types.FIELD ((id, name), field_name,field_ty)) : _ Expr.t) + (Types.FIELD {table_name = name; name = field_name; ty = field_ty}) :: to_table name rest in let table = to_table name tbl in - (id, name), table + Types.TABLE name, table let set_version t version con = let open Lwt_result.Syntax in @@ -231,11 +231,11 @@ module VersionedSchema = struct let version_str = String.concat "." (List.map Int.to_string version) in let (module DB: Caqti_lwt.CONNECTION) = con in let* () = - Query.delete ~from:t.version_table_name + Query.delete ~from:t.version_table |> Request.make_zero |> exec con in let* () = - Query.insert ~table:t.version_table_name + Query.insert ~table:t.version_table ~values:Expr.Common.[t.version_table_field := s version_str] |> Request.make_zero |> exec con in @@ -245,7 +245,7 @@ module VersionedSchema = struct let open Lwt_result.Syntax in let* () = StaticSchema.initialise t.version_db con in let* res = - Query.select Expr.[t.version_table_field] ~from:t.version_table_name + Query.select Expr.[t.version_table_field] ~from:t.version_table |> Request.make_zero_or_one |> find_opt con in match res with diff --git a/lib/petrol.mli b/lib/petrol.mli index 511945c..8c45a3c 100644 --- a/lib/petrol.mli +++ b/lib/petrol.mli @@ -1,5 +1,9 @@ -type table_name -(** Uniquely identifies a table in the system. *) +type 'kind table_ref +(** Uniquely identifies a table or a subquery in the system. + + - a [[` TABLE ] table_ref] references a physical table. + - a [[` SUBQUERY ] table_ref] references an aliased subquery (see + {!Query.as_}). *) module Expr : sig @@ -871,7 +875,7 @@ module Schema : sig ?name:string -> ?on_update:foreign_conflict_clause -> ?on_delete:foreign_conflict_clause -> - table:table_name -> + table:([ `TABLE ] table_ref) -> columns:'a Expr.expr_list -> unit -> [ `Column ] constraint_ (** [foreign_key ?name ?on_update ?on_delete ~table ~columns ()] returns a new SQL column constraint that specifies that the @@ -888,7 +892,7 @@ module Schema : sig ?name:string -> ?on_update:foreign_conflict_clause -> ?on_delete:foreign_conflict_clause -> - table:table_name -> + table:([ `TABLE ] table_ref) -> columns:'a Expr.expr_list -> string list -> [ `Table ] constraint_ (** [table_foreign_key ?name ?on_update ?on_delete ~table ~columns cols] returns a new SQL table constraint that specifies that the @@ -940,8 +944,8 @@ module Query : sig type ('a, 'b, 'd, 'c) join_fun = ?op:join_op -> - on:bool Expr.t -> ('b, 'd) t -> ('c, 'a) t -> ('c, 'a) t - constraint 'a = [< `SELECT_CORE ] constraint 'd = [< `SELECT_CORE | `SELECT ] + on:bool Expr.t -> 'd table_ref -> ('c, 'a) t -> ('c, 'a) t + constraint 'a = [< `SELECT_CORE ] constraint 'd = [< `TABLE | `SUBQUERY ] (** [('a,'b,'c,'d) join_fun] defines the type of an SQL function that corresponds to SQL's JOIN clause. *) @@ -960,19 +964,19 @@ module Query : sig that corresponds to SQL's ON CONFLICT clause. *) val select : - 'a Expr.expr_list -> from:table_name -> ('a, [> `SELECT_CORE ]) t + 'a Expr.expr_list -> from:([< `TABLE | `SUBQUERY ] table_ref) -> ('a, [> `SELECT_CORE ]) t (** [select fields ~from] corresponds to the SQL [SELECT {fields} FROM {from}]. *) val update : - table:table_name -> set:Expr.wrapped_assign list -> (unit, [> `UPDATE ]) t + table:([ `TABLE ] table_ref) -> set:Expr.wrapped_assign list -> (unit, [> `UPDATE ]) t (** [update ~table ~set] corresponds to the SQL [UPDATE {set} FROM {table}]. *) val insert : - table:table_name -> + table:([ `TABLE ] table_ref) -> values:Expr.wrapped_assign list -> (unit, [> `INSERT ]) t (** [insert ~table ~values] corresponds to the SQL [INSERT {values} INTO {table}]. *) - val delete : from:table_name -> (unit, [> `DELETE ]) t + val delete : from:[ `TABLE ] table_ref -> (unit, [> `DELETE ]) t (** [delete ~from] corresponds to the SQL [DELETE FROM {from}]. *) val where : @@ -985,7 +989,7 @@ module Query : sig val having : ([< `SELECT | `SELECT_CORE ], 'c) having_fun (** [having fields expr] corresponds to the SQL [{expr} HAVING {fields}]. *) - val join : ([ `SELECT_CORE ], 'b, [< `SELECT_CORE | `SELECT ], 'c) join_fun + val join : ([ `SELECT_CORE ], 'b, [< `TABLE | `SUBQUERY ], 'c) join_fun (** [join ?op ~on oexpr expr] corresponds to the SQL [{expr} {op} JOIN {oexpr} ON {expr}]. The ordering of the last two arguments has been chosen to allow @@ -1027,6 +1031,16 @@ module Query : sig PostgreSQL since version 8.2 (2006-12-05), and by SQLite since version 3.35.0 (2021-03-12). *) + val as_ : + name:string -> + ('a, [< `SELECT | `SELECT_CORE]) t -> + [ `SUBQUERY ] table_ref * 'a Expr.expr_list + (** [as_ ~name expr] corresponds to the SQL [{expr} AS {name}] where + [expr] must be a select query. + + This function returns a table name and an expression list which can be + used in other select queries or join clauses. *) + end module StaticSchema : sig @@ -1052,7 +1066,7 @@ module StaticSchema : sig val declare_table : t -> ?constraints:[`Table] Schema.constraint_ list -> - name:string -> 'a Schema.table -> table_name * 'a Expr.expr_list + name:string -> 'a Schema.table -> [ `TABLE ] table_ref * 'a Expr.expr_list (** [declare_table t ?constraints ~name table_spec] declares a new table on the schema [t] with the name [name]. @@ -1112,7 +1126,7 @@ module VersionedSchema : sig ?since:version -> ?constraints:[`Table] Schema.constraint_ list -> ?migrations:(version * migration list) list -> - name:string -> 'a Schema.table -> table_name * 'a Expr.expr_list + name:string -> 'a Schema.table -> [ `TABLE ] table_ref * 'a Expr.expr_list (** [declare_table t ?since ?constraints ?migrations ~name table_spec] declares a new table on the schema [t] with the name [name]. diff --git a/lib/query.ml b/lib/query.ml index d8acd8c..3187b93 100644 --- a/lib/query.ml +++ b/lib/query.ml @@ -19,7 +19,7 @@ type ('a,'c) having_fun = type ('a,'b,'d,'c) join_fun = ?op:Types.join_op -> on:bool Expr.t -> - ('b, [< `SELECT_CORE | `SELECT ] as 'd) t + ([< `TABLE | `SUBQUERY ] as 'd) Types.table_ref -> ('c, 'a) t -> ('c, 'a) t constraint 'a = ([< `SELECT_CORE]) as 'a @@ -35,7 +35,6 @@ type ('a,'b,'c) on_conflict_fun = -> ('c, 'a) t constraint 'a = ([> `INSERT]) as 'a - let query_values query = List.rev (Types.query_values [] query) let pp = Types.pp_query @@ -110,8 +109,7 @@ let having : ('a,'c) having_fun = | Types.INSERT _ -> invalid_arg "group by only supported on select clause" let join : ('a,'b,'d,'c) join_fun = - fun ?(op=INNER) ~on (type a b c) (ot: (b, _) t) - (table : (c, a) t) -> + fun ?(op=INNER) ~on (type a c) (ot: _ Types.table_ref) (table : (c, a) t) -> match table with | Types.SELECT_CORE { exprs; table; join; where; group_by; having } -> Types.SELECT_CORE { @@ -127,7 +125,7 @@ let join : ('a,'b,'d,'c) join_fun = | Types.DELETE _ | Types.UPDATE _ | Types.INSERT _ -> - invalid_arg "group by only supported on select clause" + invalid_arg "join only supported on select clause" let on_err : 'a . [`ABORT | `FAIL | `IGNORE | `REPLACE | `ROLLBACK ] -> ('c, 'a) t -> ('c, 'a) t = fun on_err (type a) (table : (_, a) t) : (_, a) t -> @@ -216,4 +214,27 @@ let returning : | Types.DELETE query -> DELETE { query with returning } | UPDATE query -> UPDATE { query with returning } | INSERT query -> INSERT { query with returning } - | SELECT_CORE _ | SELECT _ -> invalid_arg "returning not supported for select" \ No newline at end of file + | SELECT_CORE _ | SELECT _ -> invalid_arg "returning not supported for select" + +let as_ : + 'a 'b. + name:string -> + ('a, [< `SELECT | `SELECT_CORE ] as 'b) t -> + [ `SUBQUERY ] Types.table_ref * 'a Expr.expr_list = + fun (type a b) ~name (query : (a, b) t) : ([ `SUBQUERY ] Types.table_ref * a Expr.expr_list) -> + let rec update_fields : 'c. 'c Types.expr_list -> 'c Types.expr_list = + fun (type c) (exprs : c Types.expr_list) : c Types.expr_list -> + let open Types in + match exprs with + | [] -> [] + | FIELD field :: exprs -> + FIELD {field with table_name = name} :: update_fields exprs + | e :: exprs -> e :: update_fields exprs + in + let exprs = + match query with + | SELECT_CORE {exprs; _} -> exprs + | SELECT {core = SELECT_CORE core; _} -> core.exprs + | UPDATE _ | INSERT _ | DELETE _ -> invalid_arg "as_ only supported for select" + in + Types.SUBQUERY (name, query), (update_fields exprs) diff --git a/lib/schema.ml b/lib/schema.ml index 73d0312..876edf8 100644 --- a/lib/schema.ml +++ b/lib/schema.ml @@ -1,4 +1,4 @@ -type table_name = Types.table_name +type table_name = int * string type conflict_clause = [`ROLLBACK | `ABORT | `FAIL | `IGNORE | `REPLACE] type foreign_conflict_clause = [`SET_NULL | `SET_DEFAULT | `CASCADE | `RESTRICT | `NO_ACTION ] @@ -23,7 +23,7 @@ type 'a sql_constraint = | ForeignKey of { local_columns: string list option; name: string option; - table: Types.table_name; + table: [ `TABLE ] Types.table_ref; columns: string list; on_update: foreign_conflict_clause option; on_delete: foreign_conflict_clause option; @@ -116,7 +116,7 @@ let pp_sql_constraint fmt = function (pp_parens pp_column_list) vl)) local_columns (if Option.is_some name || Option.is_some local_columns then " " else "") - (snd table) + (Types.table_name table) (pp_parens pp_column_list) columns (pp_opt (fun fmt vl -> Format.fprintf fmt "ON UPDATE %a" @@ -215,11 +215,11 @@ let table_unique ?name ?on_conflict columns : [`Table] sql_constraint = on_conflict; } -let rec expr_list_to_column_names : 'a . Types.table_name -> 'a Expr.expr_list -> string list = +let rec expr_list_to_column_names : 'a . string -> 'a Expr.expr_list -> string list = fun (type a) table_name (ls: a Types.expr_list) : string list -> match ls with | [] -> [] - | Types.FIELD (table_name', name, _) :: t -> + | Types.FIELD {table_name = table_name'; name; _} :: t -> if not (table_name = table_name') then invalid_arg "foreign key constraint uses fields from a \ different table than the one specified"; @@ -229,21 +229,23 @@ let rec expr_list_to_column_names : 'a . Types.table_name -> 'a Expr.expr_list - directly not derived expressions" let foreign_key ?name ?on_update ?on_delete ~table ~columns () : [`Column] sql_constraint = + let table_name = Types.table_name table in ForeignKey { local_columns=None; name; table; - columns=expr_list_to_column_names table columns; + columns=expr_list_to_column_names table_name columns; on_update; on_delete; } let table_foreign_key ?name ?on_update ?on_delete ~table ~columns local_columns : [`Table] sql_constraint = + let table_name = Types.table_name table in ForeignKey { local_columns=Some local_columns; name; table; - columns=expr_list_to_column_names table columns; + columns=expr_list_to_column_names table_name columns; on_update; on_delete; } diff --git a/lib/types.ml b/lib/types.ml index 435c4cf..b1b43be 100644 --- a/lib/types.ml +++ b/lib/types.ml @@ -1,5 +1,3 @@ -type table_name = int * string - type comparison = EQ | NEQ | GT | GE | LT | LE @@ -30,23 +28,31 @@ let pp_opt f fmt = function | None -> () | Some vl -> Format.fprintf fmt "\n%a" f vl -type 'a field = table_name * string * 'a Type.t +type 'a field = { + table_name : string; + name : string; + ty : 'a Type.t +} + +type 'kind table_ref = + | TABLE : string -> [`TABLE] table_ref + | SUBQUERY : string * ('a, 'b) query -> [`SUBQUERY] table_ref -type 'a expr_list = +and 'a expr_list = | [] : unit expr_list | (::) : ('a expr * 'b expr_list) -> ('a * 'b) expr_list and 'a expr = .. and wrapped_assign = ASSIGN : 'a field * 'a expr -> wrapped_assign and (_, !'res) query = - | SELECT_CORE : { - exprs: 'a expr_list; - table: table_name; - join: join list; - where: bool expr option; - group_by: 'b expr_list option; - having: bool expr option; - } -> ('a, [> `SELECT_CORE]) query + | SELECT_CORE : { + exprs: 'a expr_list; + table: [< `TABLE | `SUBQUERY] table_ref; + join: join list; + where: bool expr option; + group_by: 'b expr_list option; + having: bool expr option; + } -> ('a, [> `SELECT_CORE]) query | SELECT : { core: ('a, [< `SELECT_CORE ]) query; order_by: ([`ASC | `DESC] * 'e expr_list) option; @@ -54,19 +60,19 @@ and (_, !'res) query = offset: int expr option } -> ('a, [> `SELECT]) query | DELETE : { - table: table_name; + table: [`TABLE] table_ref; where: bool expr option; returning: 'a expr_list; } -> ('a, [> `DELETE]) query | UPDATE : { - table: table_name; + table: [`TABLE] table_ref; on_err: [`ABORT | `FAIL | `IGNORE | `REPLACE | `ROLLBACK ] option; set: wrapped_assign list; where: bool expr option; returning : 'a expr_list; } -> ('a, [> `UPDATE]) query | INSERT : { - table: table_name; + table: [`TABLE] table_ref; on_err: [`ABORT | `FAIL | `IGNORE | `REPLACE | `ROLLBACK ] option; on_conflict: [`DO_NOTHING] option; set: wrapped_assign list; @@ -74,11 +80,17 @@ and (_, !'res) query = } -> ('a, [> `INSERT]) query and join = MkJoin: { - table: ('r, [< `SELECT_CORE | `SELECT ]) query; + table: [< `TABLE | `SUBQUERY ] table_ref; on: bool expr; join_op: join_op; } -> join +let table_name: 'a. 'a table_ref -> string = + fun (type a) (table_ref: a table_ref) : string -> + match table_ref with + | TABLE n -> n + | SUBQUERY (n, _) -> n + let pp_opt_expr_list (type a) f fmt : a expr_list -> unit = function | [] -> () | ls -> Format.fprintf fmt "\n%a" f ls @@ -136,9 +148,8 @@ let () = add_printer @@ fun pp -> { | NULL _ -> Format.fprintf fmt "NULL" | CONST (_, _) -> Format.fprintf fmt "?" | CONST_STATIC (vl, ty) -> Type.pp_value ty fmt vl - | FIELD (table_name, field_name, _) -> - let table_name = snd table_name in - Format.fprintf fmt "%s.%s" table_name field_name + | FIELD {table_name; name; _} -> + Format.fprintf fmt "%s.%s" table_name name | COERCETO (expr, _) -> pp_expr fmt expr | REF (name,_) -> Format.fprintf fmt "%s" name | AS (expr, name) -> Format.fprintf fmt "%a AS %s" pp_expr expr name @@ -164,7 +175,7 @@ let () = add_typer @@ fun typer -> { | NULL ty -> ty | CONST (_, ty) -> ty | CONST_STATIC (_, ty) -> ty - | FIELD (_, _, ty) -> ty + | FIELD {ty; _} -> ty | COERCETO (_, ty) -> ty | REF (_, ty) -> ty | AS (expr, _) -> ty_expr expr @@ -207,9 +218,9 @@ and pp_query: 'a 'b. Format.formatter -> (match query with | SELECT_CORE { exprs; table; join; where; group_by; having } -> Format.fprintf fmt - "SELECT %a\nFROM %s%a%a%a%a" + "SELECT %a\nFROM %a%a%a%a%a" pp_expr_list exprs - (snd table) + pp_table_ref table pp_join_list join (pp_opt (fun fmt vl -> Format.fprintf fmt "WHERE %a" pp_expr vl)) @@ -236,8 +247,8 @@ and pp_query: 'a 'b. Format.formatter -> Format.fprintf fmt "OFFSET %a" pp_expr vl)) offset | DELETE { table; where; returning } -> - Format.fprintf fmt "DELETE FROM %s%a%a" - (snd table) + Format.fprintf fmt "DELETE FROM %a%a%a" + pp_table_ref table (pp_opt (fun fmt vl -> Format.fprintf fmt "WHERE %a" pp_expr vl @@ -245,9 +256,9 @@ and pp_query: 'a 'b. Format.formatter -> where pp_returning returning | UPDATE { table; on_err; set; where; returning } -> - Format.fprintf fmt "UPDATE%a %s\nSET %a%a%a" + Format.fprintf fmt "UPDATE%a %a\nSET %a%a%a" (pp_opt pp_on_err) on_err - (snd table) + pp_table_ref table (Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt ", ") pp_wrapped_assign) set (pp_opt (fun fmt vl -> Format.fprintf fmt "WHERE %a" pp_expr vl)) @@ -257,11 +268,11 @@ and pp_query: 'a 'b. Format.formatter -> let pp_field : 'a . Format.formatter -> 'a expr -> unit = fun fmt (type a) (expr: a expr) : unit -> match expr with - | FIELD (_, field, _) -> Format.fprintf fmt "%s" field + | FIELD {name; _} -> Format.fprintf fmt "%s" name | _ -> Format.kasprintf failwith "expected field for INSERT query, got %a" pp_expr expr in - Format.fprintf fmt "INSERT%a INTO %s (%a) VALUES (%a)%a%a" + Format.fprintf fmt "INSERT%a INTO %a (%a) VALUES (%a)%a%a" (pp_opt pp_on_err) on_err - (snd table) + pp_table_ref table (Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt ", ") (fun fmt (ASSIGN (fld, _)) -> Format.fprintf fmt "%a" pp_field (FIELD fld))) set @@ -273,9 +284,9 @@ and pp_query: 'a 'b. Format.formatter -> ) and pp_join : Format.formatter -> join -> unit = fun fmt (MkJoin { table; on; join_op }) -> - Format.fprintf fmt "%a (%a) ON %a" + Format.fprintf fmt "%a %a ON %a" pp_join_op join_op - pp_query table + pp_table_ref table pp_expr on and pp_join_list : Format.formatter -> join list -> unit = fun fmt ls -> @@ -284,8 +295,16 @@ and pp_join_list : Format.formatter -> join list -> unit = | h :: t -> Format.fprintf fmt " %a%a" pp_join h pp_join_list t and pp_wrapped_assign: Format.formatter -> wrapped_assign -> unit = - fun fmt (ASSIGN ((_, field_name, _), expr)) -> - Format.fprintf fmt "%s = %a" field_name pp_expr expr + fun fmt (ASSIGN ({name; _}, expr)) -> + Format.fprintf fmt "%s = %a" name pp_expr expr + +and pp_table_ref: 'a. Format.formatter -> 'a table_ref -> unit = + fun (type a) fmt (table : a table_ref) -> + match table with + | TABLE name -> + Format.fprintf fmt "%s" name + | SUBQUERY (name, query) -> + Format.fprintf fmt "(\n%a) AS %s" pp_query query name let rec values_expr_list : 'a . wrapped_value list -> 'a expr_list -> wrapped_value list = @@ -299,9 +318,14 @@ and query_values : 'a 'b. wrapped_value list -> ('a,'b) query -> wrapped_value l | SELECT_CORE { exprs; table=_; join; where; group_by; having } -> let acc = values_expr_list acc exprs in let acc = List.fold_left (fun acc (MkJoin {table; on; join_op=_}) -> - let acc = query_values acc table in - let acc = values_expr acc on in - acc + match table with + | TABLE _ -> + let acc = values_expr acc on in + acc + | SUBQUERY (_, subquery) -> + let acc = query_values acc subquery in + let acc = values_expr acc on in + acc ) acc join in let acc = Option.map (values_expr acc) where |> Option.value ~default:acc in let acc = Option.map (values_expr_list acc) group_by |> Option.value ~default:acc in From 34815a37baec1e7c61d24703364d4eb7f6174824 Mon Sep 17 00:00:00 2001 From: Christian Ulrich Date: Thu, 14 May 2026 13:12:36 +0200 Subject: [PATCH 4/5] add tests for joining with tables and subqueries --- test/dune | 32 +++-- test/postgres_static/dune | 3 +- test/postgres_static/test-join.t | 23 ++++ test/static/dune | 3 +- test/static/test-join.t | 23 ++++ test/test_postgres_static_pet.ml | 193 +++++++++++++++++++++++++++++++ test/test_static_pet.ml | 193 +++++++++++++++++++++++++++++++ 7 files changed, 461 insertions(+), 9 deletions(-) create mode 100644 test/postgres_static/test-join.t create mode 100644 test/static/test-join.t create mode 100644 test/test_postgres_static_pet.ml create mode 100644 test/test_static_pet.ml diff --git a/test/dune b/test/dune index 6bcbc51..6025cac 100644 --- a/test/dune +++ b/test/dune @@ -1,9 +1,27 @@ -(executables (names test_static_person test_versioned_bookmark test_postgres_static test_postgres_versioned) - (modules (:standard \ "test_utils")) - (libraries test_utils petrol caqti caqti-lwt.unix caqti-driver-sqlite3 caqti-driver-postgresql)) +(executables + (names + test_static_person + test_static_pet + test_versioned_bookmark + test_postgres_static + test_postgres_static_pet + test_postgres_versioned) + (modules + (:standard \ "test_utils")) + (libraries + test_utils + petrol + caqti + caqti-lwt.unix + caqti-driver-sqlite3 + caqti-driver-postgresql)) -(library (name test_utils) +(library + (name test_utils) (modules "test_utils") - (libraries petrol caqti caqti-lwt.unix caqti-driver-sqlite3 caqti-driver-postgresql)) - - + (libraries + petrol + caqti + caqti-lwt.unix + caqti-driver-sqlite3 + caqti-driver-postgresql)) diff --git a/test/postgres_static/dune b/test/postgres_static/dune index 7c4fecd..9dd7286 100644 --- a/test/postgres_static/dune +++ b/test/postgres_static/dune @@ -1 +1,2 @@ -(cram (deps ../test_postgres_static.exe)) +(cram + (deps ../test_postgres_static.exe ../test_postgres_static_pet.exe)) diff --git a/test/postgres_static/test-join.t b/test/postgres_static/test-join.t new file mode 100644 index 0000000..3ea0333 --- /dev/null +++ b/test/postgres_static/test-join.t @@ -0,0 +1,23 @@ + $ ../test_postgres_static_pet.exe init test.db + $ ../test_postgres_static_pet.exe add-dog test.db Pluto 8 sausage + - id: 1 + $ ../test_postgres_static_pet.exe add-dog test.db Bella 2 cake + - id: 2 + $ ../test_postgres_static_pet.exe add-dog test.db Gandalf 15 hamburger + - id: 3 + $ ../test_postgres_static_pet.exe add-cat test.db Garfield 8 18 + - id: 4 + $ ../test_postgres_static_pet.exe add-cat test.db Elvis 16 20 + - id: 5 + $ ../test_postgres_static_pet.exe add-cat test.db Grumbles 4 17 + - id: 6 + $ ../test_postgres_static_pet.exe get-all test.db + [0] - name: Pluto; age: 8; favourite_food: sausage + [1] - name: Bella; age: 2; favourite_food: cake + [2] - name: Gandalf; age: 15; favourite_food: hamburger + [3] - name: Garfield; age: 8; sleeping_hours: 18 + [4] - name: Elvis; age: 16; sleeping_hours: 20 + [5] - name: Grumbles; age: 4; sleeping_hours: 17 + $ ../test_postgres_static_pet.exe get-older-than test.db 10 + [0] - name: Gandalf; age: 15; favourite_food: hamburger + [1] - name: Elvis; age: 16; sleeping_hours: 20 diff --git a/test/static/dune b/test/static/dune index 4f105fd..09672e4 100644 --- a/test/static/dune +++ b/test/static/dune @@ -1 +1,2 @@ -(cram (deps ../test_static_person.exe)) +(cram + (deps ../test_static_person.exe ../test_static_pet.exe)) diff --git a/test/static/test-join.t b/test/static/test-join.t new file mode 100644 index 0000000..cd40723 --- /dev/null +++ b/test/static/test-join.t @@ -0,0 +1,23 @@ + $ ../test_static_pet.exe init test.db + $ ../test_static_pet.exe add-dog test.db Pluto 8 sausage + - id: 1 + $ ../test_static_pet.exe add-dog test.db Bella 2 cake + - id: 2 + $ ../test_static_pet.exe add-dog test.db Gandalf 15 hamburger + - id: 3 + $ ../test_static_pet.exe add-cat test.db Garfield 8 18 + - id: 4 + $ ../test_static_pet.exe add-cat test.db Elvis 16 20 + - id: 5 + $ ../test_static_pet.exe add-cat test.db Grumbles 4 17 + - id: 6 + $ ../test_static_pet.exe get-all test.db + [0] - name: Pluto; age: 8; favourite_food: sausage + [1] - name: Bella; age: 2; favourite_food: cake + [2] - name: Gandalf; age: 15; favourite_food: hamburger + [3] - name: Garfield; age: 8; sleeping_hours: 18 + [4] - name: Elvis; age: 16; sleeping_hours: 20 + [5] - name: Grumbles; age: 4; sleeping_hours: 17 + $ ../test_static_pet.exe get-older-than test.db 10 + [0] - name: Gandalf; age: 15; favourite_food: hamburger + [1] - name: Elvis; age: 16; sleeping_hours: 20 diff --git a/test/test_postgres_static_pet.ml b/test/test_postgres_static_pet.ml new file mode 100644 index 0000000..1c60c96 --- /dev/null +++ b/test/test_postgres_static_pet.ml @@ -0,0 +1,193 @@ +[@@@warning "-27-26"] +open Lwt_result.Syntax + +let db = Petrol.StaticSchema.init () + +type pet = + | Dog of { name: string; age: int; favourite_food: string } + | Cat of { name: string; age: int; sleeping_hours: int } + +module Pet = struct + open Petrol + open Petrol.Postgres + let t, Expr.[ id; name; age ] = + StaticSchema.declare_table db ~name:"pet" + Schema.[ + field ~constraints:[primary_key ~auto_increment:true ()] "id" ~ty:Type.int; + field "name" ~ty:Type.text; + field "age" ~ty:Type.int; + ] + + module Dog = struct + let t, Expr.[ id; favourite_food ] = + StaticSchema.declare_table db ~name:"dog" + Schema.[ + field + "id" + ~ty:Type.int + ~constraints: + [ primary_key (); foreign_key ~table:t ~columns:[ id ] () ]; + field "favourite_food" ~ty:Type.text + ] + end + + module Cat = struct + let t, Expr.[ id; sleeping_hours ] = + StaticSchema.declare_table db ~name:"cat" + Schema.[ + field + "id" + ~ty:Type.int + ~constraints: + [ primary_key (); foreign_key ~table:t ~columns:[ id ] () ]; + field "sleeping_hours" ~ty:Type.int + ] + + end + + let insert (p: pet) db = + match p with + | Dog dog -> + let* (id, ()) = + Query.insert ~table:t ~values:Expr.[ name := s dog.name; age := i dog.age ] + |> Query.returning Expr.[ id ] + |> Request.make_one + |> Petrol.find db + in + let* () = + Query.insert + ~table:Dog.t + ~values: + Expr.[ Dog.id := i id; Dog.favourite_food := s dog.favourite_food ] + |> Request.make_zero + |> Petrol.exec db + in + Lwt_result.return id + | Cat cat -> + let* (id, ()) = + Query.insert ~table:t ~values:Expr.[ name := s cat.name; age := i cat.age ] + |> Query.returning Expr.[ id ] + |> Request.make_one + |> Petrol.find db + in + let* () = Query.insert + ~table:Cat.t + ~values: + Expr.[ Cat.id := i id; Cat.sleeping_hours := i cat.sleeping_hours ] + |> Request.make_zero + |> Petrol.exec db + in + Lwt_result.return id + + let get_all db = + (* join with "pet" table *) + let* dogs = + Query.select ~from:Dog.t Expr.[ name; age; Dog.favourite_food ] + |> Query.join t ~on:Expr.(id = Dog.id) + |> Request.make_many + |> Petrol.collect_list db + |> Lwt_result.map + (List.map (fun (name, (age, (favourite_food, ()))) -> + Dog { name; age; favourite_food })) + in + let* cats = + Query.select ~from:Cat.t Expr.[ name; age; Cat.sleeping_hours ] + |> Query.join t ~on:Expr.(id = Cat.id) + |> Request.make_many + |> Petrol.collect_list db + |> Lwt_result.map + (List.map (fun (name, (age, (sleeping_hours, ()))) -> + Cat { name; age; sleeping_hours })) + in + Lwt_result.return (dogs @ cats) + + let get_older_than db age_ = + (* join with subquery named "old_pets" *) + let old_pets, Expr.[ old_pet_id; old_pet_name; old_pet_age ] = + Query.select ~from:t Expr.[ id; name; age ] + |> Query.where Expr.(age > i age_) + |> Query.as_ ~name:"old_pets" + in + let* old_dogs = + Query.select ~from:Dog.t Expr.[ old_pet_name; old_pet_age; Dog.favourite_food ] + |> Query.join old_pets ~on:Expr.(old_pet_id = Dog.id) + |> Request.make_many + |> Petrol.collect_list db + |> Lwt_result.map + (List.map (fun (name, (age, (favourite_food, ()))) -> + Dog { name; age; favourite_food })) + in + let* old_cats = + Query.select ~from:Cat.t Expr.[ old_pet_name; old_pet_age; Cat.sleeping_hours ] + |> Query.join old_pets ~on:Expr.(old_pet_id = Cat.id) + |> Request.make_many + |> Petrol.collect_list db + |> Lwt_result.map + (List.map (fun (name, (age, (sleeping_hours, ()))) -> + Cat { name; age; sleeping_hours })) + in + Lwt_result.return (old_dogs @ old_cats) +end + +let print_pets pets = + List.iteri + (fun i pet -> + match pet with + | Dog {name; age; favourite_food} -> + Printf.printf + "[%i] - name: %s; age: %i; favourite_food: %s\n" + i + name + age + favourite_food; + | Cat {name; age; sleeping_hours} -> + Printf.printf + "[%i] - name: %s; age: %i; sleeping_hours: %i\n" + i + name + age + sleeping_hours;) + pets + +let () = + Test_utils.main begin fun conn -> function[@warning "-8"] + | "init", _ -> + let* _ = Petrol.StaticSchema.initialise db conn in + Lwt.return_ok () + | "add-dog", [ name; age; favourite_food ] -> + let dog = + Dog { + name; + age = int_of_string age; + favourite_food + } + in + let* _ = Petrol.StaticSchema.initialise db conn in + let* id = Pet.insert dog conn in + print_endline ("- id: " ^ string_of_int id); + Lwt.return_ok () + | "add-cat", [ name; age; sleeping_hours ] -> + let cat = + Cat { + name; + age = int_of_string age; + sleeping_hours = int_of_string sleeping_hours + } + in + let* _ = Petrol.StaticSchema.initialise db conn in + let* id = Pet.insert cat conn in + Printf.printf "- id: %i\n" id; + Lwt.return_ok () + | "get-all", _ -> + let* _ = Petrol.StaticSchema.initialise db conn in + let* pets = Pet.get_all conn in + print_pets pets; + Lwt.return_ok () + | "get-older-than", [ age ] -> + let* _ = Petrol.StaticSchema.initialise db conn in + let* pets = Pet.get_older_than conn (int_of_string age) in + print_pets pets; + Lwt.return_ok () + end + + diff --git a/test/test_static_pet.ml b/test/test_static_pet.ml new file mode 100644 index 0000000..36a6635 --- /dev/null +++ b/test/test_static_pet.ml @@ -0,0 +1,193 @@ +[@@@warning "-27-26"] +open Lwt_result.Syntax + +let db = Petrol.StaticSchema.init () + +type pet = + | Dog of { name: string; age: int; favourite_food: string } + | Cat of { name: string; age: int; sleeping_hours: int } + +module Pet = struct + open Petrol + open Petrol.Sqlite3 + let t, Expr.[ id; name; age ] = + StaticSchema.declare_table db ~name:"pet" + Schema.[ + field ~constraints:[primary_key ~auto_increment:true ()] "id" ~ty:Type.int; + field "name" ~ty:Type.text; + field "age" ~ty:Type.int; + ] + + module Dog = struct + let t, Expr.[ id; favourite_food ] = + StaticSchema.declare_table db ~name:"dog" + Schema.[ + field + "id" + ~ty:Type.int + ~constraints: + [ primary_key (); foreign_key ~table:t ~columns:[ id ] () ]; + field "favourite_food" ~ty:Type.text + ] + end + + module Cat = struct + let t, Expr.[ id; sleeping_hours ] = + StaticSchema.declare_table db ~name:"cat" + Schema.[ + field + "id" + ~ty:Type.int + ~constraints: + [ primary_key (); foreign_key ~table:t ~columns:[ id ] () ]; + field "sleeping_hours" ~ty:Type.int + ] + + end + + let insert (p: pet) db = + match p with + | Dog dog -> + let* (id, ()) = + Query.insert ~table:t ~values:Expr.[ name := s dog.name; age := i dog.age ] + |> Query.returning Expr.[ id ] + |> Request.make_one + |> Petrol.find db + in + let* () = + Query.insert + ~table:Dog.t + ~values: + Expr.[ Dog.id := i id; Dog.favourite_food := s dog.favourite_food ] + |> Request.make_zero + |> Petrol.exec db + in + Lwt_result.return id + | Cat cat -> + let* (id, ()) = + Query.insert ~table:t ~values:Expr.[ name := s cat.name; age := i cat.age ] + |> Query.returning Expr.[ id ] + |> Request.make_one + |> Petrol.find db + in + let* () = Query.insert + ~table:Cat.t + ~values: + Expr.[ Cat.id := i id; Cat.sleeping_hours := i cat.sleeping_hours ] + |> Request.make_zero + |> Petrol.exec db + in + Lwt_result.return id + + let get_all db = + (* join with "pet" table *) + let* dogs = + Query.select ~from:Dog.t Expr.[ name; age; Dog.favourite_food ] + |> Query.join t ~on:Expr.(id = Dog.id) + |> Request.make_many + |> Petrol.collect_list db + |> Lwt_result.map + (List.map (fun (name, (age, (favourite_food, ()))) -> + Dog { name; age; favourite_food })) + in + let* cats = + Query.select ~from:Cat.t Expr.[ name; age; Cat.sleeping_hours ] + |> Query.join t ~on:Expr.(id = Cat.id) + |> Request.make_many + |> Petrol.collect_list db + |> Lwt_result.map + (List.map (fun (name, (age, (sleeping_hours, ()))) -> + Cat { name; age; sleeping_hours })) + in + Lwt_result.return (dogs @ cats) + + let get_older_than db age_ = + (* join with subquery named "old_pets" *) + let old_pets, Expr.[ old_pet_id; old_pet_name; old_pet_age ] = + Query.select ~from:t Expr.[ id; name; age ] + |> Query.where Expr.(age > i age_) + |> Query.as_ ~name:"old_pets" + in + let* old_dogs = + Query.select ~from:Dog.t Expr.[ old_pet_name; old_pet_age; Dog.favourite_food ] + |> Query.join old_pets ~on:Expr.(old_pet_id = Dog.id) + |> Request.make_many + |> Petrol.collect_list db + |> Lwt_result.map + (List.map (fun (name, (age, (favourite_food, ()))) -> + Dog { name; age; favourite_food })) + in + let* old_cats = + Query.select ~from:Cat.t Expr.[ old_pet_name; old_pet_age; Cat.sleeping_hours ] + |> Query.join old_pets ~on:Expr.(old_pet_id = Cat.id) + |> Request.make_many + |> Petrol.collect_list db + |> Lwt_result.map + (List.map (fun (name, (age, (sleeping_hours, ()))) -> + Cat { name; age; sleeping_hours })) + in + Lwt_result.return (old_dogs @ old_cats) +end + +let print_pets pets = + List.iteri + (fun i pet -> + match pet with + | Dog {name; age; favourite_food} -> + Printf.printf + "[%i] - name: %s; age: %i; favourite_food: %s\n" + i + name + age + favourite_food; + | Cat {name; age; sleeping_hours} -> + Printf.printf + "[%i] - name: %s; age: %i; sleeping_hours: %i\n" + i + name + age + sleeping_hours;) + pets + +let () = + Test_utils.main begin fun conn -> function[@warning "-8"] + | "init", _ -> + let* _ = Petrol.StaticSchema.initialise db conn in + Lwt.return_ok () + | "add-dog", [ name; age; favourite_food ] -> + let dog = + Dog { + name; + age = int_of_string age; + favourite_food + } + in + let* _ = Petrol.StaticSchema.initialise db conn in + let* id = Pet.insert dog conn in + print_endline ("- id: " ^ string_of_int id); + Lwt.return_ok () + | "add-cat", [ name; age; sleeping_hours ] -> + let cat = + Cat { + name; + age = int_of_string age; + sleeping_hours = int_of_string sleeping_hours + } + in + let* _ = Petrol.StaticSchema.initialise db conn in + let* id = Pet.insert cat conn in + Printf.printf "- id: %i\n" id; + Lwt.return_ok () + | "get-all", _ -> + let* _ = Petrol.StaticSchema.initialise db conn in + let* pets = Pet.get_all conn in + print_pets pets; + Lwt.return_ok () + | "get-older-than", [ age ] -> + let* _ = Petrol.StaticSchema.initialise db conn in + let* pets = Pet.get_older_than conn (int_of_string age) in + print_pets pets; + Lwt.return_ok () + end + + From 60341fae6bdf98cea32f5d8493ab3ed799b9e86e Mon Sep 17 00:00:00 2001 From: Christian Ulrich Date: Thu, 14 May 2026 13:28:50 +0200 Subject: [PATCH 5/5] name test binaries more consistently --- test/dune | 4 ++-- test/postgres_static/dune | 2 +- test/postgres_static/test-delete-multiple.t | 24 +++++++++---------- test/postgres_static/test-delete.t | 20 ++++++++-------- test/postgres_static/test-find-missing.t | 18 +++++++------- test/postgres_static/test-find-older-than.t | 18 +++++++------- test/postgres_static/test-init.t | 6 ++--- test/postgres_static/test-insert-duplicate.t | 18 +++++++------- test/postgres_static/test-insert-multiple.t | 18 +++++++------- test/postgres_static/test-insert.t | 10 ++++---- test/postgres_static/test-update.t | 20 ++++++++-------- test/postgres_versioned/dune | 3 ++- test/postgres_versioned/test-add-tag-v2.t | 12 +++++----- test/postgres_versioned/test-clear-tags.v2.t | 18 +++++++------- test/postgres_versioned/test-init.t | 6 ++--- .../test-insert-multiple-v1.t | 16 ++++++------- .../postgres_versioned/test-insert-v1-extra.t | 10 ++++---- .../test-insert-v1.2-extra.t | 10 ++++---- test/postgres_versioned/test-insert-v1.2.t | 10 ++++---- test/postgres_versioned/test-insert-v1.t | 10 ++++---- test/postgres_versioned/test-insert-v2.t | 10 ++++---- .../test-migrate-and-use-v1-v1.2.t | 18 +++++++------- .../test-migrate-and-use-v1-v2.t | 16 ++++++------- .../postgres_versioned/test-migrate-v1-v1.2.t | 16 ++++++------- test/postgres_versioned/test-migrate-v1-v2.t | 16 ++++++------- .../test-newer-version-v2-v1.t | 16 ++++++------- ...atic.ml => test_postgres_static_person.ml} | 0 ...ml => test_postgres_versioned_bookmark.ml} | 0 28 files changed, 173 insertions(+), 172 deletions(-) rename test/{test_postgres_static.ml => test_postgres_static_person.ml} (100%) rename test/{test_postgres_versioned.ml => test_postgres_versioned_bookmark.ml} (100%) diff --git a/test/dune b/test/dune index 6025cac..86faf41 100644 --- a/test/dune +++ b/test/dune @@ -3,9 +3,9 @@ test_static_person test_static_pet test_versioned_bookmark - test_postgres_static + test_postgres_static_person test_postgres_static_pet - test_postgres_versioned) + test_postgres_versioned_bookmark) (modules (:standard \ "test_utils")) (libraries diff --git a/test/postgres_static/dune b/test/postgres_static/dune index 9dd7286..2ff081b 100644 --- a/test/postgres_static/dune +++ b/test/postgres_static/dune @@ -1,2 +1,2 @@ (cram - (deps ../test_postgres_static.exe ../test_postgres_static_pet.exe)) + (deps ../test_postgres_static_person.exe ../test_postgres_static_pet.exe)) diff --git a/test/postgres_static/test-delete-multiple.t b/test/postgres_static/test-delete-multiple.t index ceb7063..0e60d97 100644 --- a/test/postgres_static/test-delete-multiple.t +++ b/test/postgres_static/test-delete-multiple.t @@ -1,14 +1,14 @@ - $ ../test_postgres_static.exe createdb testing_delete_multiple - $ ../test_postgres_static.exe testing_delete_multiple init - $ ../test_postgres_static.exe testing_delete_multiple add john 30 - $ ../test_postgres_static.exe testing_delete_multiple add sally 15 - $ ../test_postgres_static.exe testing_delete_multiple add barry 14 - $ ../test_postgres_static.exe testing_delete_multiple add bob 20 - $ ../test_postgres_static.exe testing_delete_multiple add harry 10 - $ ../test_postgres_static.exe testing_delete_multiple delete sally - $ ../test_postgres_static.exe testing_delete_multiple delete barry - $ ../test_postgres_static.exe testing_delete_multiple delete bob - $ ../test_postgres_static.exe testing_delete_multiple list + $ ../test_postgres_static_person.exe createdb testing_delete_multiple + $ ../test_postgres_static_person.exe testing_delete_multiple init + $ ../test_postgres_static_person.exe testing_delete_multiple add john 30 + $ ../test_postgres_static_person.exe testing_delete_multiple add sally 15 + $ ../test_postgres_static_person.exe testing_delete_multiple add barry 14 + $ ../test_postgres_static_person.exe testing_delete_multiple add bob 20 + $ ../test_postgres_static_person.exe testing_delete_multiple add harry 10 + $ ../test_postgres_static_person.exe testing_delete_multiple delete sally + $ ../test_postgres_static_person.exe testing_delete_multiple delete barry + $ ../test_postgres_static_person.exe testing_delete_multiple delete bob + $ ../test_postgres_static_person.exe testing_delete_multiple list [0] - name: john; age: 30 [1] - name: harry; age: 10 - $ ../test_postgres_static.exe dropdb testing_delete_multiple + $ ../test_postgres_static_person.exe dropdb testing_delete_multiple diff --git a/test/postgres_static/test-delete.t b/test/postgres_static/test-delete.t index 6c1dc59..1cf9692 100644 --- a/test/postgres_static/test-delete.t +++ b/test/postgres_static/test-delete.t @@ -1,14 +1,14 @@ - $ ../test_postgres_static.exe createdb testing_delete - $ ../test_postgres_static.exe testing_delete init - $ ../test_postgres_static.exe testing_delete add john 30 - $ ../test_postgres_static.exe testing_delete add sally 15 - $ ../test_postgres_static.exe testing_delete add barry 14 - $ ../test_postgres_static.exe testing_delete add bob 20 - $ ../test_postgres_static.exe testing_delete add harry 10 - $ ../test_postgres_static.exe testing_delete delete sally - $ ../test_postgres_static.exe testing_delete list + $ ../test_postgres_static_person.exe createdb testing_delete + $ ../test_postgres_static_person.exe testing_delete init + $ ../test_postgres_static_person.exe testing_delete add john 30 + $ ../test_postgres_static_person.exe testing_delete add sally 15 + $ ../test_postgres_static_person.exe testing_delete add barry 14 + $ ../test_postgres_static_person.exe testing_delete add bob 20 + $ ../test_postgres_static_person.exe testing_delete add harry 10 + $ ../test_postgres_static_person.exe testing_delete delete sally + $ ../test_postgres_static_person.exe testing_delete list [0] - name: john; age: 30 [1] - name: barry; age: 14 [2] - name: bob; age: 20 [3] - name: harry; age: 10 - $ ../test_postgres_static.exe dropdb testing_delete + $ ../test_postgres_static_person.exe dropdb testing_delete diff --git a/test/postgres_static/test-find-missing.t b/test/postgres_static/test-find-missing.t index 5461f8f..c828772 100644 --- a/test/postgres_static/test-find-missing.t +++ b/test/postgres_static/test-find-missing.t @@ -1,10 +1,10 @@ - $ ../test_postgres_static.exe createdb testing_find_missing - $ ../test_postgres_static.exe testing_find_missing init - $ ../test_postgres_static.exe testing_find_missing add john 30 - $ ../test_postgres_static.exe testing_find_missing add sally 15 - $ ../test_postgres_static.exe testing_find_missing add barry 14 - $ ../test_postgres_static.exe testing_find_missing add bob 20 - $ ../test_postgres_static.exe testing_find_missing add harry 10 - $ ../test_postgres_static.exe testing_find_missing find-by darren + $ ../test_postgres_static_person.exe createdb testing_find_missing + $ ../test_postgres_static_person.exe testing_find_missing init + $ ../test_postgres_static_person.exe testing_find_missing add john 30 + $ ../test_postgres_static_person.exe testing_find_missing add sally 15 + $ ../test_postgres_static_person.exe testing_find_missing add barry 14 + $ ../test_postgres_static_person.exe testing_find_missing add bob 20 + $ ../test_postgres_static_person.exe testing_find_missing add harry 10 + $ ../test_postgres_static_person.exe testing_find_missing find-by darren not found - $ ../test_postgres_static.exe dropdb testing_find_missing + $ ../test_postgres_static_person.exe dropdb testing_find_missing diff --git a/test/postgres_static/test-find-older-than.t b/test/postgres_static/test-find-older-than.t index a97dc5e..ccf6875 100644 --- a/test/postgres_static/test-find-older-than.t +++ b/test/postgres_static/test-find-older-than.t @@ -1,12 +1,12 @@ - $ ../test_postgres_static.exe createdb testing_find_older_than - $ ../test_postgres_static.exe testing_find_older_than init - $ ../test_postgres_static.exe testing_find_older_than add john 30 - $ ../test_postgres_static.exe testing_find_older_than add sally 9 - $ ../test_postgres_static.exe testing_find_older_than add barry 14 - $ ../test_postgres_static.exe testing_find_older_than add bob 20 - $ ../test_postgres_static.exe testing_find_older_than add harry 10 - $ ../test_postgres_static.exe testing_find_older_than find-older-than 10 + $ ../test_postgres_static_person.exe createdb testing_find_older_than + $ ../test_postgres_static_person.exe testing_find_older_than init + $ ../test_postgres_static_person.exe testing_find_older_than add john 30 + $ ../test_postgres_static_person.exe testing_find_older_than add sally 9 + $ ../test_postgres_static_person.exe testing_find_older_than add barry 14 + $ ../test_postgres_static_person.exe testing_find_older_than add bob 20 + $ ../test_postgres_static_person.exe testing_find_older_than add harry 10 + $ ../test_postgres_static_person.exe testing_find_older_than find-older-than 10 [0] - name: john; age: 30 [1] - name: barry; age: 14 [2] - name: bob; age: 20 - $ ../test_postgres_static.exe dropdb testing_find_older_than + $ ../test_postgres_static_person.exe dropdb testing_find_older_than diff --git a/test/postgres_static/test-init.t b/test/postgres_static/test-init.t index af6bea6..975235d 100644 --- a/test/postgres_static/test-init.t +++ b/test/postgres_static/test-init.t @@ -1,3 +1,3 @@ - $ ../test_postgres_static.exe createdb testing_init - $ ../test_postgres_static.exe testing_init init - $ ../test_postgres_static.exe dropdb testing_init + $ ../test_postgres_static_person.exe createdb testing_init + $ ../test_postgres_static_person.exe testing_init init + $ ../test_postgres_static_person.exe dropdb testing_init diff --git a/test/postgres_static/test-insert-duplicate.t b/test/postgres_static/test-insert-duplicate.t index b58a1c7..9dabf2e 100644 --- a/test/postgres_static/test-insert-duplicate.t +++ b/test/postgres_static/test-insert-duplicate.t @@ -1,13 +1,13 @@ - $ ../test_postgres_static.exe createdb testing_insert_duplicate - $ ../test_postgres_static.exe testing_insert_duplicate init - $ ../test_postgres_static.exe testing_insert_duplicate add john 30 - $ ../test_postgres_static.exe testing_insert_duplicate add sally 15 - $ ../test_postgres_static.exe testing_insert_duplicate add barry 14 - $ ../test_postgres_static.exe testing_insert_duplicate add bob 20 - $ ../test_postgres_static.exe testing_insert_duplicate add harry 10 - $ ../test_postgres_static.exe testing_insert_duplicate add harry 10 + $ ../test_postgres_static_person.exe createdb testing_insert_duplicate + $ ../test_postgres_static_person.exe testing_insert_duplicate init + $ ../test_postgres_static_person.exe testing_insert_duplicate add john 30 + $ ../test_postgres_static_person.exe testing_insert_duplicate add sally 15 + $ ../test_postgres_static_person.exe testing_insert_duplicate add barry 14 + $ ../test_postgres_static_person.exe testing_insert_duplicate add bob 20 + $ ../test_postgres_static_person.exe testing_insert_duplicate add harry 10 + $ ../test_postgres_static_person.exe testing_insert_duplicate add harry 10 Fatal error: exception Request to failed: ERROR: duplicate key value violates unique constraint "unique_names" DETAIL: Key (name)=(harry) already exists. Query: "INSERT INTO person (name, age) VALUES ($1, $2)". [2] - $ ../test_postgres_static.exe dropdb testing_insert_duplicate + $ ../test_postgres_static_person.exe dropdb testing_insert_duplicate diff --git a/test/postgres_static/test-insert-multiple.t b/test/postgres_static/test-insert-multiple.t index 8d8f4e2..76660ed 100644 --- a/test/postgres_static/test-insert-multiple.t +++ b/test/postgres_static/test-insert-multiple.t @@ -1,14 +1,14 @@ - $ ../test_postgres_static.exe createdb testing_insert_multiple - $ ../test_postgres_static.exe testing_insert_multiple init - $ ../test_postgres_static.exe testing_insert_multiple add john 30 - $ ../test_postgres_static.exe testing_insert_multiple add sally 15 - $ ../test_postgres_static.exe testing_insert_multiple add barry 14 - $ ../test_postgres_static.exe testing_insert_multiple add bob 20 - $ ../test_postgres_static.exe testing_insert_multiple add harry 10 - $ ../test_postgres_static.exe testing_insert_multiple list + $ ../test_postgres_static_person.exe createdb testing_insert_multiple + $ ../test_postgres_static_person.exe testing_insert_multiple init + $ ../test_postgres_static_person.exe testing_insert_multiple add john 30 + $ ../test_postgres_static_person.exe testing_insert_multiple add sally 15 + $ ../test_postgres_static_person.exe testing_insert_multiple add barry 14 + $ ../test_postgres_static_person.exe testing_insert_multiple add bob 20 + $ ../test_postgres_static_person.exe testing_insert_multiple add harry 10 + $ ../test_postgres_static_person.exe testing_insert_multiple list [0] - name: john; age: 30 [1] - name: sally; age: 15 [2] - name: barry; age: 14 [3] - name: bob; age: 20 [4] - name: harry; age: 10 - $ ../test_postgres_static.exe dropdb testing_insert_multiple + $ ../test_postgres_static_person.exe dropdb testing_insert_multiple diff --git a/test/postgres_static/test-insert.t b/test/postgres_static/test-insert.t index fe561e1..08ef3cc 100644 --- a/test/postgres_static/test-insert.t +++ b/test/postgres_static/test-insert.t @@ -1,6 +1,6 @@ - $ ../test_postgres_static.exe createdb testing_insert - $ ../test_postgres_static.exe testing_insert init - $ ../test_postgres_static.exe testing_insert add john 30 - $ ../test_postgres_static.exe testing_insert list + $ ../test_postgres_static_person.exe createdb testing_insert + $ ../test_postgres_static_person.exe testing_insert init + $ ../test_postgres_static_person.exe testing_insert add john 30 + $ ../test_postgres_static_person.exe testing_insert list [0] - name: john; age: 30 - $ ../test_postgres_static.exe dropdb testing_insert + $ ../test_postgres_static_person.exe dropdb testing_insert diff --git a/test/postgres_static/test-update.t b/test/postgres_static/test-update.t index c227e6e..16d3406 100644 --- a/test/postgres_static/test-update.t +++ b/test/postgres_static/test-update.t @@ -1,15 +1,15 @@ - $ ../test_postgres_static.exe createdb testing_update - $ ../test_postgres_static.exe testing_update init - $ ../test_postgres_static.exe testing_update add john 30 - $ ../test_postgres_static.exe testing_update add sally 15 - $ ../test_postgres_static.exe testing_update add barry 14 - $ ../test_postgres_static.exe testing_update add bob 20 - $ ../test_postgres_static.exe testing_update add harry 10 - $ ../test_postgres_static.exe testing_update update harry 15 - $ ../test_postgres_static.exe testing_update list + $ ../test_postgres_static_person.exe createdb testing_update + $ ../test_postgres_static_person.exe testing_update init + $ ../test_postgres_static_person.exe testing_update add john 30 + $ ../test_postgres_static_person.exe testing_update add sally 15 + $ ../test_postgres_static_person.exe testing_update add barry 14 + $ ../test_postgres_static_person.exe testing_update add bob 20 + $ ../test_postgres_static_person.exe testing_update add harry 10 + $ ../test_postgres_static_person.exe testing_update update harry 15 + $ ../test_postgres_static_person.exe testing_update list [0] - name: john; age: 30 [1] - name: sally; age: 15 [2] - name: barry; age: 14 [3] - name: bob; age: 20 [4] - name: harry; age: 15 - $ ../test_postgres_static.exe dropdb testing_update + $ ../test_postgres_static_person.exe dropdb testing_update diff --git a/test/postgres_versioned/dune b/test/postgres_versioned/dune index 624527c..250d5ca 100644 --- a/test/postgres_versioned/dune +++ b/test/postgres_versioned/dune @@ -1 +1,2 @@ -(cram (deps ../test_postgres_versioned.exe)) +(cram + (deps ../test_postgres_versioned_bookmark.exe)) diff --git a/test/postgres_versioned/test-add-tag-v2.t b/test/postgres_versioned/test-add-tag-v2.t index 5d71d53..a6f1d00 100644 --- a/test/postgres_versioned/test-add-tag-v2.t +++ b/test/postgres_versioned/test-add-tag-v2.t @@ -1,9 +1,9 @@ - $ ../test_postgres_versioned.exe createdb ver_test_add_tag_v2 - $ ../test_postgres_versioned.exe ver_test_add_tag_v2 v2 init - $ ../test_postgres_versioned.exe ver_test_add_tag_v2 v2 add 0 http://ocaml.org 100 search - $ ../test_postgres_versioned.exe ver_test_add_tag_v2 v2 add-tag 0 john - $ ../test_postgres_versioned.exe ver_test_add_tag_v2 v2 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_add_tag_v2 + $ ../test_postgres_versioned_bookmark.exe ver_test_add_tag_v2 v2 init + $ ../test_postgres_versioned_bookmark.exe ver_test_add_tag_v2 v2 add 0 http://ocaml.org 100 search + $ ../test_postgres_versioned_bookmark.exe ver_test_add_tag_v2 v2 add-tag 0 john + $ ../test_postgres_versioned_bookmark.exe ver_test_add_tag_v2 v2 list [0] - bookmark "search": http://ocaml.org age: 100 tags: john - $ ../test_postgres_versioned.exe dropdb ver_test_add_tag_v2 + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_add_tag_v2 diff --git a/test/postgres_versioned/test-clear-tags.v2.t b/test/postgres_versioned/test-clear-tags.v2.t index 1a29ce8..fb502bc 100644 --- a/test/postgres_versioned/test-clear-tags.v2.t +++ b/test/postgres_versioned/test-clear-tags.v2.t @@ -1,18 +1,18 @@ - $ ../test_postgres_versioned.exe createdb ver_test_clear_tags_v2 - $ ../test_postgres_versioned.exe ver_test_clear_tags_v2 v2 init - $ ../test_postgres_versioned.exe ver_test_clear_tags_v2 v2 add 0 http://ocaml.org 100 search 1000 tag1 tag2 tag3 tag4 - $ ../test_postgres_versioned.exe ver_test_clear_tags_v2 v2 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_clear_tags_v2 + $ ../test_postgres_versioned_bookmark.exe ver_test_clear_tags_v2 v2 init + $ ../test_postgres_versioned_bookmark.exe ver_test_clear_tags_v2 v2 add 0 http://ocaml.org 100 search 1000 tag1 tag2 tag3 tag4 + $ ../test_postgres_versioned_bookmark.exe ver_test_clear_tags_v2 v2 list [0] - bookmark "search": http://ocaml.org age: 100 tags: 1000,tag1,tag2,tag3,tag4 - $ ../test_postgres_versioned.exe ver_test_clear_tags_v2 v2 clear-tags 0 - $ ../test_postgres_versioned.exe ver_test_clear_tags_v2 v2 list + $ ../test_postgres_versioned_bookmark.exe ver_test_clear_tags_v2 v2 clear-tags 0 + $ ../test_postgres_versioned_bookmark.exe ver_test_clear_tags_v2 v2 list [0] - bookmark "search": http://ocaml.org age: 100 tags: - $ ../test_postgres_versioned.exe ver_test_clear_tags_v2 v2 add-tag 0 random - $ ../test_postgres_versioned.exe ver_test_clear_tags_v2 v2 list + $ ../test_postgres_versioned_bookmark.exe ver_test_clear_tags_v2 v2 add-tag 0 random + $ ../test_postgres_versioned_bookmark.exe ver_test_clear_tags_v2 v2 list [0] - bookmark "search": http://ocaml.org age: 100 tags: random - $ ../test_postgres_versioned.exe dropdb ver_test_clear_tags_v2 + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_clear_tags_v2 diff --git a/test/postgres_versioned/test-init.t b/test/postgres_versioned/test-init.t index 2c2b5d1..89991ac 100644 --- a/test/postgres_versioned/test-init.t +++ b/test/postgres_versioned/test-init.t @@ -1,3 +1,3 @@ - $ ../test_postgres_versioned.exe createdb ver_test_init - $ ../test_postgres_versioned.exe ver_test_init v1 init - $ ../test_postgres_versioned.exe dropdb ver_test_init + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_init + $ ../test_postgres_versioned_bookmark.exe ver_test_init v1 init + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_init diff --git a/test/postgres_versioned/test-insert-multiple-v1.t b/test/postgres_versioned/test-insert-multiple-v1.t index bded527..f017252 100644 --- a/test/postgres_versioned/test-insert-multiple-v1.t +++ b/test/postgres_versioned/test-insert-multiple-v1.t @@ -1,10 +1,10 @@ - $ ../test_postgres_versioned.exe createdb ver_test_insert_multiple - $ ../test_postgres_versioned.exe ver_test_insert_multiple v1 init - $ ../test_postgres_versioned.exe ver_test_insert_multiple v1 add 0 http://ocaml.org - $ ../test_postgres_versioned.exe ver_test_insert_multiple v1 add 1 http://discuss.ocaml.org - $ ../test_postgres_versioned.exe ver_test_insert_multiple v1 add 2 http://github.com - $ ../test_postgres_versioned.exe ver_test_insert_multiple v1 add 3 http://fsf.org - $ ../test_postgres_versioned.exe ver_test_insert_multiple v1 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_insert_multiple + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_multiple v1 init + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_multiple v1 add 0 http://ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_multiple v1 add 1 http://discuss.ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_multiple v1 add 2 http://github.com + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_multiple v1 add 3 http://fsf.org + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_multiple v1 list [0] - bookmark "": http://ocaml.org age: -1 tags: @@ -17,4 +17,4 @@ [3] - bookmark "": http://fsf.org age: -1 tags: - $ ../test_postgres_versioned.exe dropdb ver_test_insert_multiple + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_insert_multiple diff --git a/test/postgres_versioned/test-insert-v1-extra.t b/test/postgres_versioned/test-insert-v1-extra.t index 174911b..5b8bb3a 100644 --- a/test/postgres_versioned/test-insert-v1-extra.t +++ b/test/postgres_versioned/test-insert-v1-extra.t @@ -1,8 +1,8 @@ - $ ../test_postgres_versioned.exe createdb ver_test_insert_v1_extra - $ ../test_postgres_versioned.exe ver_test_insert_v1_extra v1 init - $ ../test_postgres_versioned.exe ver_test_insert_v1_extra v1 add 0 http://ocaml.org 10 john tag1 tag2 - $ ../test_postgres_versioned.exe ver_test_insert_v1_extra v1 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_insert_v1_extra + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v1_extra v1 init + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v1_extra v1 add 0 http://ocaml.org 10 john tag1 tag2 + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v1_extra v1 list [0] - bookmark "": http://ocaml.org age: -1 tags: - $ ../test_postgres_versioned.exe dropdb ver_test_insert_v1_extra + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_insert_v1_extra diff --git a/test/postgres_versioned/test-insert-v1.2-extra.t b/test/postgres_versioned/test-insert-v1.2-extra.t index 709de88..1cd8778 100644 --- a/test/postgres_versioned/test-insert-v1.2-extra.t +++ b/test/postgres_versioned/test-insert-v1.2-extra.t @@ -1,8 +1,8 @@ - $ ../test_postgres_versioned.exe createdb ver_test_insert_v12_extra - $ ../test_postgres_versioned.exe ver_test_insert_v12_extra v1.2 init - $ ../test_postgres_versioned.exe ver_test_insert_v12_extra v1.2 add 0 http://ocaml.org 100 john tag1 tag2 - $ ../test_postgres_versioned.exe ver_test_insert_v12_extra v1.2 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_insert_v12_extra + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v12_extra v1.2 init + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v12_extra v1.2 add 0 http://ocaml.org 100 john tag1 tag2 + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v12_extra v1.2 list [0] - bookmark "": http://ocaml.org age: 100 tags: - $ ../test_postgres_versioned.exe dropdb ver_test_insert_v12_extra + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_insert_v12_extra diff --git a/test/postgres_versioned/test-insert-v1.2.t b/test/postgres_versioned/test-insert-v1.2.t index 18f9bea..b66e4a1 100644 --- a/test/postgres_versioned/test-insert-v1.2.t +++ b/test/postgres_versioned/test-insert-v1.2.t @@ -1,8 +1,8 @@ - $ ../test_postgres_versioned.exe createdb ver_test_insert_v12 - $ ../test_postgres_versioned.exe ver_test_insert_v12 v1.2 init - $ ../test_postgres_versioned.exe ver_test_insert_v12 v1.2 add 0 http://ocaml.org 100 - $ ../test_postgres_versioned.exe ver_test_insert_v12 v1.2 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_insert_v12 + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v12 v1.2 init + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v12 v1.2 add 0 http://ocaml.org 100 + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v12 v1.2 list [0] - bookmark "": http://ocaml.org age: 100 tags: - $ ../test_postgres_versioned.exe dropdb ver_test_insert_v12 + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_insert_v12 diff --git a/test/postgres_versioned/test-insert-v1.t b/test/postgres_versioned/test-insert-v1.t index dee3ea3..1b111cb 100644 --- a/test/postgres_versioned/test-insert-v1.t +++ b/test/postgres_versioned/test-insert-v1.t @@ -1,8 +1,8 @@ - $ ../test_postgres_versioned.exe createdb ver_test_insert_v1 - $ ../test_postgres_versioned.exe ver_test_insert_v1 v1 init - $ ../test_postgres_versioned.exe ver_test_insert_v1 v1 add 0 http://ocaml.org - $ ../test_postgres_versioned.exe ver_test_insert_v1 v1 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_insert_v1 + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v1 v1 init + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v1 v1 add 0 http://ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v1 v1 list [0] - bookmark "": http://ocaml.org age: -1 tags: - $ ../test_postgres_versioned.exe dropdb ver_test_insert_v1 + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_insert_v1 diff --git a/test/postgres_versioned/test-insert-v2.t b/test/postgres_versioned/test-insert-v2.t index 80b2146..5727396 100644 --- a/test/postgres_versioned/test-insert-v2.t +++ b/test/postgres_versioned/test-insert-v2.t @@ -1,8 +1,8 @@ - $ ../test_postgres_versioned.exe createdb ver_test_insert_v2 - $ ../test_postgres_versioned.exe ver_test_insert_v2 v2 init - $ ../test_postgres_versioned.exe ver_test_insert_v2 v2 add 0 http://ocaml.org 100 search - $ ../test_postgres_versioned.exe ver_test_insert_v2 v2 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_insert_v2 + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v2 v2 init + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v2 v2 add 0 http://ocaml.org 100 search + $ ../test_postgres_versioned_bookmark.exe ver_test_insert_v2 v2 list [0] - bookmark "search": http://ocaml.org age: 100 tags: - $ ../test_postgres_versioned.exe dropdb ver_test_insert_v2 + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_insert_v2 diff --git a/test/postgres_versioned/test-migrate-and-use-v1-v1.2.t b/test/postgres_versioned/test-migrate-and-use-v1-v1.2.t index eb4b778..279608e 100644 --- a/test/postgres_versioned/test-migrate-and-use-v1-v1.2.t +++ b/test/postgres_versioned/test-migrate-and-use-v1-v1.2.t @@ -1,11 +1,11 @@ - $ ../test_postgres_versioned.exe createdb ver_test_migrate_and_user_v1_v12 - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v12 v1 init - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v12 v1 add 0 http://ocaml.org - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v12 v1 add 1 http://discuss.ocaml.org - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v12 v1 add 2 http://github.com - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v12 v1 add 3 http://fsf.org - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v12 v1.2 add 4 http://fsf.org 1337 - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v12 v1.2 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_migrate_and_user_v1_v12 + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v12 v1 init + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v12 v1 add 0 http://ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v12 v1 add 1 http://discuss.ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v12 v1 add 2 http://github.com + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v12 v1 add 3 http://fsf.org + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v12 v1.2 add 4 http://fsf.org 1337 + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v12 v1.2 list [0] - bookmark "": http://ocaml.org age: 1000 tags: @@ -21,4 +21,4 @@ [4] - bookmark "": http://fsf.org age: 1337 tags: - $ ../test_postgres_versioned.exe dropdb ver_test_migrate_and_user_v1_v12 + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_migrate_and_user_v1_v12 diff --git a/test/postgres_versioned/test-migrate-and-use-v1-v2.t b/test/postgres_versioned/test-migrate-and-use-v1-v2.t index 8a7e6da..3163c3d 100644 --- a/test/postgres_versioned/test-migrate-and-use-v1-v2.t +++ b/test/postgres_versioned/test-migrate-and-use-v1-v2.t @@ -1,10 +1,10 @@ - $ ../test_postgres_versioned.exe createdb ver_test_migrate_and_user_v1_v2 - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v2 v1 init - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v2 v1 add 0 http://ocaml.org - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v2 v1 add 1 http://discuss.ocaml.org - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v2 v1 add 2 http://github.com - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v2 v2 add 3 http://fsf.org 100 example tag1 tag2 tag3 - $ ../test_postgres_versioned.exe ver_test_migrate_and_user_v1_v2 v2 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_migrate_and_user_v1_v2 + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v2 v1 init + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v2 v1 add 0 http://ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v2 v1 add 1 http://discuss.ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v2 v1 add 2 http://github.com + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v2 v2 add 3 http://fsf.org 100 example tag1 tag2 tag3 + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_and_user_v1_v2 v2 list [0] - bookmark "unnamed": http://ocaml.org age: 1000 tags: @@ -17,4 +17,4 @@ [3] - bookmark "example": http://fsf.org age: 100 tags: tag1,tag2,tag3 - $ ../test_postgres_versioned.exe dropdb ver_test_migrate_and_user_v1_v2 + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_migrate_and_user_v1_v2 diff --git a/test/postgres_versioned/test-migrate-v1-v1.2.t b/test/postgres_versioned/test-migrate-v1-v1.2.t index 0fa1c73..c559d3f 100644 --- a/test/postgres_versioned/test-migrate-v1-v1.2.t +++ b/test/postgres_versioned/test-migrate-v1-v1.2.t @@ -1,10 +1,10 @@ - $ ../test_postgres_versioned.exe createdb ver_test_migrate_v1_v12 - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v12 v1 init - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v12 v1 add 0 http://ocaml.org - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v12 v1 add 1 http://discuss.ocaml.org - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v12 v1 add 2 http://github.com - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v12 v1 add 3 http://fsf.org - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v12 v1.2 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_migrate_v1_v12 + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v12 v1 init + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v12 v1 add 0 http://ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v12 v1 add 1 http://discuss.ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v12 v1 add 2 http://github.com + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v12 v1 add 3 http://fsf.org + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v12 v1.2 list [0] - bookmark "": http://ocaml.org age: 1000 tags: @@ -17,4 +17,4 @@ [3] - bookmark "": http://fsf.org age: 1000 tags: - $ ../test_postgres_versioned.exe dropdb ver_test_migrate_v1_v12 + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_migrate_v1_v12 diff --git a/test/postgres_versioned/test-migrate-v1-v2.t b/test/postgres_versioned/test-migrate-v1-v2.t index f2df97b..2dd2bbe 100644 --- a/test/postgres_versioned/test-migrate-v1-v2.t +++ b/test/postgres_versioned/test-migrate-v1-v2.t @@ -1,10 +1,10 @@ - $ ../test_postgres_versioned.exe createdb ver_test_migrate_v1_v2 - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v2 v1 init - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v2 v1 add 0 http://ocaml.org - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v2 v1 add 1 http://discuss.ocaml.org - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v2 v1 add 2 http://github.com - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v2 v1 add 3 http://fsf.org - $ ../test_postgres_versioned.exe ver_test_migrate_v1_v2 v2 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_migrate_v1_v2 + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v2 v1 init + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v2 v1 add 0 http://ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v2 v1 add 1 http://discuss.ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v2 v1 add 2 http://github.com + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v2 v1 add 3 http://fsf.org + $ ../test_postgres_versioned_bookmark.exe ver_test_migrate_v1_v2 v2 list [0] - bookmark "unnamed": http://ocaml.org age: 1000 tags: @@ -18,4 +18,4 @@ age: 1000 tags: - $ ../test_postgres_versioned.exe dropdb ver_test_migrate_v1_v2 + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_migrate_v1_v2 diff --git a/test/postgres_versioned/test-newer-version-v2-v1.t b/test/postgres_versioned/test-newer-version-v2-v1.t index faf6493..e206f4b 100644 --- a/test/postgres_versioned/test-newer-version-v2-v1.t +++ b/test/postgres_versioned/test-newer-version-v2-v1.t @@ -1,11 +1,11 @@ - $ ../test_postgres_versioned.exe createdb ver_test_newer_version_v2_v1 - $ ../test_postgres_versioned.exe ver_test_newer_version_v2_v1 v2 init - $ ../test_postgres_versioned.exe ver_test_newer_version_v2_v1 v2 add 0 http://ocaml.org - $ ../test_postgres_versioned.exe ver_test_newer_version_v2_v1 v2 add 1 http://discuss.ocaml.org - $ ../test_postgres_versioned.exe ver_test_newer_version_v2_v1 v2 add 2 http://github.com - $ ../test_postgres_versioned.exe ver_test_newer_version_v2_v1 v2 add 3 http://fsf.org - $ ../test_postgres_versioned.exe ver_test_newer_version_v2_v1 v1 list + $ ../test_postgres_versioned_bookmark.exe createdb ver_test_newer_version_v2_v1 + $ ../test_postgres_versioned_bookmark.exe ver_test_newer_version_v2_v1 v2 init + $ ../test_postgres_versioned_bookmark.exe ver_test_newer_version_v2_v1 v2 add 0 http://ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_newer_version_v2_v1 v2 add 1 http://discuss.ocaml.org + $ ../test_postgres_versioned_bookmark.exe ver_test_newer_version_v2_v1 v2 add 2 http://github.com + $ ../test_postgres_versioned_bookmark.exe ver_test_newer_version_v2_v1 v2 add 3 http://fsf.org + $ ../test_postgres_versioned_bookmark.exe ver_test_newer_version_v2_v1 v1 list Fatal error: exception Attempted to use a newer database than supported [2] - $ ../test_postgres_versioned.exe dropdb ver_test_newer_version_v2_v1 + $ ../test_postgres_versioned_bookmark.exe dropdb ver_test_newer_version_v2_v1 diff --git a/test/test_postgres_static.ml b/test/test_postgres_static_person.ml similarity index 100% rename from test/test_postgres_static.ml rename to test/test_postgres_static_person.ml diff --git a/test/test_postgres_versioned.ml b/test/test_postgres_versioned_bookmark.ml similarity index 100% rename from test/test_postgres_versioned.ml rename to test/test_postgres_versioned_bookmark.ml