diff --git a/bin/migrations/builder_migrations.ml b/bin/migrations/builder_migrations.ml index c751981..edcb8bf 100644 --- a/bin/migrations/builder_migrations.ml +++ b/bin/migrations/builder_migrations.ml @@ -178,6 +178,7 @@ let () = actions (module M20210712c); [ f20210910 ]; actions (module M20211105); + actions (module M20220509); ]) |> Cmd.eval |> exit diff --git a/bin/migrations/m20220509.ml b/bin/migrations/m20220509.ml new file mode 100644 index 0000000..1d32490 --- /dev/null +++ b/bin/migrations/m20220509.ml @@ -0,0 +1,56 @@ +let new_version = 16L and old_version = 15L +and identifier = "2022-05-09" +and migrate_doc = "switch uuid encoding to hex" +and rollback_doc = "switch uuid encoding back to binary" + +open Grej.Infix + +let old_uuid_rep = + let encode uuid = Ok (Uuidm.to_bytes uuid) in + let decode s = + Uuidm.of_bytes s + |> Option.to_result ~none:"failed to decode uuid" + in + Caqti_type.custom ~encode ~decode Caqti_type.string + +let new_uuid_rep = + let encode uuid = Ok (Uuidm.to_string uuid) in + let decode s = + Uuidm.of_string s + |> Option.to_result ~none:"failed to decode uuid" + in + Caqti_type.custom ~encode ~decode Caqti_type.string + +let uuids_byte_encoded_q = + Caqti_type.unit ->* + Caqti_type.tup2 (Builder_db.Rep.id (`build : [`build])) old_uuid_rep @@ + "SELECT id, uuid FROM build" + +let uuids_hex_encoded_q = + Caqti_type.unit ->* + Caqti_type.tup2 (Builder_db.Rep.id (`build : [`build])) new_uuid_rep @@ + "SELECT id, uuid FROM build" + +let migrate_q = + Caqti_type.tup2 (Builder_db.Rep.id (`build : [`build])) new_uuid_rep ->. + Caqti_type.unit @@ + "UPDATE build SET uuid = $2 WHERE id = $1" + +let rollback_q = + Caqti_type.tup2 (Builder_db.Rep.id (`build : [`build])) old_uuid_rep ->. + Caqti_type.unit @@ + "UPDATE build SET uuid = $2 WHERE id = $1" + +let migrate _datadir (module Db : Caqti_blocking.CONNECTION) = + let open Grej.Infix in + Grej.check_version ~user_version:old_version (module Db) >>= fun () -> + Db.collect_list uuids_byte_encoded_q () >>= fun old_uuids -> + Grej.list_iter_result (Db.exec migrate_q) old_uuids >>= fun () -> + Db.exec (Grej.set_version new_version) () + +let rollback _datadir (module Db : Caqti_blocking.CONNECTION) = + let open Grej.Infix in + Grej.check_version ~user_version:new_version (module Db) >>= fun () -> + Db.collect_list uuids_hex_encoded_q () >>= fun new_uuids -> + Grej.list_iter_result (Db.exec rollback_q) new_uuids >>= fun () -> + Db.exec (Grej.set_version old_version) () diff --git a/db/builder_db.ml b/db/builder_db.ml index 1c44c41..26244e2 100644 --- a/db/builder_db.ml +++ b/db/builder_db.ml @@ -5,7 +5,7 @@ open Caqti_request.Infix let application_id = 1234839235l (* Please update this when making changes! *) -let current_version = 15L +let current_version = 16L type 'a id = 'a Rep.id diff --git a/db/representation.ml b/db/representation.ml index c95e0cb..4d94b93 100644 --- a/db/representation.ml +++ b/db/representation.ml @@ -36,9 +36,9 @@ type file = { } let uuid = - let encode uuid = Ok (Uuidm.to_bytes uuid) in + let encode uuid = Ok (Uuidm.to_string uuid) in let decode s = - Uuidm.of_bytes s + Uuidm.of_string s |> Option.to_result ~none:"failed to decode uuid" in Caqti_type.custom ~encode ~decode Caqti_type.string