dsl

package
v0.88.0 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildDSLQuery

func BuildDSLQuery(registry entity.Registry, input string) (*query.QueryBuilder, error)

BuildDSLQuery validates a DSL query against the app registry and returns a core query builder. Includes are validated; callers can resolve eager loading separately until relationship joins are fully generated.

func ParsePredicate added in v0.87.0

func ParsePredicate(text string, fields []schema.Field) (*filter.Predicate, error)

ParsePredicate parses the filter text the admin's filter chips, query box, a list view's Where and the ?filter= URL parameter carry, into a filter.Predicate that has already passed filter.ValidatePredicate against fields. It never builds SQL itself and never touches BuildDSLQuery, which applies no row scope; hand the predicate to a caller that does (the CRUD handler's in-process list), where owner, tenant, soft-delete and read scopes are ANDed around it.

Grammar (keywords are case-insensitive):

expr     := and_expr ("or" and_expr)*
and_expr := term ("and" term)*
term     := "(" expr ")" | field op value
op       := "=" | "!=" | "<" | ">" | "<=" | ">=" | "contains" | "in"
value    := quoted string ("\"" and "\\" escapes) | number | true | false
in value := "[" value ("," value)* "]"

`contains` maps to OpLike with the value wrapped for a literal substring match: the `%`, `_` and escape characters in the user's text are escaped and the clause carries an ESCAPE, so `contains "50%"` matches a literal 50%, not a wildcard pattern. `field` must be a bare identifier; whether it names a real, non-Hidden, non-NoQuery column of the right type is ValidatePredicate's question, answered before the tree is returned.

Empty or all-whitespace text returns (nil, nil). Input over maxDSLInputSize bytes is refused outright. Errors name the byte offset and quote at most a short, control-byte-scrubbed excerpt of the input.

func ParseSort added in v0.87.0

func ParseSort(text string, fields []schema.Field) ([]filter.ParsedSort, error)

ParseSort parses a view's Sort text — `due_on ASC`, `amount DESC, number ASC` — into filter.ParsedSort values. Field names are validated against fields: unknown and Hidden names are refused (indistinguishably, matching ParseSortValues), NoQuery names are refused by name, and a direction must be ASC or DESC, case-insensitive, defaulting to ASC when omitted. Empty or all-whitespace text returns (nil, nil).

Types

type DSLFilter

type DSLFilter struct {
	Field    string
	Operator string
	Value    string
}

DSLFilter is one where() predicate.

type DSLOrder

type DSLOrder struct {
	Field     string
	Direction string
}

DSLOrder is one order() clause.

type DSLQuery

type DSLQuery struct {
	Entity   string
	Filters  []DSLFilter
	Includes []string
	Orders   []DSLOrder
	Limit    int
	After    string
}

DSLQuery is the parsed representation of a GoFastr query DSL string.

func ParseDSL

func ParseDSL(input string) (DSLQuery, error)

ParseDSL parses strings like:

Post.where(status="published").include(author).order(created_at DESC).limit(10)

Results are cached by input string. The cache is bounded to 256 entries; when full, a single randomly-chosen entry is evicted (Go map iteration is randomised, so the first key returned by `range` is effectively random, this is not LRU).

The returned DSLQuery is caller-isolated: the cache stores the canonical copy and every call (hit or miss) returns a shallow copy with fresh Filters/Includes/Orders slices, the HooksFor posture. A value-typed result invites callers to adjust it in place; sharing the cached backing arrays would turn one caller's edit into every later caller's answer.

Jump to

Keyboard shortcuts

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