query

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 9, 2026 License: MIT Imports: 8 Imported by: 0

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

View Source
const (
	DefaultLimit = 1000
	MaxLimit     = 10000
)

The row limits of a filter (ADR-0013, ADR-0020).

View Source
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

View Source
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 Forget added in v0.3.0

func Forget(cls *model.Class)

Forget drops the cached rights of a class the store no longer holds.

func IsPhysical

func IsPhysical(name string) bool

IsPhysical reports whether a name is a generated table rather than a view a user may read.

Types

type Error

type Error struct {
	Code     string
	Element  string
	Variable string
	Pos      int
	Message  string
	Hint     string
}

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.

func (*Error) Error

func (e *Error) Error() string

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

func Compile(f Filter, cls *model.Class, sources formula.Sources, p Principal) (*Plan, error)

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.

type Principal added in v0.3.0

type Principal struct {
	ID     string
	Groups []string
	Admin  bool
}

Principal is who a filter runs for (ADR-0041): the id and the groups its read rights are compiled with, and whether it is an administrator, who reads everything.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL