# `Bandera.Store.Persistent.Ecto`

SQL persistence adapter. The repo and table name are read from
`Bandera.Config` at RUNTIME and queries bind the table via Ecto's
`{table_name, Record}` source form, so nothing about the table is fixed at
compile time. The `Record` schema supplies field types so values (e.g.
booleans) cast portably across SQL backends.

Configure:

    config :bandera,
      persistence: [
        adapter: Bandera.Store.Persistent.Ecto,
        repo: MyApp.Repo,
        ecto_table_name: "bandera_flags"
      ]

Run `Bandera.Ecto.Migrations.up/0` from a migration to create the table.

## Concurrency note

Writing a percentage gate uses a transaction (delete the existing "percentage"
row, insert the new one) rather than a database advisory lock. Single-writer
configuration flows — the common case — are fully consistent. Under concurrent
writes to the *same flag's* percentage gate, a colliding write returns
`{:error, _}` (safe to retry); a rare interleaving of two different-ratio writes
could momentarily leave two percentage rows. A future version may add advisory
locking (as fun_with_flags does) if needed.

## Errors

Unexpected database failures propagate as exceptions (let it crash — your repo's
supervision tree handles recovery), consistent with the other persistence
adapters. The percentage `put/2` additionally returns `{:error, reason}` when its
transaction is rolled back.

---

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