# `Tempo.Ecto.IntervalSet`
[🔗](https://github.com/elixir-tempo/tempo_sql/blob/v0.4.0/lib/tempo/ecto/interval_set.ex#L2)

Ecto.ParameterizedType for persisting the intervals an expression
covers as a PostgreSQL `tstzmultirange` value (PostgreSQL 14+), or
as a `tsmultirange` value when they are floating.

It takes any expression with a last span — a set, a bounded
recurrence, a value naming several — and loads a set of intervals.

## Usage

    schema "alice_calendar" do
      field :busy_times, Tempo.Ecto.IntervalSet
    end

and in the migration:

    add :busy_times, :tstzmultirange

(or use `Tempo.SQL.Migration.add_interval_set/2`). Floating values
go in a `tsmultirange`, on the floating frame:

    field :opening_hours, Tempo.Ecto.IntervalSet, frame: :floating

    add :opening_hours, :tsmultirange

## Options

  * `:resolution` — on load, truncate every member
    interval's endpoints to the given component. Same values
    and semantics as `Tempo.Ecto.Interval`.

  * `:frame` — `:utc` (the default) for a `tstzmultirange` column,
    `:floating` for a `tsmultirange` column, as for
    `Tempo.Ecto.Interval`.

## Storage contract

Every member interval must satisfy the same contract as
`Tempo.Ecto.Interval`. In addition:

  * The set must be non-empty. An empty multirange
    round-trips as `'{}'::tstzmultirange`; use a NULL column
    to represent "no set".

  * The expression must have a last span: a recurrence with no
    end has no multirange.

# `cast_type`

```elixir
@spec cast_type(keyword()) :: Ecto.Type.t()
```

Builds the parameterized-type tuple for use outside a schema.

See `Tempo.Ecto.Interval.cast_type/1` for the schema-side
equivalent and the full discussion.

### Arguments

* `options` is a keyword list of options.

### Options

* `:resolution` truncates member interval's endpoints on load to the given component. One of
  `:year`, `:month`, `:day`, `:hour`, `:minute`, or `:second`.
  Defaults to `:second`.

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

### Returns

* A `t:Ecto.ParameterizedType.opts/0` tuple.

### Examples

    iex> Tempo.Ecto.IntervalSet.cast_type()
    {:parameterized, {Tempo.Ecto.IntervalSet, %{frame: :utc, resolution: :second}}}

    iex> Tempo.Ecto.IntervalSet.cast_type(resolution: :day, frame: :floating)
    {:parameterized, {Tempo.Ecto.IntervalSet, %{frame: :floating, resolution: :day}}}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
