Tempo.SQL.SQLite.Document (Tempo SQL v0.4.0)

Copy Markdown View Source

The JSON document a SQLite column holds for a Tempo expression.

SQLite has no range type, so Tempo.Ecto.SQLite.TempoRange stores an expression as one TEXT value holding a JSON object: the expression whole, as the PostgreSQL composite types keep it, beside the integer bounds of the time it covers.

{"v": 1, "frame": "utc", "lo": 1781514000, "hi": 1781517600,
 "spans": [[1781514000, 1781517600]],
 "meta": {"expression": "2026Y6M15DT9H0MZ/T10H0MZ", ...}}
  • lo and hi are the half-open bounds of the stretch the expression covers, from the start of its first span to the end of its last, in whole seconds: since the Unix epoch at UTC for a column on the UTC frame, and since 1970-01-01T00:00 on the wall clock for a floating one. A bound with a fraction of a second is rounded outward, so the bounds always cover the expression. An open end is the least or the greatest 64-bit integer.

  • spans are the bounds of each span the expression has, in order. A recurrence with no end has its stretch alone.

  • meta is the document Tempo.SQL.Meta writes, from which the expression is read back as it was written.

encode/2 writes the document, decode/1 reads the expression back, and bounds/2 gives the bounds alone, for a query's probe.

Summary

Types

A bound in whole seconds on a column's frame.

Functions

The half-open bounds of the stretch an expression covers, in whole seconds on a frame.

Reads back the expression a SQLite column's document holds.

Writes the document a SQLite column holds for an expression.

Types

bound()

@type bound() :: integer()

A bound in whole seconds on a column's frame.

Functions

bounds(expression, frame \\ :utc)

@spec bounds(Tempo.t(), Tempo.SQL.Conversion.frame()) ::
  {:ok, {bound(), bound()}} | {:error, Exception.t()}

The half-open bounds of the stretch an expression covers, in whole seconds on a frame.

Arguments

  • expression is a Tempo.t/0 with a place on the time line.

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

Returns

Examples

iex> Tempo.SQL.SQLite.Document.bounds(~o"2026-06-15/2026-06-16", :floating)
{:ok, {1781481600, 1781654400}}

iex> Tempo.SQL.SQLite.Document.bounds(~o"2026-06-15T09:00Z/..")
{:ok, {1781514000, 9223372036854775807}}

decode(json)

@spec decode(binary()) :: {:ok, Tempo.t()} | {:error, term()}

Reads back the expression a SQLite column's document holds.

Arguments

  • json is the document, as encode/2 writes it.

Returns

  • {:ok, expression}, a Tempo.t/0, as it was written.

  • {:error, reason} for a document that is not JSON, not of this shape, or whose expression cannot be read.

Examples

iex> {:ok, json} = Tempo.SQL.SQLite.Document.encode(~o"2026-06", :floating)
iex> Tempo.SQL.SQLite.Document.decode(json)
{:ok, ~o"2026-06"}

iex> {:error, {:invalid_document, _}} = Tempo.SQL.SQLite.Document.decode(~s({"v": 9}))

encode(expression, frame \\ :utc)

@spec encode(Tempo.t(), Tempo.SQL.Conversion.frame()) ::
  {:ok, binary()} | {:error, Exception.t()}

Writes the document a SQLite column holds for an expression.

Arguments

  • expression is a Tempo.t/0 with ISO 8601 text and a place on the time line.

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

Returns

Examples

iex> {:ok, json} = Tempo.SQL.SQLite.Document.encode(~o"2026-06-15T09:00Z/2026-06-15T10:00Z")
iex> document = Tempo.SQL.JSON.decode!(json)
iex> {document["lo"], document["hi"]}
{1781514000, 1781517600}

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