diff --git a/bin/migrations/builder_migrations.ml b/bin/migrations/builder_migrations.ml index 88e53fe..e72ab39 100644 --- a/bin/migrations/builder_migrations.ml +++ b/bin/migrations/builder_migrations.ml @@ -90,6 +90,11 @@ let m20210218 = Cmdliner.Term.(const do_database_action $ const M20210218.migrate $ setup_log $ dbpath), Cmdliner.Term.info ~doc "migrate-2021-02-18" +let r20210218 = + let doc = "Roll back column 'size' in 'build_file' and 'build_artifact' (2021-02-18)" in + Cmdliner.Term.(const do_database_action $ const M20210218.rollback $ setup_log $ dbpath), + Cmdliner.Term.info ~doc "rollback-2021-02-18" + let help_cmd = let topic = let doc = "Migration to get help on" in @@ -111,6 +116,6 @@ let () = m20210126; r20210126; m20210202; r20210202; m20210216; r20210216; - m20210218; + m20210218; r20210218; ] |> Cmdliner.Term.exit diff --git a/bin/migrations/m20210218.ml b/bin/migrations/m20210218.ml index 50d46dd..1229dcd 100644 --- a/bin/migrations/m20210218.ml +++ b/bin/migrations/m20210218.ml @@ -119,4 +119,61 @@ let migrate (module Db : Caqti_blocking.CONNECTION) = Db.exec (set_version new_user_version) () -(* FIXME: rollback. Requires copying data and creating new table without size column. *) +let old_build_artifact = + Caqti_request.exec ~oneshot:true + Caqti_type.unit + {| CREATE TABLE new_build_artifact ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + filepath TEXT NOT NULL, -- the path as in the build + localpath TEXT NOT NULL, -- local path to the file on disk + sha256 BLOB NOT NULL, + build INTEGER NOT NULL, + + FOREIGN KEY(build) REFERENCES build(id), + UNIQUE(build, filepath) + ) + |} + +let old_build_file = + Caqti_request.exec ~oneshot:true + Caqti_type.unit + {| CREATE TABLE new_build_file ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + filepath TEXT NOT NULL, -- the path as in the build + localpath TEXT NOT NULL, -- local path to the file on disk + sha256 BLOB NOT NULL, + build INTEGER NOT NULL, + + FOREIGN KEY(build) REFERENCES build(id), + UNIQUE(build, filepath) + ) + |} + +let copy_build_artifact = + Caqti_request.exec ~oneshot:true + Caqti_type.unit + "INSERT INTO new_build_artifact SELECT id, filepath, localpath, sha256, build FROM build_artifact" + +let copy_build_file = + Caqti_request.exec ~oneshot:true + Caqti_type.unit + "INSERT INTO new_build_file SELECT id, filepath, localpath, sha256, build FROM build_file" + +let rollback (module Db : Caqti_blocking.CONNECTION) = + let open Rresult.R.Infix in + Db.find Builder_db.get_application_id () >>= fun application_id -> + Db.find Builder_db.get_version () >>= fun user_version -> + if application_id <> Builder_db.application_id || user_version <> new_user_version + then Error (`Wrong_version (application_id, user_version)) + else + Db.exec old_build_artifact () >>= fun () -> + Db.exec copy_build_artifact () >>= fun () -> + Db.exec drop_build_artifact () >>= fun () -> + Db.exec rename_build_artifact () >>= fun () -> + + Db.exec old_build_file () >>= fun () -> + Db.exec copy_build_file () >>= fun () -> + Db.exec drop_build_file () >>= fun () -> + Db.exec rename_build_file () >>= fun () -> + + Db.exec (set_version old_user_version) ()