Documentation ¶
Index ¶
- Constants
- type AndNode
- type Clause
- type Filter
- type FilterToSpannerFieldColumnType
- type FilterToSpannerFieldConfig
- type FilterToSquirrelSqlFieldColumnType
- type FilterToSquirrelSqlFieldConfig
- type IsNode
- type LiteralNode
- type NestedNode
- type Node
- type NodeMapper
- type NodeType
- type NotNode
- type OrNode
- type ParserOption
- type Pos
- type RangeNode
- type RangeOperator
Constants ¶
const ( FilterToSpannerFieldColumnTypeString = iota FilterToSpannerFieldColumnTypeInt64 FilterToSpannerFieldColumnTypeFloat64 FilterToSpannerFieldColumnTypeBool FilterToSpannerFieldColumnTypeTimestamp )
const ( FilterToSquirrelSqlFieldColumnTypeString = iota FilterToSquirrelSqlFieldColumnTypeInt FilterToSquirrelSqlFieldColumnTypeFloat FilterToSquirrelSqlFieldColumnTypeBool FilterToSquirrelSqlFieldColumnTypeTimestamp )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AndNode ¶
type AndNode struct { NodeType Pos Nodes []Node // The clauses nodes in lexical order. // contains filtered or unexported fields }
AndNode holds multiple sub queries.
type Clause ¶
type Clause struct { Field string // One of the following: `=`, `<`, `<=`, `>`, `>=`, `IN` Operator string // List of values for the clause. // For `IN` operator, this is a list of values to match against. // For other operators, this is a list of one string. Values []string }
func (*Clause) ToSquirrelSql ¶
func (c *Clause) ToSquirrelSql(stmt sq.SelectBuilder, config FilterToSquirrelSqlFieldConfig) (sq.SelectBuilder, error)
type Filter ¶
type Filter struct {
Clauses []Clause
}
func Parse ¶
Parse parses a filter string into a Filter struct. The filter string must not contain any boolean operators, parentheses or nested queries. The filter string must contain only simple clauses of the form "field:value", where all clauses are AND'ed. Optionally, range operators can be enabled, e.g. for expressions involving date ranges. If you need to parse a more complex filter string, use ParseAST instead.
func (Filter) ToSpannerSQL ¶
func (f Filter) ToSpannerSQL(fieldConfigs map[string]FilterToSpannerFieldConfig) ([]string, map[string]any, error)
ToSpannerSQL turns a Filter into a partial StandardSQL statement. It takes a map of fields that are allowed to be queried via this filter (as a user should not be able to query all db columns via a filter). It returns a partial SQL statement that can be added to a WHERE clause, along with associated params. An example follows.
Given a Filter that looks like this:
[(Field: "userId", Operator: "=", Values: []string{"12345"}), (Field: "email", Operator: "=", Values: []string{"john@example.*"})]
and fieldConfigs that looks like this:
{ "userId": (ColumnName: "user_id", ColumnType: FilterToSpannerFieldColumnTypeInt64, AllowPartialMatch: false), "email": (ColumnName: "email", ColumnType: FilterToSpannerFieldColumnTypeString, AllowPartialMatch: true) }
This returns a slice of SQL conditions that can be appended to an existing WHERE clause (make sure to AND these first):
["user_id=@KQL0", "email LIKE @KQL1"]
and params:
{ "@KQL0": int64(12345), "@KQL1": "john@example.%" }
For multi-value fields, the returned SQL conditions will use the IN operator:
[(Field: "team_id", Operator: "IN", Values: []string{"T1", "T2"})] { "team_id": (ColumnName: "user_id", ColumnType: FilterToSpannerFieldColumnTypeString, AllowMultipleValues: true), }
SQL would be:
["team_id IN (@KQL0,@KQL1)"]
and params:
{ "@KQL0": "T1", "@KQL1": "T2" }
Note: The Clause Operator is contextually used/ignored. It only works with INT64, FLOAT64 and TIMESTAMP types currently.
func (Filter) ToSquirrelSql ¶
func (f Filter) ToSquirrelSql(stmt sq.SelectBuilder, fieldConfigs map[string]FilterToSquirrelSqlFieldConfig) (sq.SelectBuilder, error)
type FilterToSpannerFieldColumnType ¶
type FilterToSpannerFieldColumnType int
func (FilterToSpannerFieldColumnType) String ¶
func (c FilterToSpannerFieldColumnType) String() string
type FilterToSpannerFieldConfig ¶
type FilterToSpannerFieldConfig struct { // SQL table column name. Can be omitted if the column name is equal to the key in the fieldConfigs map. ColumnName string // SQL column type. Defaults to FilterToSpannerFieldColumnTypeString. ColumnType FilterToSpannerFieldColumnType // Allow prefix matching when a wildcard (`*`) is present at the end of a string. // Only applicable for FilterToSpannerFieldColumnTypeString. Defaults to false. AllowPrefixMatch bool // Allow multiple values for this field. Defaults to false. AllowMultipleValues bool // A function that takes a string value as provided by the user and converts it to `any` result that matches how it is // stored in the database. This should return an error when the user is providing a value that is illegal for this // particular field. Defaults to using the provided value as-is. MapValue func(string) (any, error) }
type FilterToSquirrelSqlFieldColumnType ¶
type FilterToSquirrelSqlFieldColumnType int
type FilterToSquirrelSqlFieldConfig ¶
type FilterToSquirrelSqlFieldConfig struct { // SQL table column name. Can be omitted if the column name is equal to the key in the fieldConfigs map. ColumnName string // SQL column type. Defaults to FilterToSquirrelSqlFieldColumnTypeString. ColumnType FilterToSquirrelSqlFieldColumnType // Allow prefix matching when a wildcard (`*`) is present at the end of a string. // Only applicable for FilterToSpannerFieldColumnTypeString. Defaults to false. AllowPrefixMatch bool // Allow multiple values for this field. Defaults to false. AllowMultipleValues bool // A function that takes a string value as provided by the user and converts it to string result that matches how it // should be as users' input. This should return an error when the user is providing a value that is illegal or unexpected // for this particular field. Defaults to using the provided value as-is. MapValue func(string) (any, error) // A function that handle parsing the sql statement by itself. // If set, all other fields in the config will be ignored CustomBuilder func(stmt sq.SelectBuilder, operator string, values []string) (sq.SelectBuilder, error) }
type IsNode ¶
type IsNode struct { NodeType Pos Identifier string Value Node // The clauses nodes in lexical order. // contains filtered or unexported fields }
IsNode holds equality check.
type LiteralNode ¶
LiteralNode holds literal value.
func (*LiteralNode) String ¶
func (q *LiteralNode) String() string
type NestedNode ¶
type NestedNode struct { NodeType Pos Expr Node // The clauses nodes in lexical order. // contains filtered or unexported fields }
NestedNode holds nested sub query.
func (*NestedNode) String ¶
func (q *NestedNode) String() string
type Node ¶
type Node interface { Type() NodeType String() string Position() Pos // byte position of start of node in full original input string // contains filtered or unexported methods }
A Node is an element in the parse tree.
type NodeMapper ¶ added in v0.3.4
type NodeMapper struct { TransformIdentifierFunc func(string) string TransformValueFunc func(string) string }
func NewNodeMapper ¶ added in v0.3.4
func NewNodeMapper() NodeMapper
func (NodeMapper) Map ¶ added in v0.3.4
func (m NodeMapper) Map(ast Node) error
type NotNode ¶
type NotNode struct { NodeType Pos Expr Node // Negated node. // contains filtered or unexported fields }
NotNode holds a negated sub query.
type OrNode ¶
type OrNode struct { NodeType Pos Nodes []Node // The clauses nodes in lexical order. // contains filtered or unexported fields }
OrNode holds multiple sub queries.
type ParserOption ¶
type ParserOption func(*parser)
ParserOption is a function that configures a parser.
func DisableComplexExpressions ¶
func DisableComplexExpressions() ParserOption
DisableComplexExpressions disables complex expressions.
func WithMaxComplexity ¶
func WithMaxComplexity(complexity int) ParserOption
WithMaxComplexity sets limit to maximum number of individual clauses separated by boolean operators.
func WithMaxDepth ¶
func WithMaxDepth(depth int) ParserOption
WithMaxDepth sets limit to maximum number of nesting.
type Pos ¶
type Pos int
Pos represents a byte position in the original input text from which this template was parsed.
type RangeNode ¶
type RangeNode struct { NodeType Pos Identifier string Operator RangeOperator Value Node // The clauses nodes in lexical order. // contains filtered or unexported fields }
RangeNode holds range check.
type RangeOperator ¶
type RangeOperator int
const ( RangeOperatorGt RangeOperator = iota RangeOperatorGte RangeOperatorLt RangeOperatorLte )
func (RangeOperator) String ¶
func (o RangeOperator) String() string