Documentation
¶
Overview ¶
Package query compiles the JSON filter of the Go API and the command set into SQL over a class's view, and guards the read-only SQL endpoint (docs/architecture.md, "Querying"; ADR-0038).
A Filter names a class and gives a where formula over the class's variables and the system columns, an order, a limit, an offset and the fields to return. The formula is bound by the formula engine and translated by its SQL generator, so a filter means exactly what the same expression means in a formula: blanks read as 0 and "", comparisons follow ADR-0019, and a row on which the formula stops with an error does not match. Beside that exact predicate the compiler adds, for every comparison of a column with a literal in the top-level AND of the formula, the same comparison on the bare column, which SQLite can answer from an index; it is exact because a literal that a blank would not satisfy never matches a blank row, and when a blank would satisfy it, the blank rows are added back.
Authorizer is the function the read-only SQL endpoint installs on its connection: SELECT, reads through the views and function calls are allowed; reads of the physical tables, writes, schema changes, pragmas and attachments are refused.
The read rights of ADR-0028 are compiled into a filter for its principal (ADR-0041): a variable the where or the order names matches and sorts only in the rows whose state lets the principal read it, and a variable the principal may read in no state refuses the filter with forbidden. The class-level access rules, the row predicates of ADR-0010, wait for Phase 5; a SQL statement sees every row and every column, as ADR-0028 decided for the views.
Index ¶
Constants ¶
const ( DefaultLimit = 1000 MaxLimit = 10000 )
The row limits of a filter (ADR-0013, ADR-0020).
const ( CodeBadFormula = "bad_formula" CodeNotAllowed = "not_allowed" CodeUnknownVariable = "unknown_variable" CodeBadValue = "bad_value" // CodeForbidden: the where or the order names a variable the // principal may read in no state at all (ADR-0041). CodeForbidden = "forbidden" )
The codes a filter is refused with.
Variables ¶
var EngineTables = map[string]bool{ "SCHEMA_VERSION": true, "METADATA": true, "SCHEMAS": true, "CLASSES": true, "CLASS_VERSIONS": true, "TABLES_REGISTRY": true, "EVENTS": true, "EVENT_DOCS": true, }
EngineTables are the tables the engine keeps for itself; none is readable through the endpoint.
Functions ¶
func Authorizer ¶
func Authorizer(views map[string]bool) sqlite.AuthorizerFn
Authorizer makes the authorizer of the read-only SQL endpoint (docs/architecture.md, ADR-0038). It allows SELECT, reads of the views in the set and of whatever a view reads on the user's behalf, and function calls other than the ones that reach the file system; it refuses reads of the physical tables' columns and of the schema, every write, every schema change, pragmas, attachments and transactions. SQLite reports a refusal as an error of the statement, before it runs.
When a statement reads no column of a table, count(*) or SELECT 1 over a view, SQLite reports one read of the underlying table with an empty column name and no view context. That read is allowed for the tables behind the views, doc_ and tbl_, since it reveals no column; it is refused for the engine's own tables and the schema.
func IsPhysical ¶
IsPhysical reports whether a name is a generated table rather than a view a user may read.
Types ¶
type Error ¶
Error is a refusal of a filter: a code of the store's list, the element of the filter it is about, the variable when the finding is about one, the byte offset inside where when the finding is in the formula, a message and a hint.
type Filter ¶
type Filter struct {
Class string `json:"class"`
// Where is a formula over the class's variables and the system
// columns id, title, state, version, class_version, created_at,
// updated_at and state_entered_at; empty matches every document.
Where string `json:"where,omitempty"`
// Order lists variables or system columns to sort by, a leading "-"
// for descending; empty is by id.
Order []string `json:"order,omitempty"`
// Limit is at most MaxLimit; 0 is DefaultLimit. Offset skips rows.
Limit int `json:"limit,omitempty"`
Offset int `json:"offset,omitempty"`
// Fields names the variables to return; empty returns every variable.
Fields []string `json:"fields,omitempty"`
}
Filter is one query over a class (ADR-0038).
type Plan ¶
type Plan struct {
// Where is the WHERE clause without the keyword, "" for none.
Where string
// Order is the ORDER BY list without the keywords.
Order string
// Args are the named parameters Where references, the prefilter's
// literals and the context parameters of the dialect.
Args []any
Limit, Offset int
// Fields are the declared names of the variables to return, nil for
// all.
Fields []string
// Prog is the bound where formula, nil when there is none.
Prog *formula.Program
}
Plan is a compiled filter: the fragments the store puts around its select list, the parameters, and the fields to return.
func Compile ¶
Compile binds a filter against a class and translates it for SQLite. sources are the explicit tables the store has, so that a lookup in the where is refused as a lookup and not as an unknown name; nil is none. The read rights of the variables the where and the order name are compiled into the predicate for the principal (ADR-0041). The context parameters of the dialect are bound by the caller.