# `Host.Migrator`
[🔗](https://github.com/aaronrussell/beamlet/blob/v0.1.0/lib/host/migrator.ex#L1)

Run the migrations you define against the agent database, and read
their history.

A migration is a module that uses `Ecto.Migration`, defined with
the define tool like any other. Your beamlet files it with the next
version number; it is *pending* until you run it from here. The
loop is: define the migration, `migrate/0`, then define the
`Ecto.Schema` module for the table it created and use it through
`Host.Repo`.

    defmodule Shopping.CreateLists do
      @moduledoc "Creates the shopping lists table."
      use Ecto.Migration

      def change do
        create table(:shopping_lists) do
          add :name, :string, null: false
          timestamps type: :utc_datetime
        end
      end
    end

Then, from eval: `Host.Migrator.migrate()`.

`migrate/0` and `rollback/0` change the database, print what they
applied or undid, and return `:ok`; `print_migrations/0` prints the
history, version, module, applied or pending, and returns `:ok`.
A failure raises with a teaching message. Inside a migration, query
by table name and call `Host.Repo` by name after `flush()`; do not
reference schema modules, which change while a migration is frozen
history.

To change a migration that has run, `rollback/0`, replace it and
`migrate/0` again. SQLite cannot change a column's type or drop a
constraint: create a new table, copy the rows with an insert from
a select, drop the old table and rename the new one.

# `migrate`

```elixir
@spec migrate() :: :ok
```

Applies every pending migration in version order, printing each
one as it is applied.

Nothing pending prints so. If one fails, the ones before it stay
applied and the error names the one that failed; fix it with define
(replace: true) and migrate again.

# `print_migrations`

```elixir
@spec print_migrations() :: :ok
```

Prints the migration history: each version with its module and
whether it is applied (with when) or pending.

This is the audit trail of every change made to the agent
database's tables.

# `rollback`

```elixir
@spec rollback() :: :ok
```

Undoes the most recently applied migration and prints it.

The migration is pending again: replace or remove it, or migrate to
re-apply it. Call repeatedly to roll back further.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
