12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970typestep={label:string;statement:string;check_fk:bool}typesteps=steplisttypet=string*stepsletname="migration"exceptionExceptionofstringexceptionDirty_migrationmoduletypeSig=sig(** [register_migration migration] registers a migration [migration] with the
migration service so it can be executed with `run_all`. *)valregister_migration:t->unit(** [register_migrations migrations] registers migrations [migrations] with
the migration service so it can be executed with `run_all`. *)valregister_migrations:tlist->unit(** [execute migrations] runs all migrations [migrations]. *)valexecute:tlist->unitLwt.t(** [run_all ()] runs all migrations that have been registered. *)valrun_all:unit->unitLwt.t(** [pending_migrations ()] returns a list of migrations that need to be
executed in order to have all migrations applied. The returned migration
is a tuple [(namespace, number)] where [namespace] is the namespace of the
migration and [number] is the number of pending migrations that need to be
applied in order to achieve the desired schema version.
An empty list means that there are no pending migrations and that the
database schema is up-to-date. *)valpending_migrations:unit->(string*int)listLwt.tvalregister:tlist->Core_container.Service.tincludeCore_container.Service.Sigend(* Common *)letto_sexp(namespace,steps)=letopenSexplib0.Sexp_convinletopenSexplib0.Sexpinletsteps=List.map(fun{label;statement;check_fk}->List[List[Atom"label";sexp_of_stringlabel];List[Atom"statement";sexp_of_stringstatement];List[Atom"check_fk";sexp_of_boolcheck_fk]])stepsinList(List.cons(List[Atom"namespace";sexp_of_stringnamespace])steps);;letppfmtt=Sexplib0.Sexp.pp_humfmt(to_sexpt)letemptynamespace=namespace,[]letcreate_step~label?(check_fk=true)statement={label;check_fk;statement};;(* Append the migration step to the list of steps *)letadd_stepstep(label,steps)=label,List.concat[steps;[step]]