# `Tempo.Ecto.SQLite.QueryAPI`
[🔗](https://github.com/elixir-tempo/tempo_sql/blob/v0.4.0/lib/tempo/ecto/sqlite/query_api.ex#L1)

Ecto query fragments for `Tempo.Ecto.SQLite.TempoRange` columns, named
after Allen's interval algebra as `Tempo.Ecto.QueryAPI` names the
PostgreSQL range operators.

    import Ecto.Query
    import Tempo.Ecto.SQLite.QueryAPI

    {:ok, morning} = Tempo.Ecto.SQLite.QueryAPI.probe(~o"2026-06-15T09:00Z/2026-06-15T12:00Z")
    from m in Meeting, where: overlaps(m.window, ^morning)

The right-hand operand is a probe, the integer bounds of an expression
`probe/2` makes on the column's frame, pinned with `^`. Each macro
compares those bounds with the bounds the column's document holds:

  * `overlaps/2` — whether a span of the column shares any second with
    the probe.

  * `contains/2` — whether a span of the column holds every second of
    the probe.

  * `meets/2` — whether the column's stretch ends where the probe
    begins, or begins where it ends.

  * `strictly_before/2` — whether the column's stretch ends at or
    before the probe begins: Allen's `precedes` and `meets`.

  * `strictly_after/2` — whether the column's stretch begins at or
    after the probe ends.

`overlaps/2` and `contains/2` test each span the column holds, so the
gaps between a set's members match nothing, and first compare the
stretch, which the indexes `Tempo.SQL.SQLite.Migration.create_tempo_range_index/2`
creates answer. The bounds are whole seconds.

# `probe`

```elixir
@type probe() :: %{lo: integer(), hi: integer()}
```

The bounds of an expression, in whole seconds on a frame, for a query.

# `contains`
*macro* 

Matches rows with a span that holds every second of the probe.

### Arguments

* `column` is a `Tempo.Ecto.SQLite.TempoRange` column.

* `probe` is a probe from `probe/2`, pinned with `^`.

### Returns

* A query fragment usable anywhere Ecto accepts a boolean expression.

### Examples

    from s in Shop, where: contains(s.opening_hours, ^half_past_nine)

# `meets`
*macro* 

Matches rows whose stretch ends where the probe begins, or begins
where it ends.

### Arguments

* `column` is a `Tempo.Ecto.SQLite.TempoRange` column.

* `probe` is a probe from `probe/2`, pinned with `^`.

### Returns

* A query fragment usable anywhere Ecto accepts a boolean expression.

### Examples

    from m in Meeting, where: meets(m.window, ^lunch)

# `overlaps`
*macro* 

Matches rows with a span that shares any second with the probe.

### Arguments

* `column` is a `Tempo.Ecto.SQLite.TempoRange` column.

* `probe` is a probe from `probe/2`, pinned with `^`.

### Returns

* A query fragment usable anywhere Ecto accepts a boolean expression.

### Examples

    from m in Meeting, where: overlaps(m.window, ^morning)

# `probe`

```elixir
@spec probe(Tempo.t(), Tempo.SQL.Conversion.frame()) ::
  {:ok, probe()} | {:error, Exception.t()}
```

Makes the probe a query compares a column with: the bounds of an
expression, in whole seconds on the column's frame.

### Arguments

* `expression` is a `t:Tempo.t/0` with a place on the time line.

* `frame` is the column's frame, `:utc` (the default) or `:floating`.

### Returns

* `{:ok, probe}`, a map of `:lo` and `:hi`, to pin with `^`.

* `{:error, exception}` for an expression with no place on the time
  line, or of the other frame.

### Examples

    iex> Tempo.Ecto.SQLite.QueryAPI.probe(~o"2026-06-15T09:00Z/2026-06-15T10:00Z")
    {:ok, %{lo: 1781514000, hi: 1781517600}}

    iex> {:error, error} = Tempo.Ecto.SQLite.QueryAPI.probe(~o"2026-06-15T09:00/2026-06-15T10:00")
    iex> error.reason
    :frame

# `strictly_after`
*macro* 

Matches rows whose stretch begins at or after the probe ends.

### Arguments

* `column` is a `Tempo.Ecto.SQLite.TempoRange` column.

* `probe` is a probe from `probe/2`, pinned with `^`.

### Returns

* A query fragment usable anywhere Ecto accepts a boolean expression.

### Examples

    from m in Meeting, where: strictly_after(m.window, ^lunch)

# `strictly_before`
*macro* 

Matches rows whose stretch ends at or before the probe begins.

### Arguments

* `column` is a `Tempo.Ecto.SQLite.TempoRange` column.

* `probe` is a probe from `probe/2`, pinned with `^`.

### Returns

* A query fragment usable anywhere Ecto accepts a boolean expression.

### Examples

    from m in Meeting, where: strictly_before(m.window, ^lunch)

---

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