# `Lotus.Runner`
[🔗](https://github.com/elixir-lotus/lotus/blob/v1.0.0/lib/lotus/runner.ex#L1)

Statement execution with safety checks, param binding, and result shaping.

By default, all statements are read-only. Destructive operations (writes,
schema changes — INSERT, UPDATE, DELETE and DDL in SQL terms) are blocked
at both the application and database level. Pass `read_only: false` to
allow write operations.

What counts as a write is the adapter's judgement, via
`c:Lotus.Source.Adapter.sanitize_query/3`.

# `opts`

```elixir
@type opts() :: [
  timeout: non_neg_integer(),
  statement_timeout_ms: non_neg_integer(),
  read_only: boolean(),
  search_path: String.t() | nil,
  scope: term(),
  context: term(),
  vars: map()
]
```

# `query_result`

```elixir
@type query_result() :: Lotus.Result.t()
```

# `run_statement`

```elixir
@spec run_statement(Lotus.Source.Adapter.t(), Lotus.Query.Statement.t(), opts()) ::
  {:ok, query_result()} | {:error, term()}
```

---

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