Documentation
¶
Overview ¶
Package query builds Payload REST query strings.
The split is load-bearing and verified live (§2.3, §9.5): `where` and `data` are URL-encoded JSON strings, while `select`, `populate`, `joins`, `sort`, `depth`, `limit`, `page`, `draft` and `trash` use qs bracket notation. Sending `select` as a JSON string is silently dropped by the server, and bracket notation cannot express JSON null — `where[jobTitle][equals]=null` matched 0 documents where the JSON form matched 23.
Index ¶
- Constants
- Variables
- func BoolPtr(b bool) *bool
- func Canonical(alias string) (string, bool)
- func CheckOperator(op, dbAdapter, adapterSource string) error
- func CheckPathSyntax(path string) error
- func EncodePairs(pairs []Pair) string
- func EscapeLike(s string) string
- func ExtractOperators(w Where) []string
- func ExtractPaths(w Where) []string
- func IntPtr(n int) *int
- func IsOperator(s string) bool
- func KnownAliases() []string
- func ParseSince(expr string, now time.Time) (time.Time, error)
- func SplitList(s string) []string
- func TypeValue(raw string) (any, error)
- func TypedID(id, idType string) (any, error)
- func ValidateDateField(field string, s Schema) error
- func ValidateLimit(limit *int) error
- func ValidateSelect(fields []string, s Schema) error
- func ValidateSort(fields []string, s Schema) error
- func ValidateWhere(w Where, s Schema) error
- func WrapLike(s string) string
- type Input
- type Pair
- type Params
- type ParseOptions
- type Schema
- type Where
- func And(terms ...Where) Where
- func Build(in Input) (Where, error)
- func BuildTerm(path, alias, raw string, opts ParseOptions) (Where, error)
- func Combine(and []Where, or []Where) Where
- func DateTerm(field string, since, until *time.Time) Where
- func IDTerm(ids []string, idType string) (Where, error)
- func Or(terms ...Where) Where
- func ParseTerm(term string, opts ParseOptions) (Where, error)
- func ParseWhereJSON(s string) (Where, error)
- func QTerm(text string, fields []string) (Where, error)
- func Term(path, op string, value any) Where
- type WhereStyle
Constants ¶
const ( OpEquals = "equals" OpNotEquals = "not_equals" OpGreaterThan = "greater_than" OpGreaterThanEqual = "greater_than_equal" OpLessThan = "less_than" OpLessThanEqual = "less_than_equal" OpLike = "like" OpNotLike = "not_like" OpContains = "contains" OpIn = "in" OpNotIn = "not_in" OpAll = "all" OpExists = "exists" OpNear = "near" OpWithin = "within" OpIntersects = "intersects" )
The 16 operators Payload implements (§2.3, fixed list).
const MaxQFields = 12
MaxQFields caps the fan-out of --q (§9.4).
const SinceForms = "N[h|d|w|mo] (12h 30d 4w 1mo) · a Go duration (720h 90m 36h30m) · YYYY-MM-DD · full RFC 3339"
SinceForms documents the accepted --since/--until spellings; it is quoted verbatim in the error message so an agent never has to guess.
Variables ¶
var Operators = []string{ OpAll, OpContains, OpEquals, OpExists, OpGreaterThan, OpGreaterThanEqual, OpIn, OpIntersects, OpLessThan, OpLessThanEqual, OpLike, OpNear, OpNotEquals, OpNotIn, OpNotLike, OpWithin, }
Operators is the canonical operator list, sorted.
Functions ¶
func CheckOperator ¶
CheckOperator implements §9.3's tri-state rule for adapter-specific operators: reject locally only when PayCLI actually knows the adapter is Postgres. "unknown" means send it and learn.
func CheckPathSyntax ¶
CheckPathSyntax rejects a path that cannot be a field path before it reaches the server, where an unknown path is a 400 QueryError at best and silently ignored at worst.
func EscapeLike ¶
EscapeLike escapes the SQL LIKE metacharacters so a user's literal `%` or `_` is matched as itself. Verified live on the Postgres adapter.
func ExtractOperators ¶
ExtractOperators returns every operator used in a where clause, sorted.
func ExtractPaths ¶
ExtractPaths returns every field path a where clause queries, sorted and de-duplicated. `and` and `or` are structure, not fields, so they are walked through rather than reported.
func IsOperator ¶
IsOperator reports whether s is a canonical Payload operator.
func KnownAliases ¶
func KnownAliases() []string
KnownAliases lists every accepted spelling of every operator, sorted.
func ParseSince ¶
ParseSince resolves a --since/--until expression to an absolute instant. `now` is passed in (never read from the clock here) so the resolution is deterministic under test, per §3.1 and §9.4.
func SplitList ¶
SplitList splits a comma-separated list, honouring `\,` as a literal comma and `\\` as a literal backslash.
func TypeValue ¶
TypeValue applies §9.4 value typing to one raw token:
null -> JSON null true / false -> bool 1, -2, 3.5, 1e6 -> number (kept as json.Number so it round-trips verbatim) "123" / '123' -> string (quotes force a string) json:… -> raw JSON anything else -> string
This typing is the entire reason PayCLI emits JSON rather than bracket notation: the bracket form stringifies everything, and `equals=null` then silently matches nothing.
func TypedID ¶
TypedID coerces one id to the collection's id_type. An unknown id_type is the tri-state "send it and learn" case: §9.4 typing applies and nothing is rejected locally.
func ValidateDateField ¶
ValidateDateField enforces §9.4's --date-field rule.
func ValidateLimit ¶
ValidateLimit rejects `--limit 0`, which Payload reads as unlimited — an agent that means "no documents" would get every document instead.
func ValidateSelect ¶
ValidateSelect rejects an unknown --select key, which the server answers with HTTP 200 and a document containing only `id`.
func ValidateSort ¶
ValidateSort rejects an unknown sort field. The server's behaviour here is the worst kind: `sort=bogusField` returns HTTP 200, silently unsorted.
func ValidateWhere ¶
ValidateWhere checks every queried path and operator against the schema.
Types ¶
type Input ¶
type Input struct {
Where []string // --where, ANDed
Or []string // --or, one OR group ANDed with the rest
// WhereJSON is --where-json, which replaces everything else (§9.4).
WhereJSON string
// IDs is --id/--ids sugar, compiled to {"id":{"in":[…]}}.
IDs []string
// IDType is the manifest's id_type: "number", "string" or "unknown".
// Unknown means §9.4 typing decides, never a fabricated rejection.
IDType string
DraftOnly bool
PublishedOnly bool
// Q is --q: an OR of `contains` across QFields.
Q string
QFields []string
// Extra terms already compiled by the caller (e.g. --since/--until).
Extra []Where
Options ParseOptions
}
Input is everything the filter flags contribute to one where clause.
type Pair ¶
Pair is one already-escaped query-string parameter.
func Brackets ¶
Brackets renders a nested value into qs bracket notation under prefix:
Brackets("select", map[string]any{"hero": map[string]any{"media": true}})
-> select[hero][media]=true
Map keys are emitted in sorted order so the output is deterministic, and slices become [0], [1], … in index order.
A JSON null anywhere in the tree is a hard error: bracket notation has no syntax for it and the server reads the four characters "null" as the string "null", which silently matches nothing (verified: where[jobTitle][equals]=null returned 0 documents where the JSON form returned 23).
func WhereBrackets ¶
WhereBrackets renders a where tree in bracket notation for --where-style qs. It is a debugging aid; StyleJSON is what PayCLI sends by default.
type Params ¶
type Params struct {
Where Where
WhereStyle WhereStyle
// WhereRaw is --where-raw: a literal query string appended verbatim.
WhereRaw string
// Data is the rare `data=` query parameter (URL-encoded JSON, like where).
Data any
Sort []string
Limit *int
Page int
Depth *int
Select []string
SelectExclude []string
// Populate is populate[collection][field]=true.
Populate map[string][]string
// Joins is joins[field][limit]=5.
Joins map[string]map[string]string
Draft *bool
Trash *bool
Locale string
FallbackLocale string
// Extra carries anything a caller needs that this struct does not model
// (pay raw --query k=v). Keys are emitted in sorted order.
Extra url.Values
}
Params is every query parameter PayCLI knows how to send. Zero values are omitted, so one type serves find, get, count, create, update and upload.
func (Params) Clone ¶
Clone returns a shallow-enough copy that callers can adjust one field without mutating a shared Params.
type ParseOptions ¶
type ParseOptions struct {
// ReadFile resolves an @file.geojson argument. Nil means @file is refused
// rather than silently treated as a string — the query package performs no
// I/O of its own.
ReadFile func(path string) ([]byte, error)
// NoEscapeContains disables the `contains` escaping for a caller that
// genuinely wants LIKE wildcards.
NoEscapeContains bool
// NoWrapNotLike disables the not_like auto-wrap.
NoWrapNotLike bool
}
ParseOptions tunes term parsing. The zero value is the safe default.
type Schema ¶
type Schema struct {
// Collection is the slug, for error messages only.
Collection string
// Queryable lists field paths that may appear in a where clause.
Queryable []string
// Sortable lists field paths that may appear in --sort.
Sortable []string
// Selectable lists field paths that may appear in --select.
Selectable []string
// DateFields lists fields with payload_type "date".
DateFields []string
// DBAdapter / DBAdapterSource gate the adapter-specific operators.
DBAdapter string
DBAdapterSource string
}
Schema is the slice of the manifest the query layer needs. Every slice is tri-state: a nil slice means "PayCLI never learned this", and §9.3's rule is that an unknown fact is never a local rejection — the request is sent and a *_unknown warning is attached by the caller. An empty non-nil slice means "known to be empty" and does reject.
type Where ¶
Where is a Payload where-clause tree: {"and":[…]}, {"or":[…]} or {"field":{"operator":value}}.
func And ¶
And ANDs the non-empty terms. A single term is returned unwrapped so the simplest query stays the simplest string.
func BuildTerm ¶
func BuildTerm(path, alias, raw string, opts ParseOptions) (Where, error)
BuildTerm compiles one path/operator/value triple into a Where clause.
func Combine ¶
Combine implements §9.4's composition rule: --where terms are ANDed, and the repeatable --or terms form exactly one OR group which is ANDed with them.
func IDTerm ¶
IDTerm compiles --id/--ids into {"id":{"in":[…]}}, typing each id against the collection's id_type when it is known.
func ParseTerm ¶
func ParseTerm(term string, opts ParseOptions) (Where, error)
ParseTerm parses one `--where` / `--or` term: at most three whitespace-separated tokens — path, operator, rest-of-string-as-value — so a value containing spaces needs no quoting.
func ParseWhereJSON ¶
ParseWhereJSON decodes --where-json, rejecting anything that is not a JSON object so `--where-json '[…]'` fails here rather than as an opaque server 400.
type WhereStyle ¶
type WhereStyle string
WhereStyle selects the encoding of the `where` parameter.
const ( // StyleJSON is the default and the only style that can express null. StyleJSON WhereStyle = "json" // StyleQS emits bracket notation for debugging and URL-pasting // (--where-style qs). It fails loudly on a null comparison rather than // silently returning the wrong documents. StyleQS WhereStyle = "qs" )
func ParseWhereStyle ¶
func ParseWhereStyle(s string) (WhereStyle, error)
ParseWhereStyle validates a --where-style value.