View Source migraterl_plan (migraterl v0.5.0)

Pure diff engine.

Given the scripts discovered on disk and the currently-applied journal state, decides what must run. Has no database or filesystem dependencies, so it is exhaustively unit-testable in isolation.

Classification rules per script class:

  • once: run if never applied; if applied but the hash differs, that is content drift (a once script was edited after the fact) and surfaces as a warning, not a re-run.
  • on_change: run if never applied or if the hash differs.
  • always: always run; never consulted against the journal.

Out-of-order detection: a not-yet-applied once script that sorts before an already-applied once script is a late insertion. Whether that warns, errors, or is ignored is governed by the out-of-order policy.

Summary

Functions

Build the plan from disk scripts, current journal entries, and options.

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.

warning()

-type warning() :: {out_of_order, binary()} | {drift, binary()} | {missing, binary()}.

Functions

build(Scripts, Journal, Opts)

-spec build(Scripts, Journal, Opts) ->
               #plan{actions ::
                         [#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()}],
                     warnings :: [warning()],
                     skipped :: [binary()]}
               when
                   Scripts ::
                       [#script{namespace :: namespace(),
                                name :: binary(),
                                path :: file:filename_all(),
                                class :: script_class(),
                                order :: non_neg_integer(),
                                hash :: binary(),
                                sql :: binary()}],
                   Journal ::
                       #{binary() =>
                             #entry{namespace :: namespace(),
                                    name :: binary(),
                                    hash :: binary(),
                                    class :: once | on_change,
                                    applied_at :: binary()}},
                   Opts ::
                       #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()}.

Build the plan from disk scripts, current journal entries, and options.