What a migration plan module compiles to.
A plan is a value: one repo and a list of rewrites, each naming a schema,
how the tenant is resolved for its rows, and the fields to rewrite. The
macros in Encryptor.Ecto.Migration build it at compile time and a plan
module hands it over through Encryptor.Ecto.Migration.__plan__/0; the
migrator (ece-b25) reads it and nothing else.
Keeping the compiled form a plain struct rather than generated behaviour
callbacks is what makes a plan inspectable. MyApp.CloakMigration.__plan__()
in a console prints the whole thing, a test can assert against it without
running a pass, and the dry-run report has something to name its rows after.
What the tenant field means here
ADR-0002 decision 3: the migrator supplies the tenant explicitly, per row,
rather than reading an ambient scope. So a rewrite's :tenant says where
the migrator finds it:
{:column, :account_id}- read it off the row being rewritten, which istenant_from :account_idin the DSL.:none- the field is global; there is no tenant to resolve.- a module - an
Encryptor.Ecto.TenantContextimplementation the migrator asks, for a host whose tenant is not a column of the table being rewritten.
:scope is deliberately absent, and the DSL refuses it: process scope is
ambient state a migrator running from a release command does not have, and
a plan that silently read the empty scope would rewrite every row under the
wrong key.
Summary
Types
One schema's rewrite: its tenant strategy and its fields, in declared order.
A compiled plan: one repo (ADR-0002 decision 12) and its rewrites.
How the migrator resolves the tenant for the rows of one rewrite.
Functions
The compiled plan a plan module carries, or an ArgumentError naming the DSL.
Types
@type rewrite() :: %{ schema: module(), tenant: tenant(), fields: [{atom(), Encryptor.Ecto.Migration.field_spec()}] }
One schema's rewrite: its tenant strategy and its fields, in declared order.
Each field is {name, field_spec}, where the name is the schema field the
bytes are read from and the spec is Encryptor.Ecto.Migration.field_spec/0.
A compiled plan: one repo (ADR-0002 decision 12) and its rewrites.
How the migrator resolves the tenant for the rows of one rewrite.
See the moduledoc for why :scope is not one of them.
Functions
The compiled plan a plan module carries, or an ArgumentError naming the DSL.
caller is the function to blame in the message - every entry point that
takes a plan module resolves it through here, and a message naming run/2
when the operator called verify/2 sends them to the wrong docs.
Checked with function_exported?/3 rather than by calling and rescuing: a
schema module handed to run/2 by mistake would otherwise fail with an
UndefinedFunctionError that says nothing about plans.