Migration helpers for creating PostgreSQL ICU collations.
PostgreSQL preloads ICU collations for plain locales, but not for
locales carrying a BCP 47 collation type such as de-u-co-phonebk
(German phonebook ordering) or zh-u-co-stroke (Chinese stroke
ordering). Those must be created once per database, which belongs
in a migration:
defmodule MyApp.Repo.Migrations.AddPhonebookCollation do
use Ecto.Migration
import Localize.Ecto.Migration
def change do
create_collation("de-u-co-phonebk")
end
endThe default collation name is the one Localize.Ecto.Collation
resolves the same locale to, so once created, the collation is used
automatically by Localize.Ecto.collate/2:
from p in Product, order_by: collate(p.name, "de-u-co-phonebk")The primary public API is create_collation/2 and
drop_collation/2. The SQL they execute is also available from
create_collation_sql/2 and drop_collation_sql/2.
Summary
Functions
Returns a collated column expression for use in an index definition.
Creates an ICU collation in a migration.
Returns the CREATE COLLATION statement for a locale.
Drops an ICU collation in a migration.
Returns the DROP COLLATION statement for a locale.
Functions
Returns a collated column expression for use in an index definition.
PostgreSQL only uses an index for a collated sort or comparison when
the index was created with the same collation. This function builds
the column expression for such an index, for use with
Ecto.Migration.index/3:
create index("products", [collated(:name, "de")])
create index("products", [collated(:name, collation: "german_phonebook")])Note that if a PostgreSQL upgrade links a newer ICU library whose
collation data changed — uncommon, but it happens — PostgreSQL warns
of a collation version mismatch and indexes built with that
collation must be reindexed (REINDEX INDEX index_name, then
ALTER COLLATION collation_name REFRESH VERSION).
Arguments
columnis the column name as an atom or string.locale_or_optionsis a locale accepted byLocalize.Ecto.Collation.collation_for!/2, or a keyword list with a:collationoption naming a collation directly. The default is the current locale fromLocalize.get_locale/0.
Returns
- A column expression string such as
"name" COLLATE "de-x-icu".
Examples
iex> Localize.Ecto.Migration.collated(:name, "de")
~s["name" COLLATE "de-x-icu"]
iex> Localize.Ecto.Migration.collated(:name, collation: "german_phonebook")
~s["name" COLLATE "german_phonebook"]
@spec create_collation(Localize.locale() | String.t(), Keyword.t()) :: :ok
Creates an ICU collation in a migration.
Runs CREATE COLLATION with the ICU provider. The operation is
reversible: rolling back drops the collation.
Arguments
localeis aLocalize.LanguageTag.t/0, or any locale identifier accepted byLocalize.validate_locale/1.optionsis a keyword list of options.
Options
:nameis the collation name to create. The default is the nameLocalize.Ecto.Collation.collation_for!/1resolveslocaleto, such as"de-u-co-phonebk-x-icu", so queries built withLocalize.Ecto.collate/2find the collation without further configuration.:icu_localeis the ICU locale string for the collation definition. The default is the canonical locale identifier oflocale, which preserves all BCP 47 extensions.:deterministicdetermines whether the collation is deterministic. The default istrue, matching PostgreSQL's default. Non-deterministic collations compare canonically equivalent strings as equal but cannot be used withLIKEor pattern matching.:if_not_existsaddsIF NOT EXISTSwhentrue. The default isfalse.:schemaschema-qualifies the collation name.
Returns
:ok.
Examples
create_collation("de-u-co-phonebk")
create_collation("de-u-co-phonebk", name: "german_phonebook")
create_collation("und-u-ks-level2", name: "case_insensitive", deterministic: false)
@spec create_collation_sql(Localize.locale() | String.t(), Keyword.t()) :: String.t()
Returns the CREATE COLLATION statement for a locale.
Arguments
localeis aLocalize.LanguageTag.t/0, or any locale identifier accepted byLocalize.validate_locale/1.optionsis a keyword list of options. Seecreate_collation/2.
Returns
- The SQL statement as a string.
Examples
iex> Localize.Ecto.Migration.create_collation_sql("de-u-co-phonebk")
~s[CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk')]
iex> Localize.Ecto.Migration.create_collation_sql("de-u-co-phonebk", name: "german_phonebook")
~s[CREATE COLLATION "german_phonebook" (provider = icu, locale = 'de-u-co-phonebk')]
@spec drop_collation(Localize.locale() | String.t(), Keyword.t()) :: :ok
Drops an ICU collation in a migration.
The operation is reversible: rolling back recreates the collation from the same arguments.
Arguments
localeis aLocalize.LanguageTag.t/0, or any locale identifier accepted byLocalize.validate_locale/1.optionsis a keyword list of options. Seecreate_collation/2;:if_not_existsis replaced by:if_exists.
Returns
:ok.
Examples
drop_collation("de-u-co-phonebk")
drop_collation("de-u-co-phonebk", name: "german_phonebook")
@spec drop_collation_sql(Localize.locale() | String.t(), Keyword.t()) :: String.t()
Returns the DROP COLLATION statement for a locale.
Arguments
localeis aLocalize.LanguageTag.t/0, or any locale identifier accepted byLocalize.validate_locale/1.optionsis a keyword list of options. Seedrop_collation/2.
Returns
- The SQL statement as a string.
Examples
iex> Localize.Ecto.Migration.drop_collation_sql("de-u-co-phonebk")
~s[DROP COLLATION "de-u-co-phonebk-x-icu"]
iex> Localize.Ecto.Migration.drop_collation_sql("de-u-co-phonebk", if_exists: true)
~s[DROP COLLATION IF EXISTS "de-u-co-phonebk-x-icu"]