# `StatifierPersistence.Ecto.KeyGenerator`
[🔗](https://github.com/riddler/statifier_persistence/blob/v0.18.0/lib/statifier_persistence/ecto/key_generator.ex#L1)

Behaviour a surrogate-key scheme implements for the Ecto layer.

ADR-0002 makes the surrogate primary keys of this package's tables
compile-time configurable per host: `:uxid` (the default), `:uuid`
(UUIDv7), `:bigserial`, or any `{module, opts}` implementing this
behaviour. A key scheme must answer three questions - the Ecto schema
field type, the migration column type, and how a key is generated (or
that the database assigns it) - and both the generated schemas and the
migrations helper read their answers from the same resolved generator,
so the two cannot disagree.

Engine identities (the chart content hash, the engine session id, the
caller's execution id) are stored verbatim and are not touched by any key
generator - ADR-0002 decision 1.

The bundled implementations:

  * `StatifierPersistence.Ecto.KeyGenerator.UXID` - k-sortable strings
    with per-table prefixes (`chart_`, `pos_`, `exec_`)
  * `StatifierPersistence.Ecto.KeyGenerator.UUIDv7` - RFC 9562 UUIDv7
  * `StatifierPersistence.Ecto.KeyGenerator.Bigserial` -
    database-assigned auto-increment

# `spelling`

```elixir
@type spelling() :: :uxid | :uuid | :bigserial | {module(), keyword()}
```

ADR-0002's key option spellings.

# `table`

```elixir
@type table() :: :charts | :positions | :executions | :inputs
```

The tables whose rows carry a generated surrogate key.

# `autogenerate`

```elixir
@callback autogenerate(table(), opts :: keyword()) :: {module(), atom(), [term()]} | nil
```

The `{module, function, args}` an Ecto schema uses to autogenerate a
primary key for a row of `table`, or `nil` when the database assigns
the key itself.

# `ecto_type`

```elixir
@callback ecto_type(opts :: keyword()) :: atom()
```

The Ecto schema field type for the primary key, e.g. `:string`,
`Ecto.UUID`, or `:id`.

# `migration_type`

```elixir
@callback migration_type(opts :: keyword()) :: atom()
```

The column type the migrations helper emits for the primary key, e.g.
`:text`, `:uuid`, or `:bigserial`.

# `resolve`

```elixir
@spec resolve(spelling()) :: {module(), keyword()}
```

Resolves one of ADR-0002's key option spellings to `{module, opts}`.

`:uxid`, `:uuid`, and `:bigserial` map onto the bundled
implementations. A `{module, opts}` tuple passes through after a check
that `module` declares this behaviour; anything else raises
`ArgumentError`.

---

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