mirror of
https://github.com/pocketbase/pocketbase.git
synced 2024-11-28 18:11:17 +02:00
80 lines
2.7 KiB
Go
80 lines
2.7 KiB
Go
package search
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/pocketbase/dbx"
|
|
"github.com/pocketbase/pocketbase/tools/inflector"
|
|
"github.com/pocketbase/pocketbase/tools/list"
|
|
)
|
|
|
|
// ResolverResult defines a single FieldResolver.Resolve() successfully parsed result.
|
|
type ResolverResult struct {
|
|
// Identifier is the plain SQL identifier/column that will be used
|
|
// in the final db expression as left or right operand.
|
|
Identifier string
|
|
|
|
// Params is a map with db placeholder->value pairs that will be added
|
|
// to the query when building both resolved operands/sides in a single expression.
|
|
Params dbx.Params
|
|
|
|
// MultiMatchSubQuery is an optional sub query expression that will be added
|
|
// in addition to the combined ResolverResult expression during build.
|
|
MultiMatchSubQuery dbx.Expression
|
|
|
|
// AfterBuild is an optional function that will be called after building
|
|
// and combining the result of both resolved operands/sides in a single expression.
|
|
AfterBuild func(expr dbx.Expression) dbx.Expression
|
|
}
|
|
|
|
// FieldResolver defines an interface for managing search fields.
|
|
type FieldResolver interface {
|
|
// UpdateQuery allows to updated the provided db query based on the
|
|
// resolved search fields (eg. adding joins aliases, etc.).
|
|
//
|
|
// Called internally by `search.Provider` before executing the search request.
|
|
UpdateQuery(query *dbx.SelectQuery) error
|
|
|
|
// Resolve parses the provided field and returns a properly
|
|
// formatted db identifier (eg. NULL, quoted column, placeholder parameter, etc.).
|
|
Resolve(field string) (*ResolverResult, error)
|
|
}
|
|
|
|
// NewSimpleFieldResolver creates a new `SimpleFieldResolver` with the
|
|
// provided `allowedFields`.
|
|
//
|
|
// Each `allowedFields` could be a plain string (eg. "name")
|
|
// or a regexp pattern (eg. `^\w+[\w\.]*$`).
|
|
func NewSimpleFieldResolver(allowedFields ...string) *SimpleFieldResolver {
|
|
return &SimpleFieldResolver{
|
|
allowedFields: allowedFields,
|
|
}
|
|
}
|
|
|
|
// SimpleFieldResolver defines a generic search resolver that allows
|
|
// only its listed fields to be resolved and take part in a search query.
|
|
//
|
|
// If `allowedFields` are empty no fields filtering is applied.
|
|
type SimpleFieldResolver struct {
|
|
allowedFields []string
|
|
}
|
|
|
|
// UpdateQuery implements `search.UpdateQuery` interface.
|
|
func (r *SimpleFieldResolver) UpdateQuery(query *dbx.SelectQuery) error {
|
|
// nothing to update...
|
|
return nil
|
|
}
|
|
|
|
// Resolve implements `search.Resolve` interface.
|
|
//
|
|
// Returns error if `field` is not in `r.allowedFields`.
|
|
func (r *SimpleFieldResolver) Resolve(field string) (*ResolverResult, error) {
|
|
if !list.ExistInSliceWithRegex(field, r.allowedFields) {
|
|
return nil, fmt.Errorf("Failed to resolve field %q.", field)
|
|
}
|
|
|
|
return &ResolverResult{
|
|
Identifier: "[[" + inflector.Columnify(field) + "]]",
|
|
}, nil
|
|
}
|