# `Bylaw.Ecto.Query.Checks.UnboundedDeletes`
[🔗](https://github.com/ryanzidago/bylaw/blob/v0.1.0-alpha.1/lib/bylaw/ecto/query/checks/unbounded_deletes.ex#L1)

Validates that `delete_all` queries are bounded.

This check prevents accidental table-wide deletes by requiring callers to add
a restricting root `where` or `or_where` before `Repo.delete_all/2` runs.

## Examples

Bad:

    from(Session, as: :session)

Why this is bad:

A `delete_all` query without a root predicate can remove every row in the
table.

Better:

    from(Session, as: :session)
    |> where([session: s], s.expires_at < ^DateTime.utc_now())

Why this is better:

The root `where` clause states the intended delete scope.

## Notes

This check only requires a non-true root predicate. It does not prove the
predicate is selective or semantically correct.

The check only validates the root query prepared for the `:delete_all`
operation. It requires every possible root `where` branch to include at least
one non-true expression and does not try to prove whether that
predicate is selective.

## Options

  * `:validate` - explicit `false` disables the check. Defaults to `true`.

## Usage

Add this module to the explicit check list passed through `Bylaw.Ecto.Query`.
See `Bylaw.Ecto.Query` for the full `c:Ecto.Repo.prepare_query/3` setup.

# `validate`

```elixir
@spec validate(
  Bylaw.Ecto.Query.Check.operation(),
  Bylaw.Ecto.Query.Check.query(),
  opts()
) ::
  Bylaw.Ecto.Query.Check.result()
```

Implements the `Bylaw.Ecto.Query.Check` validation callback.

---

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