Tempo.SQL.Migration (Tempo SQL v0.4.0)

Copy Markdown View Source

Ecto migration helpers for the Tempo PostgreSQL range types.

These helpers wrap the underlying Postgres types — tstzrange and tstzmultirange, or tsrange and tsmultirange for a column on the floating frame — under Tempo-flavoured names, so a migration reads in the same vocabulary as the schema:

import Tempo.SQL.Migration

create table(:meetings) do
  add_interval :window
  add_interval_set :busy, null: false
  add_interval :opening_hours, frame: :floating
end

create_interval_index :meetings, :window

All helpers are thin delegates to Ecto.Migration.add/3 and Ecto.Migration.index/3 — callers can also write the raw add :window, :tstzrange form if they prefer.

Summary

Functions

Add a tstzrange column for a Tempo.Ecto.Interval field, or a tsrange column for one on the floating frame.

Add a tstzmultirange column for a Tempo.Ecto.IntervalSet field, or a tsmultirange column for one on the floating frame.

Adds a tempo_multirange column for a Tempo.Ecto.TempoMultirange field, or a tempo_floating_multirange column for one on the floating frame.

Adds a tempo_range column for a Tempo.Ecto.TempoRange field, or a tempo_floating_range column for one on the floating frame.

Create a GiST index on a range or multirange column, of either frame.

Create the composite types used by Tempo.Ecto.TempoRange and Tempo.Ecto.TempoMultirange on one frame.

Drops the composite types created by create_tempo_types/1 on one frame.

Functions

add_interval(field, options \\ [])

(macro)

Add a tstzrange column for a Tempo.Ecto.Interval field, or a tsrange column for one on the floating frame.

Arguments

  • field is the column name as an atom.

  • options is a keyword list of options.

Options

  • :frame is :utc (the default) for a tstzrange column or :floating for a tsrange column, as the field declares it.

  • Every other option is passed through to Ecto.Migration.add/3 — for example null: false, default: ....

Returns

Examples

add_interval :window
add_interval :window, null: false
add_interval :opening_hours, frame: :floating

add_interval_set(field, options \\ [])

(macro)

Add a tstzmultirange column for a Tempo.Ecto.IntervalSet field, or a tsmultirange column for one on the floating frame.

Requires PostgreSQL 14 or later.

Arguments

  • field is the column name as an atom.

  • options is a keyword list of options.

Options

  • :frame is :utc (the default) for a tstzmultirange column or :floating for a tsmultirange column.

  • Every other option is passed through to Ecto.Migration.add/3.

Returns

Examples

add_interval_set :busy_times
add_interval_set :free_slots, null: false

add_tempo_multirange(field, options \\ [])

(macro)

Adds a tempo_multirange column for a Tempo.Ecto.TempoMultirange field, or a tempo_floating_multirange column for one on the floating frame.

Requires create_tempo_types/1, for the column's frame, to have been run in an earlier migration, or earlier in this one.

Arguments

  • field is the column name as an atom.

  • options is a keyword list of options.

Options

  • :frame is :utc (the default) for a tempo_multirange column or :floating for a tempo_floating_multirange column.

  • Every other option is passed through to Ecto.Migration.add/3.

Returns

Examples

add_tempo_multirange :busy_times
add_tempo_multirange :busy_times, null: false

add_tempo_range(field, options \\ [])

(macro)

Adds a tempo_range column for a Tempo.Ecto.TempoRange field, or a tempo_floating_range column for one on the floating frame.

Requires create_tempo_types/1, for the column's frame, to have been run in an earlier migration, or earlier in this one.

Arguments

  • field is the column name as an atom.

  • options is a keyword list of options.

Options

  • :frame is :utc (the default) for a tempo_range column or :floating for a tempo_floating_range column.

  • Every other option is passed through to Ecto.Migration.add/3.

Returns

Examples

add_tempo_range :reporting_period
add_tempo_range :reporting_period, null: false

create_interval_index(table, column, options \\ [])

(macro)

Create a GiST index on a range or multirange column, of either frame.

Range-operator queries (@>, &&, -|-) are only fast under a GiST index — this helper wraps create index(..., using: :gist).

Arguments

  • table is the table name.

  • column is the range column to index.

  • options are passed through to Ecto.Migration.index/3. The :using option defaults to :gist.

Returns

Examples

create_interval_index :meetings, :window
create_interval_index :calendars, :busy_times, name: "calendars_busy_gist"

create_tempo_types(options \\ [])

@spec create_tempo_types(keyword()) :: :ok

Create the composite types used by Tempo.Ecto.TempoRange and Tempo.Ecto.TempoMultirange on one frame.

This should be run once for each frame a schema uses, in an early migration, before any schema declares a column of the types:

defmodule MyApp.Repo.Migrations.CreateTempoTypes do
  use Ecto.Migration
  import Tempo.SQL.Migration

  def up do
    create_tempo_types()
    create_tempo_types(frame: :floating)
  end

  def down do
    drop_tempo_types(frame: :floating)
    drop_tempo_types()
  end
end

On the UTC frame it creates two PostgreSQL composite types:

CREATE TYPE tempo_range AS (
  range      tstzrange,
  resolution text,
  meta       jsonb
);

CREATE TYPE tempo_multirange AS (
  ranges     tstzmultirange,
  resolution text,
  meta       jsonb
);

On the floating frame it creates tempo_floating_range and tempo_floating_multirange, the same with a tsrange and a tsmultirange.

These are the round-trip-preserving counterparts to the plain range columns used by Tempo.Ecto.Interval and Tempo.Ecto.IntervalSet.

Arguments

  • options is a keyword list of options.

Options

  • :frame is :utc (the default) or :floating.

Returns

  • The two CREATE TYPE statements, as Ecto.Migration.execute/2 returns them. Both are reversible, so a change/0 that calls this rolls back cleanly.

Examples

def change do
  create_tempo_types()

  create table(:meetings) do
    add_tempo_range :window
  end
end

drop_tempo_types(options \\ [])

@spec drop_tempo_types(keyword()) :: :ok

Drops the composite types created by create_tempo_types/1 on one frame.

Intended for use in down/0 callbacks. Fails if any column still uses either type — drop those columns first.

Arguments

  • options is a keyword list of options.

Options

  • :frame is :utc (the default) or :floating.

Returns

Examples

def up do
  create_tempo_types()
end

def down do
  drop_tempo_types()
end