Localize.Ecto (Localize Ecto v0.1.0)

Copy Markdown View Source

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

collate(expression)

(macro)

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

  • expression is 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 comparison left 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

collate(expression, locale_or_options)

(macro)

Applies a COLLATE clause for the given locale or collation.

Arguments

  • expression is any Ecto query expression that evaluates to a string value, or a comparison (<, <=, >, >=, ==, !=) between two such expressions.

  • locale_or_options is a Localize.LanguageTag.t/0, any locale identifier accepted by Localize.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

Returns

  • A query fragment expression COLLATE "collation", or for a comparison left 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