Bylaw.Ecto.Query.Checks.UnboundedDeletes (bylaw_ecto_query v0.2.0)

Copy Markdown View Source

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 this check. It can be used in the repo-wide check list or in call-site overrides passed to Bylaw.Ecto.Query.validate/4.

Run globally with defaults:

Bylaw.Ecto.Query.Checks.UnboundedDeletes

Run only for matching rule scopes:

{Bylaw.Ecto.Query.Checks.UnboundedDeletes,
 rules: [
   [where: [ecto_schemas: [Session]]],
   [where: [tables: ["sessions"]]]
 ]}

This check has no check-specific rule options.

Usage

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

Summary

Functions

validate(operation, query, opts)

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