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, :windowAll 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 a tstzrange column for a Tempo.Ecto.Interval field, or a
tsrange column for one on the floating frame.
Arguments
fieldis the column name as an atom.optionsis a keyword list of options.
Options
:frameis:utc(the default) for atstzrangecolumn or:floatingfor atsrangecolumn, as the field declares it.Every other option is passed through to
Ecto.Migration.add/3— for examplenull: false,default: ....
Returns
- The column declaration, as
Ecto.Migration.add/3returns it. Call it inside acreate tableblock.
Examples
add_interval :window
add_interval :window, null: false
add_interval :opening_hours, frame: :floating
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
fieldis the column name as an atom.optionsis a keyword list of options.
Options
:frameis:utc(the default) for atstzmultirangecolumn or:floatingfor atsmultirangecolumn.Every other option is passed through to
Ecto.Migration.add/3.
Returns
- The column declaration, as
Ecto.Migration.add/3returns it. Call it inside acreate tableblock.
Examples
add_interval_set :busy_times
add_interval_set :free_slots, null: false
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
fieldis the column name as an atom.optionsis a keyword list of options.
Options
:frameis:utc(the default) for atempo_multirangecolumn or:floatingfor atempo_floating_multirangecolumn.Every other option is passed through to
Ecto.Migration.add/3.
Returns
- The column declaration, as
Ecto.Migration.add/3returns it. Call it inside acreate tableblock.
Examples
add_tempo_multirange :busy_times
add_tempo_multirange :busy_times, null: false
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
fieldis the column name as an atom.optionsis a keyword list of options.
Options
:frameis:utc(the default) for atempo_rangecolumn or:floatingfor atempo_floating_rangecolumn.Every other option is passed through to
Ecto.Migration.add/3.
Returns
- The column declaration, as
Ecto.Migration.add/3returns it. Call it inside acreate tableblock.
Examples
add_tempo_range :reporting_period
add_tempo_range :reporting_period, null: false
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
tableis the table name.columnis the range column to index.optionsare passed through toEcto.Migration.index/3. The:usingoption defaults to:gist.
Returns
- The index creation, as
Ecto.Migration.create/1returns it.
Examples
create_interval_index :meetings, :window
create_interval_index :calendars, :busy_times, name: "calendars_busy_gist"
@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
endOn 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
optionsis a keyword list of options.
Options
:frameis:utc(the default) or:floating.
Returns
- The two
CREATE TYPEstatements, asEcto.Migration.execute/2returns them. Both are reversible, so achange/0that calls this rolls back cleanly.
Examples
def change do
create_tempo_types()
create table(:meetings) do
add_tempo_range :window
end
end
@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
optionsis a keyword list of options.
Options
:frameis:utc(the default) or:floating.
Returns
- The two
DROP TYPEstatements, asEcto.Migration.execute/2returns them.
Examples
def up do
create_tempo_types()
end
def down do
drop_tempo_types()
end