Tempo.Ecto.SQLite.QueryAPI (Tempo SQL v0.4.0)

Copy Markdown View Source

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.

Summary

Types

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

Functions

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

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

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

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

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

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

Types

probe()

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

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

Functions

contains(column, probe)

(macro)

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

Arguments

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(column, probe)

(macro)

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

Arguments

Returns

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

Examples

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

overlaps(column, probe)

(macro)

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

Arguments

Returns

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

Examples

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

probe(expression, frame \\ :utc)

@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 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(column, probe)

(macro)

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

Arguments

Returns

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

Examples

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

strictly_before(column, probe)

(macro)

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

Arguments

Returns

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

Examples

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