Locale-aware query expressions for Ecto on PostgreSQL.
The primary public API is the collate/1 and collate/2 macros,
which apply a PostgreSQL COLLATE clause to a query expression — or
to a comparison between two expressions — using the ICU collation
that best matches a locale. The collation name is resolved by
Localize.Ecto.Collation.resolve!/1 and emitted as a quoted
identifier via Ecto's literal/1 fragment, so it is never
interpolated into the SQL as text.
Import this module (or import Localize.Ecto, only: [collate: 1, collate: 2])
alongside Ecto.Query and use collate/1,2 anywhere a query
expression is accepted — order_by, select, where, distinct
and so on:
import Ecto.Query
import Localize.Ecto
# Collate using the current locale (Localize.get_locale/0)
from p in Product, order_by: collate(p.name)
# Collate using an explicit locale
from p in Product, order_by: collate(p.name, "sv")
# Locale determined at runtime
def sorted_products(locale) do
from p in Product, order_by: collate(p.name, ^locale)
end
# Collate a comparison: name < 'münchen' under German collation
from p in Product, where: collate(p.name < "münchen", "de"), select: p.name
# Use a collation created in a migration, by name
from p in Product, order_by: collate(p.name, collation: "german_phonebook")Collations for locales carrying a BCP 47 collation type, such as
de-u-co-phonebk, are not preloaded by PostgreSQL. Create them once
in a migration with Localize.Ecto.Migration.create_collation/2 and
they resolve automatically thereafter.
Summary
Functions
Applies a COLLATE clause for the current locale.
Applies a COLLATE clause for the given locale or collation.
Functions
Applies a COLLATE clause for the current locale.
The collation is resolved from Localize.get_locale/0 at the time
the query is built.
Arguments
expressionis any Ecto query expression that evaluates to a string value, or a comparison (<,<=,>,>=,==,!=) between two such expressions.
Returns
- A query fragment
expression COLLATE "collation", or for a comparisonleft OP right COLLATE "collation".
Examples
iex> import Ecto.Query
iex> query = from p in "products", order_by: collate(p.name), select: p.name
iex> match?(%Ecto.Query{}, query)
true
Applies a COLLATE clause for the given locale or collation.
Arguments
expressionis any Ecto query expression that evaluates to a string value, or a comparison (<,<=,>,>=,==,!=) between two such expressions.locale_or_optionsis aLocalize.LanguageTag.t/0, any locale identifier accepted byLocalize.validate_locale/1, or a keyword list of options. A pinned expression (^locale) is also accepted, so runtime locale values read naturally in query syntax.
Options
:collationis a collation name used verbatim, bypassing locale resolution — for example a collation created withLocalize.Ecto.Migration.create_collation/2under a custom name.Any other options are passed to
Localize.Ecto.Collation.collation_for!/2.
Returns
- A query fragment
expression COLLATE "collation", or for a comparisonleft OP right COLLATE "collation".
Examples
iex> import Ecto.Query
iex> query = from p in "products", order_by: collate(p.name, "sv"), select: p.name
iex> match?(%Ecto.Query{}, query)
true
iex> import Ecto.Query
iex> query = from p in "products", select: collate(p.name < p.description, "de")
iex> match?(%Ecto.Query{}, query)
true