From 21065c9f444e4328215ecb03f2572f0e2709ef75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reynir=20Bj=C3=B6rnsson?= Date: Thu, 1 Jul 2021 10:31:32 +0200 Subject: [PATCH] Use initially deferred foreign key constraint On build.main_binary. --- bin/migrations/builder_migrations.ml | 1 + bin/migrations/m20210701.ml | 87 ++++++++++++++++++++++++++++ db/builder_db.ml | 4 +- 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 bin/migrations/m20210701.ml diff --git a/bin/migrations/builder_migrations.ml b/bin/migrations/builder_migrations.ml index 5f86b21..b62c76c 100644 --- a/bin/migrations/builder_migrations.ml +++ b/bin/migrations/builder_migrations.ml @@ -122,5 +122,6 @@ let () = actions (module M20210625); actions (module M20210629); actions (module M20210630); + actions (module M20210701); ]) |> Cmdliner.Term.exit diff --git a/bin/migrations/m20210701.ml b/bin/migrations/m20210701.ml new file mode 100644 index 0000000..6d74db0 --- /dev/null +++ b/bin/migrations/m20210701.ml @@ -0,0 +1,87 @@ +let new_version = 11L and old_version = 10L +let identifier = "2021-07-01" +let migrate_doc = "build.main_binary deferred foreign key constraint" +let rollback_doc = "build.main_binary immediate foreign key constraint" + +let new_build = + Caqti_request.exec + Caqti_type.unit + {| CREATE TABLE new_build ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + uuid VARCHAR(36) NOT NULL UNIQUE, + start_d INTEGER NOT NULL, + start_ps INTEGER NOT NULL, + finish_d INTEGER NOT NULL, + finish_ps INTEGER NOT NULL, + result_kind TINYINT NOT NULL, + result_code INTEGER, + result_msg TEXT, + console BLOB NOT NULL, + script TEXT NOT NULL, + main_binary INTEGER, + user INTEGER NOT NULL, + job INTEGER NOT NULL, + + FOREIGN KEY(main_binary) REFERENCES build_artifact(id) DEFERRABLE INITIALLY DEFERRED, + FOREIGN KEY(user) REFERENCES user(id), + FOREIGN KEY(job) REFERENCES job(id) + ) + |} + +let old_build = + Caqti_request.exec + Caqti_type.unit + {| CREATE TABLE new_build ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + uuid VARCHAR(36) NOT NULL UNIQUE, + start_d INTEGER NOT NULL, + start_ps INTEGER NOT NULL, + finish_d INTEGER NOT NULL, + finish_ps INTEGER NOT NULL, + result_kind TINYINT NOT NULL, + result_code INTEGER, + result_msg TEXT, + console BLOB NOT NULL, + script TEXT NOT NULL, + main_binary INTEGER, + user INTEGER NOT NULL, + job INTEGER NOT NULL, + + FOREIGN KEY(main_binary) REFERENCES build_artifact(id), + FOREIGN KEY(user) REFERENCES user(id), + FOREIGN KEY(job) REFERENCES job(id) + ) + |} + +let copy_build = + Caqti_request.exec + Caqti_type.unit + "INSERT INTO new_build SELECT * from build" + +let drop_build = + Caqti_request.exec + Caqti_type.unit + "DROP TABLE build" + +let rename_build = + Caqti_request.exec + Caqti_type.unit + "ALTER TABLE new_build RENAME TO build" + +open Rresult.R.Infix + +let migrate _datadir (module Db : Caqti_blocking.CONNECTION) = + Grej.check_version ~user_version:old_version (module Db) >>= fun () -> + Db.exec new_build () >>= fun () -> + Db.exec copy_build () >>= fun () -> + Db.exec drop_build () >>= fun () -> + Db.exec rename_build () >>= fun () -> + Db.exec (Grej.set_version new_version) () + +let rollback _datadir (module Db : Caqti_blocking.CONNECTION) = + Grej.check_version ~user_version:new_version (module Db) >>= fun () -> + Db.exec old_build () >>= fun () -> + Db.exec copy_build () >>= fun () -> + Db.exec drop_build () >>= fun () -> + Db.exec rename_build () >>= fun () -> + Db.exec (Grej.set_version old_version) () diff --git a/db/builder_db.ml b/db/builder_db.ml index c7e1d30..180369c 100644 --- a/db/builder_db.ml +++ b/db/builder_db.ml @@ -4,7 +4,7 @@ open Rep let application_id = 1234839235l (* Please update this when making changes! *) -let current_version = 10L +let current_version = 11L type id = Rep.id @@ -328,7 +328,7 @@ module Build = struct user INTEGER NOT NULL, job INTEGER NOT NULL, - FOREIGN KEY(main_binary) REFERENCES build_artifact(id), + FOREIGN KEY(main_binary) REFERENCES build_artifact(id) DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(user) REFERENCES user(id), FOREIGN KEY(job) REFERENCES job(id) )