Documentation
¶
Index ¶
Constants ¶
const MaxSearchTerms = 8
MaxSearchTerms bounds the number of tokens a single ?q= value expands to. A search term is one whitespace-delimited token; beyond this cap, extra tokens are dropped. Keeps statement size bounded against an adversarial input.
Variables ¶
This section is empty.
Functions ¶
func ApplySortToQuery ¶
func ApplySortToQuery(qb *query.QueryBuilder, sorts []ParsedSort)
applySortToQuery applies parsed sorts to a query builder.
func ApplyToCountQuery ¶
func ApplyToCountQuery(cb *query.CountBuilder, filters []ParsedFilter)
applyFiltersToCountQuery applies parsed filters to a count builder.
func ApplyToQuery ¶
func ApplyToQuery(qb *query.QueryBuilder, filters []ParsedFilter)
applyFiltersToQuery applies parsed filters to a query builder.
Types ¶
type Condition ¶ added in v0.18.0
Condition is a single WHERE fragment (SQL + args) produced by SearchConditions. Convert to a hook.WhereClause and append via qb.Where(c.SQL, c.Args…) — the query builder wraps each Where in parens and AND-composes them, so multi-field search clauses combine safely with owner/tenant/soft-delete scopes.
func SearchConditions ¶ added in v0.18.0
SearchConditions builds a slice of AND-composed search conditions from a free-text term over the given DB column names. Each whitespace- delimited token produces one Condition whose SQL is a parenthesized OR-group: (LOWER(f1) LIKE $1 ESCAPE '\' OR LOWER(f2) LIKE $2 ESCAPE '\'). Every Condition must match (AND); within one Condition, any field may match (OR). A blank/whitespace-only term returns nil (no conditions).
Case contract: LOWER() is ASCII-only on SQLite and locale-aware on Postgres, so matching is ASCII-case-insensitive everywhere. Unicode case folding is a Postgres bonus. The token itself is lowercased before building the LIKE pattern so the comparison is consistent across dialects.
LIKE metacharacters (%, _, \) in each token are escaped via the existing escaper so they match literally — a user searching for "50%" finds rows containing "50%", not every row with any character sequence. The args are ordered to match the $N placeholders left-to-right; the crud query builder renumbers $N on Build.
type ParsedFilter ¶
ParsedFilter represents a single parsed filter from query parameters.
func ParseFilters ¶
ParseFilters extracts filters from query parameters based on entity fields. Supported patterns:
?field=value → equals ?field_gt=value → greater than ?field_lt=value → less than ?field_gte=value → greater than or equal ?field_lte=value → less than or equal ?field_like=value → LIKE (contains) ?field_in=v1,v2,v3 → IN
Only fields present in the schema are accepted. Hidden fields are excluded from the allow-list (mirroring ParseSort): building a WHERE predicate on a column the caller can't read turns row-count/result changes into a value-disclosure oracle — an attacker could probe a Hidden column (e.g. a password hash) via ?password_hash_like=… and exfiltrate it prefix by prefix. A Hidden field name is treated as an unknown filter param and never produces a ParsedFilter.
type ParsedSort ¶
ParsedSort represents sort direction for a field.
func ParseSort ¶
ParseSort extracts sort information from query parameters. Supported: ?sort=field (ascending), ?sort=-field (descending).
Hidden fields are excluded from the allow-list: sorting by a hidden column reveals row ordering by a value the caller can't read, which is an information-disclosure path. Unknown fields fail closed with a 400-shaped error rather than being silently ignored — silent drop turns probe attempts into "the API works the same with or without this param" oracles that mask broken client code.