View Source migraterl_pg (migraterl v0.5.0)

PostgreSQL layer for migraterl.

Thin, explicit wrapper over epgsql. Owns the journal DDL, the version floor check, session-level advisory locking, the temporal journal upsert and the post-apply NOTIFY. Transaction boundaries are driven by the runner (via begin_txn/1, commit/1, rollback/1) so the same primitives serve per-script, single and no-transaction modes.

Summary

Functions

Acquire a session-level advisory lock for the namespace. Held across per-script commits and released in advisory_unlock/2.

Release the namespace advisory lock. Best-effort.

Execute one script and record it in the journal. Does NOT manage transaction boundaries; the caller wraps this as its txn mode dictates. Returns the execution time in milliseconds.

Fail fast unless the server is PostgreSQL 18 or newer; the journal relies on application-time temporal support.

The currently-in-force journal entries for a namespace, keyed by name.

Idempotently create the journal schema from the bundled DDL.

Types

action_reason()

-type action_reason() :: new | changed | always.

namespace()

-type namespace() :: binary().

ooo_policy()

-type ooo_policy() :: warn | error | ignore.

script_class()

-type script_class() :: once | on_change | always.

txn_mode()

-type txn_mode() :: per_script | single | none.

Functions

advisory_lock(Conn, Namespace)

-spec advisory_lock(epgsql:connection(), namespace()) -> ok | {error, term()}.

Acquire a session-level advisory lock for the namespace. Held across per-script commits and released in advisory_unlock/2.

advisory_unlock(Conn, Namespace)

-spec advisory_unlock(epgsql:connection(), namespace()) -> ok.

Release the namespace advisory lock. Best-effort.

apply_one/3

-spec apply_one(epgsql:connection(),
                #action{script ::
                            #script{namespace :: namespace(),
                                    name :: binary(),
                                    path :: file:filename_all(),
                                    class :: script_class(),
                                    order :: non_neg_integer(),
                                    hash :: binary(),
                                    sql :: binary()},
                        reason :: action_reason()},
                #opts{namespace :: namespace(),
                      sources :: [{script_class(), file:filename_all()}],
                      txn :: txn_mode(),
                      on_out_of_order :: ooo_policy(),
                      variables :: #{binary() => binary()},
                      dry_run :: boolean(),
                      notify :: boolean()}) ->
                   {ok, non_neg_integer()} | {error, term()}.

Execute one script and record it in the journal. Does NOT manage transaction boundaries; the caller wraps this as its txn mode dictates. Returns the execution time in milliseconds.

assert_version(Conn)

-spec assert_version(epgsql:connection()) -> ok | {error, term()}.

Fail fast unless the server is PostgreSQL 18 or newer; the journal relies on application-time temporal support.

begin_txn(Conn)

-spec begin_txn(epgsql:connection()) -> ok | {error, term()}.

commit(Conn)

-spec commit(epgsql:connection()) -> ok | {error, term()}.

current_entries(Conn, Namespace)

-spec current_entries(epgsql:connection(), namespace()) ->
                         {ok,
                          #{binary() =>
                                #entry{namespace :: namespace(),
                                       name :: binary(),
                                       hash :: binary(),
                                       class :: once | on_change,
                                       applied_at :: binary()}}} |
                         {error, term()}.

The currently-in-force journal entries for a namespace, keyed by name.

ensure_journal(Conn)

-spec ensure_journal(epgsql:connection()) -> ok | {error, term()}.

Idempotently create the journal schema from the bundled DDL.

rollback(Conn)

-spec rollback(epgsql:connection()) -> ok | {error, term()}.