Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildDSLQuery ¶
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
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
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 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 ¶
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.