FatEcto.Dynamics.FatDynamics (FatEcto v1.1.0)
View SourceProvides functions to build dynamic where
conditions for Ecto queries.
This module is designed to construct complex where
clauses dynamically using Ecto's dynamic/2
macro.
It supports a variety of conditions such as equality, inequality, comparison operators (>
, <
, >=
, <=
),
IN
clauses, LIKE
/ILIKE
for string matching, and JSONB operations (@>
, &&
).
Key Features:
- Dynamic Conditions: Builds
where
clauses dynamically based on field names, values, and logic types (:and
/:or
). - Binding Support: Supports query bindings for joins or nested queries via the
:binding
option. - JSONB Operations: Provides functions to work with JSONB fields, such as checking containment or overlap.
- String Matching: Supports
LIKE
andILIKE
for substring matching, including case-insensitive searches. - Range Queries: Allows building conditions for ranges (
BETWEEN
,IN
, etc.).
Usage:
Each function in this module constructs a dynamic expression that can be combined with other dynamics or used directly in an Ecto query. The functions accept the following common parameters:
key
: The field name (as a string or atom).value
: The value to compare against (can be a single value, list, or map depending on the function).opts
: Options to control the behavior, such:binding
(:last
for joins).
Example:
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.field_is_nil_dynamic(:location) iex> inspect(result) "dynamic([c], is_nil(c.location))"
This module is typically used internally by FatEcto
to construct queries based on user-provided filters.
Summary
Functions
Builds a dynamic query where any element in an array field matches a substring (case-insensitive).
Builds a dynamic query where a field's value is between two provided values.
Builds a dynamic query where a field's value is between or equal to two provided values.
Builds a dynamic query where a field casted to date is equal to a value.
Builds a dynamic query where a field casted to date is greater than a value.
Builds a dynamic query where a field casted to date is great than or equal to a value.
Builds a dynamic query where a field casted to date is less than a value.
Builds a dynamic query where a field casted to date is less than or equal to a value.
Builds a dynamic query where a JSONB field contains any of the provided values.
Builds a dynamic query where a JSONB field contains a specific value.
Builds a dynamic query where a field is equal to a value.
Builds a dynamic query where field is nil.
Builds dynamic condition for field greater than value.
Builds dynamic condition for field greater than or equal to value.
Builds a dynamic query where a field matches a substring (case-insensitive).
Builds a dynamic query where a field's value is in a provided list.
Builds a dynamic query where a field matches a substring (case-sensitive).
Builds a dynamic query where a field is less than a given value.
Builds dynamic condition for field less than or equal to value.
Builds a dynamic query where a field is not equal to a value.
Functions
@spec array_ilike_dynamic(any(), any(), nil | maybe_improper_list() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where any element in an array field matches a substring (case-insensitive).
Parameters
key
- The field name.value
- The substring to match.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.array_ilike_dynamic(:tags, "%elixir%")
iex> inspect(result)
"dynamic([q], fragment(\"EXISTS (SELECT 1 FROM UNNEST(?) as value WHERE value ILIKE ?)\", q.tags, ^\"%elixir%\"))"
@spec between_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field's value is between two provided values.
Parameters
key
- The field name.values
- A list of two values representing the range.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.between_dynamic(:experience_years, [2, 5])
iex> inspect(result)
"dynamic([q], q.experience_years > ^2 and q.experience_years < ^5)"
@spec between_equal_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field's value is between or equal to two provided values.
Parameters
key
- The field name.values
- A list of two values representing the range.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.between_equal_dynamic(:experience_years, [2, 5])
iex> inspect(result)
"dynamic([q], q.experience_years >= ^2 and q.experience_years <= ^5)"
@spec cast_to_date_eq_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field casted to date is equal to a value.
Parameters
key
- The field name to cast into date.value
- The value to compare against.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.cast_to_date_eq_dynamic(:end_date, ~D[2025-02-08])
iex> inspect(result)
"dynamic([q], fragment(\"?::date\", q.end_date == ^~D[2025-02-08]))"
@spec cast_to_date_gt_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field casted to date is greater than a value.
Parameters
key
- The field name to cast into date.value
- The value to compare against.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.cast_to_date_gt_dynamic(:end_date, ~D[2025-02-08])
iex> inspect(result)
"dynamic([q], fragment(\"?::date\", q.end_date > ^~D[2025-02-08]))"
@spec cast_to_date_gte_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field casted to date is great than or equal to a value.
Parameters
key
- The field name to cast into date.value
- The value to compare against.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.cast_to_date_gte_dynamic(:end_date, ~D[2025-02-08])
iex> inspect(result)
"dynamic([q], fragment(\"?::date\", q.end_date >= ^~D[2025-02-08]))"
@spec cast_to_date_lt_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field casted to date is less than a value.
Parameters
key
- The field name to cast into date.value
- The value to compare against.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.cast_to_date_lt_dynamic(:end_date, ~D[2025-02-08])
iex> inspect(result)
"dynamic([q], fragment(\"?::date\", q.end_date < ^~D[2025-02-08]))"
@spec cast_to_date_lte_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field casted to date is less than or equal to a value.
Parameters
key
- The field name to cast into date.value
- The value to compare against.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.cast_to_date_lte_dynamic(:end_date, ~D[2025-02-08])
iex> inspect(result)
"dynamic([q], fragment(\"?::date\", q.end_date <= ^~D[2025-02-08]))"
@spec contains_any_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a JSONB field contains any of the provided values.
Parameters
key
- The JSONB field name.values
- The values to check for overlap.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.contains_any_dynamic(:tags, ["elixir", "erlang"])
iex> inspect(result)
"dynamic([q], fragment(\"? && ?\", q.tags, ^[\"elixir\", \"erlang\"]))"
@spec contains_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a JSONB field contains a specific value.
Parameters
key
- The JSONB field name.values
- The value(s) to check for containment.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.contains_dynamic(:metadata, %{"role" => "admin"})
iex> inspect(result)
"dynamic([q], fragment(\"? @> ?\", q.metadata, ^%{\"role\" => \"admin\"}))"
@spec eq_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field is equal to a value.
Parameters
key
- The field name.value
- The value to compare against.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.eq_dynamic(:experience_years, 2)
iex> inspect(result)
"dynamic([q], q.experience_years == ^2)"
@spec field_is_nil_dynamic(any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where field is nil.
Parameters
key
- Field name.opts
- Options for binding. Examples iex> result = Elixir.FatEcto.Dynamics.FatDynamics.field_is_nil_dynamic(:location) iex> inspect(result) "dynamic([c], is_nil(c.location))"
@spec gt_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds dynamic condition for field greater than value.
Parameters
key
- Field name.value
- Comparison value or field reference.opts
- Options for binding Examples iex> result = Elixir.FatEcto.Dynamics.FatDynamics.gtdynamic(:experience_years, 2, [binding: :last]) iex> inspect(result) "dynamic([, ..., c], c.experience_years > ^2)"
@spec gte_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds dynamic condition for field greater than or equal to value.
Parameters
key
- Field name.value
- Comparison value or field reference.opts
- Options for binding Examples iex> result = Elixir.FatEcto.Dynamics.FatDynamics.gtedynamic(:experience_years, 2, [binding: :last]) iex> inspect(result) "dynamic([, ..., c], c.experience_years >= ^2)"
@spec ilike_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field matches a substring (case-insensitive).
Parameters
key
- The field name.value
- The substring to match.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.ilike_dynamic(:name, "%john%")
iex> inspect(result)
"dynamic([q], ilike(fragment(\"(?)::TEXT\", q.name), ^\"%john%\"))"
@spec in_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field's value is in a provided list.
Parameters
key
- The field name.values
- A list of values to match against.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.in_dynamic(:experience_years, [2, 5])
iex> inspect(result)
"dynamic([q], q.experience_years in ^[2, 5])"
@spec like_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field matches a substring (case-sensitive).
Parameters
key
- The field name.value
- The substring to match.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.like_dynamic(:name, "%John%")
iex> inspect(result)
"dynamic([q], like(fragment(\"(?)::TEXT\", q.name), ^\"%John%\"))"
@spec lt_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field is less than a given value.
Parameters
key
- The field name.value
- The value to compare against.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.lt_dynamic(:experience_years, 2, [binding: :last])
iex> inspect(result)
"dynamic([_, ..., c], c.experience_years < ^2)"
@spec lte_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds dynamic condition for field less than or equal to value.
Parameters
key
- Field name.value
- Comparison value or field reference.opts
- Options for binding Examples iex> result = Elixir.FatEcto.Dynamics.FatDynamics.lte_dynamic(:experience_years, 2) iex> inspect(result) "dynamic([q], q.experience_years <= ^2)"
@spec not_eq_dynamic(any(), any(), nil | keyword() | map()) :: Ecto.Query.dynamic_expr()
Builds a dynamic query where a field is not equal to a value.
Parameters
key
- The field name.value
- The value to compare against.opts
- Options for binding and logic type (:and/:or).
Examples
iex> result = Elixir.FatEcto.Dynamics.FatDynamics.not_eq_dynamic(:experience_years, 2)
iex> inspect(result)
"dynamic([q], q.experience_years != ^2)"