One answer of a source: its rows, as the source gave them, and what it actually served (spec/01 §3).
A delivery is a handful of terms beside its rows, never per row:
rows: the rows as the source gave them (macaw#185): a list of row maps or tuples, a map or keyword list of columns, anNx.Tensor, aTable.Readersource, or aMacaw.Data.Table. Nothing is packed or rewritten at construction:rows/1reads them as they are, a row list uncopied, andtable/2packs them into a table for a reader that wants columns, normalizing there and only there. A source that has a table delivers it, and it passes as it is. A gap staysnilin either form: absence is never zero.names: the column names of tuple rows or a tensor, in order, for whoever must read them by name (named_rows/1,table/2, finishing);nilotherwise.types: column types fortable/2to pack with,%{}to infer them.schema: the version of the schema the rows were produced under (Macaw.Data.Schema.version/1), never the schema itself, whichMacaw.Data.Schema.Cacheholds by version;nilwhen the source has none.served: what this answer served, which may differ from what was asked:window: a range[from, to], a box over a:pointwindow field%{west: w, south: s, east: e, north: n}, ornil;resolution: the spacing of the rows as served (seconds, or a name such as:minute), ornil;capped: whether the source stopped short of the window it was asked for;reduced_by: who brought the rows within budget,:sourceor:runtime, ornilwhen nobody had to;params: the parameters it was answered for, a map;note: a line for a person ("coarsened from raw"), ornil.
origin: where it came from,%{source: name, request: digest, as_of: time | nil}, ornil.
The shape of visualize's Visualize.Data.Delivery, whose facts are flat and whose
reduced_by is :feed or :visualize, is spec/01 §3's here.
Examples
iex> alias Macaw.Data.Delivery
iex> rows = [%{t: 1, v: 3}, %{t: 2, v: nil}]
iex> d = Delivery.new(rows, served: [window: [0, 10]], schema: "ab12")
iex> Delivery.rows(d) === rows
true
iex> {d.served.window, d.served.capped, d.served.reduced_by}
{[0, 10], false, nil}
iex> d |> Delivery.table!() |> Macaw.Data.Table.column(:v)
[3, nil]
Summary
Types
Where an answer came from.
What one answer served (spec/01 §3).
A window as served: a range, a box over positions, or none.
Functions
Whether the delivery has no rows.
The rows as maps, for a reader that reads them by name (finishing, push, a reducer):
rows/1, with tuple rows and a tensor's named by names (Macaw.Data.Table.named/2).
Tuple rows without names raise ArgumentError: they cannot be read by name, and are
never dropped for it.
A delivery of rows, any source Macaw.Data.Table.rows/1 reads, kept as given, with
served: (a keyword list or map of the served facts), schema: (a version), origin:,
names: (tuple rows' or a tensor's column names, in order) and types: (for
table/2).
The rows a delivery carries, as Macaw.Data.Table.rows/1 reads its source: a row list
itself, uncopied, its tuple rows unchanged; a table, a column map or a tensor one row
at a time. Nothing is rewritten.
The rows packed into a Macaw.Data.Table (spec/01 §1.1), for a reader that wants
columns: {:ok, table} or {:error, faults}. A table passes as it is. The delivery's
types: and names: apply, and opts may give others (types: merged over them).
Packing normalizes (an integer beside floats reads back a float, a naive time a UTC
DateTime); the delivery's rows are never changed by it.
As table/2, raising ArgumentError naming the faults.
Types
@type origin() :: %{source: term(), request: String.t(), as_of: DateTime.t() | nil} | nil
Where an answer came from.
@type served() :: %{ window: window(), resolution: term(), capped: boolean(), reduced_by: :source | :runtime | nil, params: map(), note: String.t() | nil }
What one answer served (spec/01 §3).
@type t() :: %Macaw.Data.Delivery{ names: [Macaw.Data.Table.name()] | nil, origin: origin(), rows: Macaw.Data.Table.source() | Macaw.Data.Table.t(), schema: String.t() | nil, served: served(), types: %{required(Macaw.Data.Table.name()) => Macaw.Data.Table.type()} }
@type window() :: [term()] | %{west: number(), south: number(), east: number(), north: number()} | nil
A window as served: a range, a box over positions, or none.
Functions
Whether the delivery has no rows.
The rows as maps, for a reader that reads them by name (finishing, push, a reducer):
rows/1, with tuple rows and a tensor's named by names (Macaw.Data.Table.named/2).
Tuple rows without names raise ArgumentError: they cannot be read by name, and are
never dropped for it.
@spec new(Macaw.Data.Table.source() | Macaw.Data.Table.t(), keyword()) :: t()
A delivery of rows, any source Macaw.Data.Table.rows/1 reads, kept as given, with
served: (a keyword list or map of the served facts), schema: (a version), origin:,
names: (tuple rows' or a tensor's column names, in order) and types: (for
table/2).
Raises ArgumentError naming the fault: a key that is not a delivery's or a served
fact, a value a field does not take, a delivery of a delivery, or rows of no shape a
source has. The rows themselves are not read: a source's rows are its own until a
reader reads them.
@spec rows(t()) :: [Macaw.Data.Table.row()]
The rows a delivery carries, as Macaw.Data.Table.rows/1 reads its source: a row list
itself, uncopied, its tuple rows unchanged; a table, a column map or a tensor one row
at a time. Nothing is rewritten.
@spec table(t(), keyword()) :: {:ok, Macaw.Data.Table.t()} | {:error, term()}
The rows packed into a Macaw.Data.Table (spec/01 §1.1), for a reader that wants
columns: {:ok, table} or {:error, faults}. A table passes as it is. The delivery's
types: and names: apply, and opts may give others (types: merged over them).
Packing normalizes (an integer beside floats reads back a float, a naive time a UTC
DateTime); the delivery's rows are never changed by it.
@spec table!(t(), keyword()) :: Macaw.Data.Table.t()
As table/2, raising ArgumentError naming the faults.