Bylaw.Ecto.Query
Ecto query validation APIs and checks for Bylaw.
Use this package to validate prepared Ecto.Query structs before they run.
Callers choose checks explicitly and pass them to
Bylaw.Ecto.Query.validate/3.
Installation
Add :bylaw_ecto_query to your dependencies:
def deps do
[
{:bylaw_ecto_query, "~> 0.1.0-alpha.1"}
]
endUsage
For repo-wide validation, choose the query checks you want to enforce and pass
them explicitly to Bylaw.Ecto.Query.validate/3 from
c:Ecto.Repo.prepare_query/3:
defmodule MyApp.Repo do
use Ecto.Repo,
otp_app: :my_app,
adapter: Ecto.Adapters.Postgres
@query_checks [
Bylaw.Ecto.Query.Checks.RequiredOrder,
Bylaw.Ecto.Query.Checks.DeterministicOrder,
{Bylaw.Ecto.Query.Checks.MandatoryWhereKeys, keys: [:organization_id]}
]
@impl Ecto.Repo
def prepare_query(operation, query, opts) do
case Bylaw.Ecto.Query.validate(operation, query, @query_checks) do
:ok -> {query, opts}
{:error, issues} -> raise Bylaw.Ecto.Query.Issue.format_many(issues)
end
end
endIf you want to enable validation only in certain environments, gate the call with your own application config:
# config/dev.exs and config/test.exs
config :my_app, :bylaw, validate_ecto_queries?: true
# config/prod.exs
config :my_app, :bylaw, validate_ecto_queries?: falsedefmodule MyApp.Repo do
use Ecto.Repo,
otp_app: :my_app,
adapter: Ecto.Adapters.Postgres
@query_checks [
Bylaw.Ecto.Query.Checks.RequiredOrder,
{Bylaw.Ecto.Query.Checks.MandatoryWhereKeys, keys: [:organization_id]}
]
@impl Ecto.Repo
def prepare_query(operation, query, opts) do
if bylaw_ecto_query_enabled?() do
validate_query!(operation, query)
end
{query, opts}
end
defp validate_query!(operation, query) do
case Bylaw.Ecto.Query.validate(operation, query, @query_checks) do
:ok -> :ok
{:error, issues} -> raise Bylaw.Ecto.Query.Issue.format_many(issues)
end
end
defp bylaw_ecto_query_enabled? do
:my_app
|> Application.get_env(:bylaw, [])
|> Keyword.get(:validate_ecto_queries?, false)
end
end
This config belongs to :my_app. bylaw_ecto_query does not read application
config or register checks globally.
Built-in checks live under Bylaw.Ecto.Query.Checks.*. Start with the checks
that match your application invariants; each check module documents its own
examples, notes, options, and copyable check specs.