builder-web/bin/migrations/m20210218.ml

123 lines
4.2 KiB
OCaml
Raw Normal View History

2021-02-23 14:37:30 +00:00
let old_user_version = 2L
let new_user_version = 3L
let set_version version =
Caqti_request.exec ~oneshot:true
Caqti_type.unit
(Printf.sprintf "PRAGMA user_version = %Ld" version)
2021-02-24 08:37:07 +00:00
let new_build_artifact =
2021-02-23 14:37:30 +00:00
Caqti_request.exec ~oneshot:true
Caqti_type.unit
2021-02-24 08:37:07 +00:00
{| 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,
size INTEGER NOT NULL,
build INTEGER NOT NULL,
2021-02-23 14:37:30 +00:00
2021-02-24 08:37:07 +00:00
FOREIGN KEY(build) REFERENCES build(id),
UNIQUE(build, filepath)
)
|}
let new_build_file =
2021-02-23 14:37:30 +00:00
Caqti_request.exec ~oneshot:true
Caqti_type.unit
2021-02-24 08:37:07 +00:00
{| 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,
size INTEGER NOT NULL,
build INTEGER NOT NULL,
FOREIGN KEY(build) REFERENCES build(id),
UNIQUE(build, filepath)
)
|}
2021-02-23 14:37:30 +00:00
2021-02-24 08:37:07 +00:00
let collect_build_artifact =
2021-02-23 14:37:30 +00:00
Caqti_request.collect ~oneshot:true
Caqti_type.unit
2021-02-24 08:37:07 +00:00
Caqti_type.(tup3 int64 (tup3 string string octets) int64)
"SELECT id, filepath, localpath, sha256, build FROM build_artifact"
2021-02-23 14:37:30 +00:00
2021-02-24 08:37:07 +00:00
let collect_build_file =
2021-02-23 14:37:30 +00:00
Caqti_request.collect ~oneshot:true
Caqti_type.unit
2021-02-24 08:37:07 +00:00
Caqti_type.(tup3 int64 (tup3 string string octets) int64)
"SELECT id, filepath, localpath, sha256, build FROM build_file"
let insert_new_build_artifact =
Caqti_request.exec ~oneshot:true
Caqti_type.(tup3 int64 (tup4 string string octets int64) int64)
{| INSERT INTO new_build_artifact (id, filepath, localpath, sha256, size, build)
VALUES (?, ?, ?, ?, ?, ?)
|}
let insert_new_build_file =
Caqti_request.exec ~oneshot:true
Caqti_type.(tup3 int64 (tup4 string string octets int64) int64)
{| INSERT INTO new_build_file (id, filepath, localpath, sha256, size, build)
VALUES (?, ?, ?, ?, ?, ?)
|}
let drop_build_artifact =
Caqti_request.exec ~oneshot:true
Caqti_type.unit
"DROP TABLE build_artifact"
let drop_build_file =
Caqti_request.exec ~oneshot:true
Caqti_type.unit
"DROP TABLE build_file"
2021-02-23 14:37:30 +00:00
2021-02-24 08:37:07 +00:00
let rename_build_artifact =
2021-02-23 14:37:30 +00:00
Caqti_request.exec ~oneshot:true
2021-02-24 08:37:07 +00:00
Caqti_type.unit
"ALTER TABLE new_build_artifact RENAME TO build_artifact"
2021-02-23 14:37:30 +00:00
2021-02-24 08:37:07 +00:00
let rename_build_file =
2021-02-23 14:37:30 +00:00
Caqti_request.exec ~oneshot:true
2021-02-24 08:37:07 +00:00
Caqti_type.unit
"ALTER TABLE new_build_file RENAME TO build_file"
2021-02-23 14:37:30 +00:00
let migrate (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 <> old_user_version
then Error (`Wrong_version (application_id, user_version))
else
2021-02-24 08:37:07 +00:00
Db.exec new_build_artifact () >>= fun () ->
Db.rev_collect_list collect_build_artifact () >>= fun build_artifacts ->
List.fold_left
(fun r (id, (filepath, localpath, sha256), build) ->
r >>= fun () ->
2021-02-23 14:37:30 +00:00
let stats = Unix.stat localpath in
2021-02-24 08:37:07 +00:00
Db.exec insert_new_build_artifact
(id, (filepath, localpath, sha256, Int64.of_int stats.st_size), build))
(Ok ())
build_artifacts >>= fun () ->
Db.exec drop_build_artifact () >>= fun () ->
Db.exec rename_build_artifact () >>= fun () ->
Db.exec new_build_file () >>= fun () ->
Db.rev_collect_list collect_build_file () >>= fun build_files ->
List.fold_left
(fun r (id, (filepath, localpath, sha256), build) ->
r >>= fun () ->
2021-02-23 14:37:30 +00:00
let stats = Unix.stat localpath in
2021-02-24 08:37:07 +00:00
Db.exec insert_new_build_file
(id, (filepath, localpath, sha256, Int64.of_int stats.st_size), build))
(Ok ())
build_files >>= fun () ->
Db.exec drop_build_file () >>= fun () ->
Db.exec rename_build_file () >>= fun () ->
Db.exec (set_version new_user_version) ()
2021-02-23 14:37:30 +00:00
(* FIXME: rollback. Requires copying data and creating new table without size column. *)