kura_migrator (kura v2.19.0)

View Source

Runs, rolls back, and reports status of migrations.

Discovers migration modules automatically from the application that owns the repo module. Any module named m<YYYYMMDDHHMMSS>_<name> in the application's module list is treated as a migration. Tracks applied versions in a schema_migrations table.

All migrations run within a single transaction protected by a PostgreSQL advisory lock (pg_advisory_xact_lock) to prevent concurrent execution across multiple nodes.

Summary

Functions

Check migration operations for actions that are unsafe during rolling deployments.

Compile a single DDL operation to SQL using RepoMod's dialect.

Stamp all pending migrations as applied WITHOUT running their DDL.

Run all pending migrations in order.

Roll back the last migration.

Roll back the last Steps migrations.

Return the status of all discovered migrations (:up or :pending).

Functions

check_unsafe_operations/2

-spec check_unsafe_operations([kura_migration:operation()], [kura_migration:safe_entry()]) -> [map()].

Check migration operations for actions that are unsafe during rolling deployments.

compile_operation/2

-spec compile_operation(module(), kura_migration:operation()) -> binary().

Compile a single DDL operation to SQL using RepoMod's dialect.

ensure_database(RepoMod)

-spec ensure_database(module()) -> ok.

ensure_schema_migrations(RepoMod)

-spec ensure_schema_migrations(module()) -> ok.

fake(RepoMod)

-spec fake(module()) -> {ok, [integer()]} | {error, term()}.

Stamp all pending migrations as applied WITHOUT running their DDL.

Baseline for brownfield adoption: after rebar3 kura gen_schemas bootstraps schema modules from an existing database, the first compile emits create_table migrations for tables that already exist. fake/1 records those in schema_migrations so real migrations proceed from there. It never executes migration DDL.

Precondition: fake/1 stamps EVERY pending migration. Only run it when every pending migration corresponds to schema that already exists - a genuinely-new migration in the pending set would be stamped without its table ever being created, and a later migrate/1 would then treat it as done. Check status/1 first; the versions about to be stamped are also logged at warning level. For the mixed new/existing case use a version-scoped baseline (kura#156).

migrate(RepoMod)

-spec migrate(module()) -> {ok, [integer()]} | {error, term()}.

Run all pending migrations in order.

rollback(RepoMod)

-spec rollback(module()) -> {ok, [integer()]} | {error, term()}.

Roll back the last migration.

rollback(RepoMod, Steps)

-spec rollback(module(), non_neg_integer()) -> {ok, [integer()]} | {error, term()}.

Roll back the last Steps migrations.

status(RepoMod)

-spec status(module()) -> [{integer(), module(), up | pending}].

Return the status of all discovered migrations (:up or :pending).

wait_for_pool(RepoMod)

-spec wait_for_pool(module()) -> ok | {error, pool_unavailable}.

wait_for_pool(RepoMod, Timeout)

-spec wait_for_pool(module(), non_neg_integer()) -> ok | {error, pool_unavailable}.