Localize.Unit.DDL (Localize SQL v1.0.0)

Copy Markdown View Source

Generates the SQL that stores Localize.Unit.t/0 values in PostgreSQL.

A unit pairs a unit name with a decimal value — 2.5 metres, 100 kilometres — and is stored as a tagged decimal composite type so that the database can add and aggregate units while refusing to add metres to feet. This module returns the SQL creating those types and their aggregate functions; it is a thin wrapper over Localize.Ecto.TaggedDecimal.DDL, supplying the unit specifications.

Two composite types are created. cldr_unit(unit, value) stores a unit and its value; cldr_unit_with_usage(unit, value, usage) additionally preserves the unit's usage (:road versus :rainfall, say) across the round trip. Each has sum, min, max and avg aggregates that raise on a unit-name mismatch.

Migrations

The generated statements install into a migration with execute/1 and execute_each/1, which mix localize.unit.gen.migration does automatically:

defmodule MyApp.Repo.Migrations.AddCldrUnit do
  use Ecto.Migration

  def up do
    Localize.Unit.DDL.execute_each(Localize.Unit.DDL.create_cldr_unit())
    Localize.Unit.DDL.execute_each(Localize.Unit.DDL.define_aggregate_functions())
  end

  def down do
    Localize.Unit.DDL.execute_each(Localize.Unit.DDL.drop_aggregate_functions())
    Localize.Unit.DDL.execute_each(Localize.Unit.DDL.drop_cldr_unit())
  end
end

Summary

Types

The target database. Only PostgreSQL is supported; the argument exists so the API can grow without changing.

Functions

Returns the SQL creating the cldr_unit and cldr_unit_with_usage composite types.

Returns the SQL defining the sum, min, max and avg aggregates for both unit composite types.

Returns the SQL dropping the aggregates and their functions for both unit composite types.

Returns the SQL dropping the cldr_unit and cldr_unit_with_usage composite types.

Wraps a SQL string as a single execute call for a migration.

Wraps each statement of a SQL string as its own execute call.

Types

db_type()

@type db_type() :: :postgres

The target database. Only PostgreSQL is supported; the argument exists so the API can grow without changing.

Functions

create_cldr_unit(db_type \\ :postgres)

@spec create_cldr_unit(db_type()) :: String.t()

Returns the SQL creating the cldr_unit and cldr_unit_with_usage composite types.

Arguments

  • db_type is the target database. Only :postgres is supported. The default is :postgres.

Returns

  • The SQL statements as a string, separated by two blank lines.

Examples

iex> Localize.Unit.DDL.create_cldr_unit() =~ "CREATE TYPE public.cldr_unit AS"
true

define_aggregate_functions(db_type \\ :postgres)

@spec define_aggregate_functions(db_type()) :: String.t()

Returns the SQL defining the sum, min, max and avg aggregates for both unit composite types.

Arguments

  • db_type is the target database. Only :postgres is supported. The default is :postgres.

Returns

  • The SQL statements as a string, separated by two blank lines.

Examples

iex> Localize.Unit.DDL.define_aggregate_functions() =~ "CREATE OR REPLACE AGGREGATE sum(cldr_unit)"
true

drop_aggregate_functions(db_type \\ :postgres)

@spec drop_aggregate_functions(db_type()) :: String.t()

Returns the SQL dropping the aggregates and their functions for both unit composite types.

Arguments

  • db_type is the target database. Only :postgres is supported. The default is :postgres.

Returns

  • The SQL statements as a string, separated by two blank lines.

Examples

iex> Localize.Unit.DDL.drop_aggregate_functions() =~ "DROP AGGREGATE IF EXISTS avg(cldr_unit);"
true

drop_cldr_unit(db_type \\ :postgres)

@spec drop_cldr_unit(db_type()) :: String.t()

Returns the SQL dropping the cldr_unit and cldr_unit_with_usage composite types.

Arguments

  • db_type is the target database. Only :postgres is supported. The default is :postgres.

Returns

  • The SQL statements as a string, separated by two blank lines.

Examples

iex> Localize.Unit.DDL.drop_cldr_unit() =~ "DROP TYPE public.cldr_unit_with_usage;"
true

execute(sql)

@spec execute(String.t()) :: String.t()

Wraps a SQL string as a single execute call for a migration.

See Localize.Ecto.TaggedDecimal.DDL.execute/2.

Arguments

  • sql is a SQL string.

Returns

  • The execute call as a string.

Examples

iex> Localize.Unit.DDL.execute("DROP TYPE public.cldr_unit;")
"execute \"DROP TYPE public.cldr_unit;\""

execute_each(sql)

@spec execute_each(String.t()) :: String.t()

Wraps each statement of a SQL string as its own execute call.

See Localize.Ecto.TaggedDecimal.DDL.execute_each/2.

Arguments

  • sql is a SQL string possibly containing several statements.

Returns

  • The execute calls as a string, one per statement.

Examples

iex> Localize.Unit.DDL.execute_each(Localize.Unit.DDL.drop_cldr_unit()) =~ "execute"
true