gizweb:view
one view of a relation for the grid, the pivot, the charts, the board, the timeline, the calendar and the gallery. A view is a Spec (fields, sort, filters, search, groups, measures, pivot). The server compiles it to the SQL of the relation's dialect, runs it bounded by what one screen shows, and answers with a binary columnar frame (GZV1) or JSON. The database computes and reduces; the browser keeps only the windows it shows. A page's tables answer at /_view/NAME through the Gate (gate); a product mounts another relation, such as an external database, with source and handle. Every value of a Spec becomes a quoted literal or a checked number, and every name must be a column of the relation, so a Spec cannot become other SQL.
import * as View from "gizweb:view";Types
Sort
type Sort = { field: string; desc?: bool; }An order of the view: a column, descending or not.
field:stringdesc:_gizlang_sdk_core.Option<bool>
Filter
type Filter = { field: string; op: string; values?: Vec<string>; }A condition on a column. OP is eq, ne, lt, le, gt, ge, between (two values), in, out (any values), contains, starts, ends, null or notnull.
field:stringop:stringvalues:_gizlang_sdk_core.Option<Vec<string>>
Measure
type Measure = { field: string; agg: string; expr?: string; name?: string; }An aggregate of a column: AGG (one of AGGREGATES) of FIELD (count of * counts rows). With EXPR it is instead a measure expression
(expression) over aggregates, such as sum(amount) / count() or sum(amount) / total(sum(amount)), and NAME is what people read.
field:stringagg:stringexpr:_gizlang_sdk_core.Option<string>name:_gizlang_sdk_core.Option<string>
Computed
type Computed = { name: string; expr: string; }A calculated column: NAME, and EXPR, an expression over the columns (and the calculated columns before it) that the database computes
(expression).
name:stringexpr:string
Spec
type Spec = { fields?: Vec<string>; sort?: Vec<Sort>; filters?: Vec<Filter>; search?: string; groups?: Vec<string>; measures?: Vec<Measure>; pivot?: Vec<string>; computed?: Vec<Computed>; where?: string; }One view of a relation. FIELDS empty is every column; COMPUTED adds calculated columns. WHERE is a condition in the expression language
(expression) that every row of the view meets, beside FILTERS.
fields:_gizlang_sdk_core.Option<Vec<string>>sort:_gizlang_sdk_core.Option<Vec<M104.Sort>>filters:_gizlang_sdk_core.Option<Vec<M104.Filter>>search:_gizlang_sdk_core.Option<string>groups:_gizlang_sdk_core.Option<Vec<string>>measures:_gizlang_sdk_core.Option<Vec<M104.Measure>>pivot:_gizlang_sdk_core.Option<Vec<string>>computed:_gizlang_sdk_core.Option<Vec<M104.Computed>>where:_gizlang_sdk_core.Option<string>
Cube
type Cube = { x: string; lo: f64; hi: f64; buckets: i64; }The cube of a reduction for a brush of the column X over LO..HI (axis units: milliseconds for a time) in BUCKETS steps: each group
of the reduction once per step, its measure in parts that add up (giz_sum and giz_count for an average), so a linked chart draws
any brush of those steps itself, however many rows the relation holds.
x:stringlo:f64hi:f64buckets:i64
Reduce
type Reduce = { kind: string; x?: string; y?: string; series?: string; agg?: string; expr?: string; buckets?: i64; ybuckets?: i64; top?: i64; cube?: Cube; }The reduction of a view: its KIND, the columns X, Y and SERIES, the aggregate AGG, the buckets and TOP, and the CUBE.
kind:stringx:_gizlang_sdk_core.Option<string>y:_gizlang_sdk_core.Option<string>series:_gizlang_sdk_core.Option<string>agg:_gizlang_sdk_core.Option<string>expr:_gizlang_sdk_core.Option<string>buckets:_gizlang_sdk_core.Option<i64>ybuckets:_gizlang_sdk_core.Option<i64>top:_gizlang_sdk_core.Option<i64>cube:_gizlang_sdk_core.Option<M104.Cube>
Cell
type Cell = { name: string; value?: string; }One cell of a row to add: a column and its wire text (none: NULL).
name:stringvalue:_gizlang_sdk_core.Option<string>
Edit
type Edit = { op?: string; key?: Vec<string>; name?: string; value?: string; before?: string; check?: bool; row?: Vec<Cell>; }One change of apply. set (the default) sets the column NAME of the row KEY (its key columns' wire texts, in order) to VALUE (none:
NULL); with CHECK it is refused as a conflict when the column no longer holds BEFORE (none: NULL). insert adds ROW, delete removes KEY.
op:_gizlang_sdk_core.Option<string>key:_gizlang_sdk_core.Option<Vec<string>>name:_gizlang_sdk_core.Option<string>value:_gizlang_sdk_core.Option<string>before:_gizlang_sdk_core.Option<string>check:_gizlang_sdk_core.Option<bool>row:_gizlang_sdk_core.Option<Vec<M104.Cell>>
Ask
type Ask = { op: string; spec?: Spec; from?: i64; count?: i64; total?: bool; by?: Vec<string>; path?: Vec<Option<string>>; after?: Vec<Option<string>>; skip?: i64; field?: string; like?: string; reduce?: Reduce; changes?: Vec<Edit>; format?: string; protect?: bool; title?: string; save?: string; data?: string; columns?: Vec<string>; dry?: bool; keys?: Vec<Vec<string>>; key?: Vec<string>; body?: string; }A request of a view. OP is describe, rows, aggregate, profile, values, reduce, apply, export, import, notes or note.
FROM and COUNT page rows, aggregate and values; TOTAL asks the count of all rows (or groups) as well. aggregate groups by BY,
inside the group PATH of the Spec's groups (none in PATH is NULL). AFTER (the order values of a row, sort fields then keys; none for
NULL) starts a rows window just after that row, SKIP rows further, instead of at FROM: a keyed view then never reads the rows before
it. marks answers the order values of every COUNT-th row, where a jump starts its window. FIELD is the column of values; LIKE
narrows it. profile answers a profile of each of COLUMNS, in one scan.
export writes FORMAT (one of FORMATS, csv the default): a workbook sheet is read-only with PROTECT, a PDF has TITLE over its table, and
with SAVE the file is kept under that name where the host keeps files (Opened.save) instead of answered. import reads DATA, a CSV
or XLSX file (FORMAT) in base64, whose first row names its columns; COLUMNS gives the view column of each file column ("" leaves it out,
a missing one is the column of that name or label), and DRY answers the preview without inserting. notes answers the notes of the cells
of the rows KEYS where the host keeps them (Opened.notes); note keeps BODY as the note of the cell of the row KEY and the column
FIELD (an empty BODY removes it).
op:stringspec:_gizlang_sdk_core.Option<M104.Spec>from:_gizlang_sdk_core.Option<i64>count:_gizlang_sdk_core.Option<i64>total:_gizlang_sdk_core.Option<bool>by:_gizlang_sdk_core.Option<Vec<string>>path:_gizlang_sdk_core.Option<Vec<_gizlang_sdk_core.Option<string>>>after:_gizlang_sdk_core.Option<Vec<_gizlang_sdk_core.Option<string>>>skip:_gizlang_sdk_core.Option<i64>field:_gizlang_sdk_core.Option<string>like:_gizlang_sdk_core.Option<string>reduce:_gizlang_sdk_core.Option<M104.Reduce>changes:_gizlang_sdk_core.Option<Vec<M104.Edit>>format:_gizlang_sdk_core.Option<string>protect:_gizlang_sdk_core.Option<bool>title:_gizlang_sdk_core.Option<string>save:_gizlang_sdk_core.Option<string>data:_gizlang_sdk_core.Option<string>columns:_gizlang_sdk_core.Option<Vec<string>>dry:_gizlang_sdk_core.Option<bool>keys:_gizlang_sdk_core.Option<Vec<Vec<string>>>key:_gizlang_sdk_core.Option<Vec<string>>body:_gizlang_sdk_core.Option<string>
Column
type Column = { name: string; label: string; ty: Type; key: bool; editable: bool; nullable: bool; values: Vec<string>; kind?: string; }A column of the relation: its SQL name, what people read, its type, and whether it is a key, may be changed and may be NULL. VALUES are the choices of its value; KIND, the no-code field kind that the grid shows and edits it as (none: as its type).
name:stringlabel:stringty:M80.Typekey:booleditable:boolnullable:boolvalues:Vec<string>kind:_gizlang_sdk_core.Option<string>
Fetched
type Fetched = { types: Vec<Type>; rows: Vec<Vec<Value>>; }Rows that a runner read, with the type of each column.
types:Vec<M80.Type>rows:Vec<Vec<M80.Value>>
Runner
type Runner = { dialect: string; relation: string; columns: Vec<Column>; writable: bool; fetch: (sql: string, outputs: Vec<Typed.Slot>, max: i64) => Fetched throws Model.Rejection; apply: (changes: Vec<Edit>) => i64 throws Model.Rejection; target?: string; }One relation that views read: its dialect, its SQL (a table or a parenthesized query), its columns, how to read a SELECT over it (with the result's slots, nameless, for a typed source) and how to apply changes in one transaction.
dialect:stringrelation:stringcolumns:Vec<M104.Column>writable:boolfetch:(sql: string, outputs: Vec<M79.Slot>, max: i64) => M104.Fetched throws M72.Rejectionapply:(changes: Vec<M104.Edit>) => i64 throws M72.Rejectiontarget:_gizlang_sdk_core.Option<string>— The table that changes go to when RELATION is a query over it, as a relation with computed columns is (none: RELATION).
Saving
type Saving = (name: string, write: (stream: Stream) => i64 throws IoError) => string throws Model.RejectionWhere a host keeps a file: the file NAME, filled by WRITE through its stream. Answers where it was kept.
Note
type Note = { key: Vec<string>; field: string; body: string; author: string; at: i64; }A note on the cell of the row KEY (its key values, as a frame writes them) and the column FIELD: BODY, by AUTHOR at AT (milliseconds since 1970).
key:Vec<string>field:stringbody:stringauthor:stringat:i64
Revision
type Revision = { field: string; before?: string; after?: string; author: string; at: i64; }One change of a cell of the row a history is of: its column FIELD from BEFORE to AFTER (none: NULL), by AUTHOR at AT.
field:stringbefore:_gizlang_sdk_core.Option<string>after:_gizlang_sdk_core.Option<string>author:stringat:i64
Noting
type Noting = { read: (keys: Vec<Vec<string>>) => Vec<Note> throws Model.Rejection; write: (key: Vec<string>, field: string, body: string) => Note throws Model.Rejection; history?: (key: Vec<string>) => Vec<Revision> throws Model.Rejection; }Where a host keeps the notes of a view's cells, one per cell: READ gives those of the rows KEYS, WRITE keeps BODY as the note of a cell (an empty BODY removes it) and answers it. HISTORY, when the host keeps it, gives the changes of the row KEY, newest first. Who may read and write them is the host's to decide.
read:(keys: Vec<Vec<string>>) => Vec<M104.Note> throws M72.Rejectionwrite:(key: Vec<string>, field: string, body: string) => M104.Note throws M72.Rejectionhistory:_gizlang_sdk_core.Option<(key: Vec<string>) => Vec<M104.Revision> throws M72.Rejection>
Opened
type Opened = { runner: Runner; close: () => void; save: Option<Saving>; notes: Option<Noting>; }A view that is open: its runner, what to release once it answered (a connection), where its exports are kept as files and where the notes of its cells are kept (none: the host keeps none).
runner:M104.Runnerclose:() => voidsave:_gizlang_sdk_core.Option<(name: string, write: (stream: gizlang_system.Stream) => i64 throws gizlang_system.IoError) => string throws M72.Rejection>notes:_gizlang_sdk_core.Option<M104.Noting>
Functions
expression
function expression(r: Runner, expr: string): Compiled throws Model.RejectionEXPR, an expression over the columns of R, as SQL and its type.
Effects: fail, read, write, console, io.
computed
function computed(r: Runner, spec: Spec): Runner throws Model.RejectionR with the calculated columns of SPEC: each wraps the relation in a SELECT that adds its column, so it sorts, filters, groups, pivots, reduces and exports as a stored column does, and a later one may name an earlier one. A calculated column is never edited.
Effects: fail, read, write, console, io.
frame
function frame(names: Vec<string>, fetched: Fetched, total: i64, from: i64, keys: Vec<string>): bytesNAMES and ROWS as a GZV1 frame: GZV1, the head's byte length (u32), the head (JSON: columns, rows, total, from, keys), then each
column: a null bitmap of ceil(rows / 8) bytes (bit set: NULL), then its values (i64, f64, a byte, or a dictionary: u32 count, each entry
u32 length and UTF-8 bytes, then a u32 code for each row).
Effects: fail.
selectSql
function selectSql(r: Runner, ask: Ask): string throws Model.RejectionThe SELECT of a window of rows (OP "rows") or of groups (OP "aggregate"), for a product that runs it itself or shows it, as an agent's answer does.
Effects: fail, read, write, console, io.
answer
function answer(r: Runner, ask: Ask, keeps: bool, notes: bool, history: bool = false): Http.Response throws Model.RejectionThe answer to ASK of the relation of R; KEEPS, NOTES and HISTORY say that the host keeps exports as files, notes of cells and the
changes of rows (describe tells the element).
Effects: fail, read, write, console, io.
held
function held(r: Runner): OpenedThe view of R, which holds nothing to release and keeps no files or notes.
handle
function handle(request: Http.Request, view: Result<Opened, Model.Rejection>): Http.ResponseThe answer to a POST of a JSON Ask to VIEW, which is released once it answered. A refusal is JSON: a view is called by its element, never by a form.
Effects: fail, read, write, console, io.
gate
function gate(s: Data.Scoped, shape: Model.Shape, sys: System): Runner throws Model.RejectionThe table of SHAPE as the actor of S may read it: the Gate's query of its rows (masks included) is the relation, and a change is a patch, an insert or a delete through the Gate, all in one transaction. A hidden field is not a column of the view, unless it is a key.
Effects: fail, read, write, console, io.
hosted
function hosted(context: Table.Context, shapes: Vec<Model.Shape>, name: string): Runner throws Model.RejectionThe view of the table NAME of the host (one of SHAPES) as the person of CONTEXT may use it.
Effects: fail, read, write, console, io.
serve
function serve(context: Table.Context, shapes: Vec<Model.Shape>, request: Http.Request): Http.ResponseThe answer to a request at /_view/NAME.
Effects: fail, read, write, console, io.
source
function source(src: Source.Source, relation: string, keys: Vec<string>, apply: Option<(changes: Vec<Edit>) => i64 throws Model.Rejection>): Runner throws Model.RejectionA relation of the source SRC: RELATION is a table path or a parenthesized SELECT. Its columns are the source's (a key column named in KEYS may identify a row); APPLY, when given, applies changes in one transaction, so the view may change rows.
Effects: fail, read, write, console, io.
editSql
function editSql(r: Runner, changes: Vec<Edit>): Vec<string> throws Model.RejectionThe SQL of CHANGES to R, whose relation is a table path (not a SELECT): one statement each, which changes exactly one row. A set with
CHECK compares the value it replaces too, so a statement that changes no row means the row changed since it was read.
Effects: fail.
Constants
FRAME
const FRAME = "application/vnd.gizlang.view"The media type of a frame.
WINDOW
const WINDOW = 10000The most rows of one window, one group level or one reduction.
PIVOT_CELLS
const PIVOT_CELLS = 200000The most cells of a pivot (rows times columns times measures).
EXPORT_ROWS
const EXPORT_ROWS = 1000000The most rows of an export.
CHANGES
const CHANGES = 100000The most changes of one apply, and rows of one import: each goes in one transaction.
FORMATS
const FORMATS = ["csv", "xlsx", "parquet", "pdf"]The file formats of an export.
BUCKETS
const BUCKETS = 4096The most buckets of a reduction on one axis.
AGGREGATES
const AGGREGATES = ["count", "distinct", "sum", "avg", "min", "max", "median", "p25", "p75", "p90", "p95", "p99", "stddev", "variance"]The aggregates of a measure. median and pNN are nearest-rank quantiles; stddev and variance are of a sample.
COMPUTED
const COMPUTED = 16The most calculated columns of one Spec, and the longest expression.
CUBE_CELLS
const CUBE_CELLS = 50000The most cells of a cube: a brush of more is refused, and the chart asks the server when the brush rests. Below the rows a text source answers (gizdb:source TEXT_ROWS); a chart sizes the steps of its cube to its groups (giz-grid.js cubeOf).
NOTE_CHARS
const NOTE_CHARS = 10000The most characters of one note.