Documentation
¶
Index ¶
- Constants
- Variables
- func AddParentSubqueryContext(ctx context.Context, inf *ExpressionInfo) context.Context
- func GetLookup(inf *ExpressionInfo, lookupName string, lhs any, args []any) (func(sb *strings.Builder) []any, error)
- func IsSubqueryContext(ctx context.Context) bool
- func MakeSubqueryContext(ctx context.Context) context.Context
- func RegisterCastType(castType CastType, entry CastFuncEntry, drivers ...driver.Driver)
- func RegisterFunc(funcName string, ...)
- func RegisterLookup(Lookup Lookup)
- func RegisterTransforms(transforms ...LookupTransform)
- func StatementParserArg(which string, data any) any
- type AliasField
- type BaseLookup
- func (l *BaseLookup) Arity() (min, max int)
- func (l *BaseLookup) Drivers() []driver.Driver
- func (l *BaseLookup) Name() string
- func (l *BaseLookup) NormalizeArgs(inf *ExpressionInfo, values []any) ([]any, error)
- func (l *BaseLookup) Resolve(inf *ExpressionInfo, lhsResolved ResolvedExpression, values []any) func(sb *strings.Builder) []any
- type BaseTransform
- type CaseExpression
- func (c *CaseExpression) Clone() Expression
- func (c *CaseExpression) Default(value any) *CaseExpression
- func (c *CaseExpression) Resolve(inf *ExpressionInfo) Expression
- func (c *CaseExpression) SQL(sb *strings.Builder) []any
- func (c *CaseExpression) Then(value any) *CaseExpression
- func (c *CaseExpression) When(keyOrExpr interface{}, vals ...any) *CaseExpression
- type CastFuncEntry
- type CastType
- type ClauseExpression
- type ExprGroup
- func (g *ExprGroup) And(exprs ...Expression) ClauseExpression
- func (g *ExprGroup) Clone() Expression
- func (g *ExprGroup) IsNot() bool
- func (g *ExprGroup) Not(not bool) ClauseExpression
- func (g *ExprGroup) Operator() ExprOp
- func (g *ExprGroup) Or(exprs ...Expression) ClauseExpression
- func (g *ExprGroup) Resolve(inf *ExpressionInfo) Expression
- func (g *ExprGroup) SQL(sb *strings.Builder) []any
- func (g *ExprGroup) Unwrap() []Expression
- type ExprNode
- func (e *ExprNode) And(exprs ...Expression) ClauseExpression
- func (e *ExprNode) Clone() Expression
- func (e *ExprNode) IsNot() bool
- func (e *ExprNode) Not(not bool) ClauseExpression
- func (e *ExprNode) Or(exprs ...Expression) ClauseExpression
- func (e *ExprNode) Resolve(inf *ExpressionInfo) Expression
- func (e *ExprNode) SQL(sb *strings.Builder) []any
- type ExprOp
- type Expression
- type ExpressionBuilder
- type ExpressionInfo
- type ExpressionLookupInfo
- type ExpressionStatement
- type FieldResolver
- type Function
- type InLookup
- type IsNullLookup
- type Join
- type JoinCondition
- type JoinType
- type LogicalExpression
- type LogicalLookup
- type LogicalNamedExpressionFunc
- func AVG(expr ...any) LogicalNamedExpressionFunc
- func COALESCE(expr ...any) LogicalNamedExpressionFunc
- func CONCAT(expr ...any) LogicalNamedExpressionFunc
- func COUNT(expr ...any) LogicalNamedExpressionFunc
- func DATE(expr any) LogicalNamedExpressionFunc
- func DATE_FORMAT(expr any, format string) LogicalNamedExpressionFunc
- func EXISTS(expr any) LogicalNamedExpressionFunc
- func LENGTH(expr any) LogicalNamedExpressionFunc
- func LOCALTIMESTAMP() LogicalNamedExpressionFunc
- func LOWER(expr any) LogicalNamedExpressionFunc
- func MAX(expr ...any) LogicalNamedExpressionFunc
- func MIN(expr ...any) LogicalNamedExpressionFunc
- func NOW() LogicalNamedExpressionFunc
- func SUBSTR(expr any, start, length any) LogicalNamedExpressionFunc
- func SUM(expr ...any) LogicalNamedExpressionFunc
- func UPPER(expr any) LogicalNamedExpressionFunc
- func UTCNOW() LogicalNamedExpressionFunc
- type LogicalOp
- type Lookup
- type LookupExpression
- type LookupField
- type LookupFilter
- type LookupTransform
- type ModelMeta
- type NamedExpression
- type OrderBy
- type PatternLookup
- type QueryInformation
- type RangeLookup
- type RawExpr
- type RawNamedExpression
- type ResolvedExpression
- type ResolvedField
- type StatementParser
- type String
- type TableColumn
- type VirtualField
- type WhenExpression
Constants ¶
const SELF_TABLE = "SELF" // the name of the self table, used in expressions
Variables ¶
var ( ErrCastTypeNotImplemented errors.Error = errors.New( "CastTypeNotImplemented", "cast type is not implemented", ) ErrCastTypeNoColumnProvided errors.Error = errors.New( "CastTypeNoColumnProvided", "cast type requires a column to be provided", ) )
var ( CastString = newCastFunc(CastTypeString) CastText = newCastFunc(CastTypeText) CastInt = newCastFunc(CastTypeInt) CastFloat = newCastFunc(CastTypeFloat) CastBool = newCastFunc(CastTypeBool) CastDate = newCastFunc(CastTypeDate) CastTime = newCastFunc(CastTypeTime) CastBytes = newCastFunc(CastTypeBytes) CastDecimal = newCastFunc(CastTypeDecimal) CastJSON = newCastFunc(CastTypeJSON) CastUUID = newCastFunc(CastTypeUUID) CastNull = newCastFunc(CastTypeNull) CastArray = newCastFunc(CastTypeArray) )
var ( ErrLookupNotFound errors.Error = errors.New("LookupNotFound", "lookup not found") ErrTransformNotFound errors.Error = errors.New("TransformNotFound", "transform not found") ErrLookupArgsInvalid errors.Error = errors.New("LookupArgsInvalid", "lookup arguments invalid") )
var PARSER = &statement{ Field: &statementParser{ typ: "field", pattern: `\!\[([a-zA-Z][a-zA-Z0-9_.-]*)\]`, rawtext: func(in []string) string { return in[1] }, resolve: func(nodeIndex int, typIndex int, in []string, info *ExpressionInfo, args []any, data any) (string, []any, error) { var fieldName = in[1] info.SupportsWhereAlias = false info.SupportsAsExpr = false var resolvedField = info.ResolveExpressionField(fieldName) return resolvedField.SQLText, resolvedField.SQLArgs, nil }, }, Table: &statementParser{ typ: "table", pattern: `(?:(?i)table)\(([a-zA-Z][a-zA-Z0-9_.-]*)\)`, rawtext: func(in []string) string { return in[1] }, resolve: func(nodeIndex int, typIndex int, in []string, info *ExpressionInfo, args []any, data any) (string, []any, error) { var fieldPath = in[1] if strings.EqualFold(fieldPath, SELF_TABLE) { var meta = attrs.GetModelMeta(info.Model) var defs = meta.Definitions() return info.QuoteIdentifier(defs.TableName()), []any{}, nil } var _, field, _, err = info.Resolver.Resolve(fieldPath, info) if err != nil { return "", []any{}, fmt.Errorf( "error when walking fields: %w", err, ) } var rel = field.Rel() if rel == nil { return "", []any{}, fmt.Errorf( "field %q is not a relation, cannot resolve table name", fieldPath, ) } var ( current = rel.Model() defs = current.FieldDefs() tableName = defs.TableName() lhs_tableName = info.QuoteIdentifier(tableName) rhs_tableAlias = info.QuoteIdentifier(info.Resolver.Alias().GetTableAlias( defs.TableName(), fieldPath, )) ) return fmt.Sprintf("%s AS %s", lhs_tableName, rhs_tableAlias), []any{}, nil }, }, Value: &statementParser{ typ: "value", pattern: `(?:\?\[([0-9]+)\])|\?`, rawtext: func(in []string) string { return "?" }, resolve: func(nodeIndex int, typIndex int, in []string, info *ExpressionInfo, args []any, data any) (string, []any, error) { var valIdx = 0 if len(in) > 1 && in[1] != "" { var err error valIdx, err = strconv.Atoi(in[1]) if err != nil { return "", []any{}, fmt.Errorf("invalid index %q in statement: %w", in[1], err) } valIdx-- } else { valIdx = typIndex } if valIdx < 0 || valIdx >= len(args) { return "", nil, fmt.Errorf("index %d out of range in statement for %d arguments", valIdx, len(args)) } var val = args[valIdx] if expr, ok := val.(Expression); ok { var exprStr strings.Builder var exprParams = expr.Resolve(info).SQL(&exprStr) return exprStr.String(), exprParams, nil } return "?", []any{val}, nil }, }, Expr: &expressionParser{ statementParser: statementParser{ typ: "expr", pattern: `(?:(?i)expr)\(((?:[a-zA-Z][a-zA-Z0-9_.-]*|[0-9]*))\)`, rawtext: func(in []string) string { return in[1] }, resolve: func(nodeIndex int, typIndex int, in []string, info *ExpressionInfo, args []any, data any) (string, []any, error) { if data == nil { return "", nil, fmt.Errorf("expression data is nil for expr statement") } var exprData, ok = data.(*expressionData) if !ok { return "", nil, fmt.Errorf("invalid expression data type for expr statement") } var ( exprId = in[1] expr Expression ) if unicode.IsDigit(rune(exprId[0])) { var idx, err = strconv.Atoi(exprId) if err != nil { return "", nil, fmt.Errorf("invalid expression index %q: %w", exprId, err) } if idx < 0 || idx >= len(exprData._list) { return "", nil, fmt.Errorf("expression index %d out of range for %d expressions", idx, len(exprData._list)) } expr = exprData._list[idx] goto buildExpression } expr, ok = exprData._map[exprId] if !ok { return "", nil, fmt.Errorf("expression %q not found in data", exprId) } buildExpression: var exprStr strings.Builder var exprParams = expr. Resolve(info). SQL(&exprStr) return exprStr.String(), exprParams, nil }, }, }, }
Functions ¶
func AddParentSubqueryContext ¶
func AddParentSubqueryContext(ctx context.Context, inf *ExpressionInfo) context.Context
func GetLookup ¶
func GetLookup(inf *ExpressionInfo, lookupName string, lhs any, args []any) (func(sb *strings.Builder) []any, error)
GetLookup retrieves a lookup function based on the provided expression info, lookup name, inner expression, and arguments. It returns a function that can be used to build a SQL string with the lookup applied. The LHS will need to be either an Expression (RESOLVED ALREADY!) or a sql `table`.`column` pair.
func IsSubqueryContext ¶
func RegisterCastType ¶
func RegisterCastType(castType CastType, entry CastFuncEntry, drivers ...driver.Driver)
func RegisterFunc ¶
func RegisterLookup ¶
func RegisterLookup(Lookup Lookup)
func RegisterTransforms ¶
func RegisterTransforms(transforms ...LookupTransform)
func StatementParserArg ¶
StatementParserArg creates a parserArg for the given type and data.
a parserArg is a special case used in ExpressionStatement.Resolve to pass additional data to a registered parser.
Types ¶
type AliasField ¶
A field can adhere to this interface to indicate that the field should be aliased when generating the SQL for the field.
For example: this is used in annotations to alias the field name.
type BaseLookup ¶
type BaseLookup struct {
AllowedDrivers []driver.Driver
Identifier LookupFilter
ArgMin int
ArgMax int
Normalize func(any) any
ResolveFunc func(inf *ExpressionInfo, lhsResolved ResolvedExpression, values []any) LookupExpression
}
func (*BaseLookup) Arity ¶
func (l *BaseLookup) Arity() (min, max int)
func (*BaseLookup) Drivers ¶
func (l *BaseLookup) Drivers() []driver.Driver
func (*BaseLookup) Name ¶
func (l *BaseLookup) Name() string
func (*BaseLookup) NormalizeArgs ¶
func (l *BaseLookup) NormalizeArgs(inf *ExpressionInfo, values []any) ([]any, error)
func (*BaseLookup) Resolve ¶
func (l *BaseLookup) Resolve(inf *ExpressionInfo, lhsResolved ResolvedExpression, values []any) func(sb *strings.Builder) []any
type BaseTransform ¶
type BaseTransform struct {
AllowedDrivers []driver.Driver
// Transforms []string
// Lookups []string
Identifier string
Transform func(inf *ExpressionInfo, lhsResolved ResolvedExpression) (ResolvedExpression, error)
}
func (*BaseTransform) Drivers ¶
func (t *BaseTransform) Drivers() []driver.Driver
func (*BaseTransform) Name ¶
func (t *BaseTransform) Name() string
func (*BaseTransform) Resolve ¶
func (t *BaseTransform) Resolve(inf *ExpressionInfo, lhsResolved ResolvedExpression) (ResolvedExpression, error)
type CaseExpression ¶
type CaseExpression struct {
// contains filtered or unexported fields
}
func Case ¶
func Case(cases ...any) *CaseExpression
func (*CaseExpression) Clone ¶
func (c *CaseExpression) Clone() Expression
func (*CaseExpression) Default ¶
func (c *CaseExpression) Default(value any) *CaseExpression
func (*CaseExpression) Resolve ¶
func (c *CaseExpression) Resolve(inf *ExpressionInfo) Expression
func (*CaseExpression) Then ¶
func (c *CaseExpression) Then(value any) *CaseExpression
func (*CaseExpression) When ¶
func (c *CaseExpression) When(keyOrExpr interface{}, vals ...any) *CaseExpression
type CastFuncEntry ¶
type ClauseExpression ¶
type ClauseExpression interface {
Expression
IsNot() bool
Not(b bool) ClauseExpression
And(...Expression) ClauseExpression
Or(...Expression) ClauseExpression
}
func Express ¶
func Express(key interface{}, vals ...interface{}) []ClauseExpression
type ExprGroup ¶
type ExprGroup struct {
// contains filtered or unexported fields
}
ExprGroup
func (*ExprGroup) And ¶
func (g *ExprGroup) And(exprs ...Expression) ClauseExpression
func (*ExprGroup) Clone ¶
func (g *ExprGroup) Clone() Expression
func (*ExprGroup) Not ¶
func (g *ExprGroup) Not(not bool) ClauseExpression
func (*ExprGroup) Or ¶
func (g *ExprGroup) Or(exprs ...Expression) ClauseExpression
func (*ExprGroup) Resolve ¶
func (g *ExprGroup) Resolve(inf *ExpressionInfo) Expression
func (*ExprGroup) Unwrap ¶
func (g *ExprGroup) Unwrap() []Expression
type ExprNode ¶
type ExprNode struct {
// contains filtered or unexported fields
}
func Q ¶
func Q(fieldLookup LookupFilter, value ...any) *ExprNode
func (*ExprNode) And ¶
func (e *ExprNode) And(exprs ...Expression) ClauseExpression
func (*ExprNode) Clone ¶
func (e *ExprNode) Clone() Expression
func (*ExprNode) Not ¶
func (e *ExprNode) Not(not bool) ClauseExpression
func (*ExprNode) Or ¶
func (e *ExprNode) Or(exprs ...Expression) ClauseExpression
func (*ExprNode) Resolve ¶
func (e *ExprNode) Resolve(inf *ExpressionInfo) Expression
type ExprOp ¶
type ExprOp string
ExprOp represents the expression operator to use in a query.
It is used to combine multiple expressions in a logical expression.
type Expression ¶
type Expression interface {
ResolvedExpression
Clone() Expression
Resolve(inf *ExpressionInfo) Expression
}
func Raw ¶
func Raw(statement string, value ...any) Expression
func V ¶
func V(v any, unsafe ...bool) Expression
V is a shorthand for Value, allowing for a more concise syntax. See Value for more information.
func Value ¶
func Value(v any, unsafe ...bool) Expression
Value is a function that creates a value expression. It is used to represent a value in SQL queries, allowing for both safe and unsafe usage. It can be used like so:
Value("some value") // safe usage
Value("some value", true) // unsafe usage, will not use placeholders
The unsafe usage allows for direct insertion of values into the SQL query, which can be dangerous if not used carefully.
func Values ¶
func Values(vs ...any) Expression
Values creates a values expression from a slice of values. It is used to represent multiple values in SQL queries, allowing for both safe and unsafe usage. It can be used like so:
Values([]any{"value1", "value2"})
type ExpressionBuilder ¶
type ExpressionBuilder interface {
BuildExpression() Expression
}
type ExpressionInfo ¶
type ExpressionInfo struct {
// Driver is the driver used to execute the query.
Driver driver.Driver
// Model is the base model of the queryset.
Model attrs.Definer
// Resolver is the field resolver used to resolve fields in the queryset.
Resolver FieldResolver
// Placeholder is the placeholder to use in the query.
//
// It is used to format the placeholders in the query.
Placeholder string
// FormatField is a function that formats the field for the SQL query.
//
// It takes a TableColumn and returns the formatted field as a string
// and a slice of possible args that can be used in the query.
FormatField func(*alias.Generator, *TableColumn) (string, []any)
// Quote is a function that quotes the given string for use in a SQL query.
Quote func(string) string
// QuoteIdentifier is a function that quotes the given identifier for use in a SQL query.
//
// It should be used to quote table names, column names, and other identifiers such as aliases.
//
// It should only be used for advanced use cases, such as when creating custom expressions
// or when there is no other way to format an identifier (see [ExpressionStatement.Resolve] for example).
QuoteIdentifier func(string) string
// Lookups provides information about how to format the lookups
// used in the query.
Lookups ExpressionLookupInfo
// ForUpdate specifies if the expression is used in an UPDATE statement
// or UPDATE- like statement.
//
// This will automatically append "= ?" to the SQL TableColumn statement
ForUpdate bool
// SupportsWhereExpressionAlias indicates if the database supports WHERE expressions with aliases.
SupportsWhereAlias bool
// SupportsAsExpr indicates if the current method of building expressions support aliasing the expression.
SupportsAsExpr bool
// Annotations is a map of queryset annotations (fields).
Annotations *orderedmap.OrderedMap[string, attrs.Field]
}
func ParentFromSubqueryContext ¶
func ParentFromSubqueryContext(ctx context.Context) (*ExpressionInfo, bool)
func (*ExpressionInfo) ResolveExpressionField ¶
func (inf *ExpressionInfo) ResolveExpressionField(fieldName string) *ResolvedField
type ExpressionLookupInfo ¶
type ExpressionLookupInfo struct {
// PrepForLikeQuery is a function that prepares the value for a LIKE query.
//
// It takes any value and returns a string that is properly formatted and
// escaped for use in a LIKE query.
PrepForLikeQuery func(any) string
// FormatLookupCol is a function that formats the left-hand side and right-hand side of
// a lookup operation in the query.
//
// It takes the operator and the left-hand side value and returns a formatted string.
// This is used to format the left-hand side of an operator in the query for iexact, icontains, etc.
//
// The default compiler has a format function for the following operators:
//
// - iexact
// - icontains
// - istartswith
// - iendswith
FormatLookupCol func(string, string) string
// LogicalOpRHS is a map of logical operators to functions that format the right-hand side of the operator.
//
// It takes the logical operator and the right-hand side value and returns a formatted string.
//
// The defualt compiler has logical operators for:
//
// - EQ
// - NE
// - GT
// - LT
// - GTE
// - LTE
// - ADD
// - SUB
// - MUL
// - DIV
// - MOD
// - BITAND
// - BITOR
// - BITXOR
// - BITLSH
// - BITRSH
// - BITNOT
LogicalOpRHS map[LogicalOp]func(rhs string, value []any) (string, []any)
// Operators is a map of lookup operations to format strings.
//
// It is used to format the operators in the query.
//
// Use ExpressionInfo.FormatOp(...) to format the operator.
//
// The default compiler has operators for:
//
// - iexact
// - contains
// - icontains
// - regex
// - iregex
// - startswith
// - endswith
// - istartswith
// - iendswith
OperatorsRHS map[string]string
// PatternOps is a map of pattern operators to format strings.
//
// It is used to format operators when the operator is used as
// an expression in a pattern match, such as 'contains' or 'icontains'.
//
// Use ExpressionInfo.PatternOp(...) to format the pattern operator.
//
// The default compiler supports pattern operators for:
//
// - contains
// - icontains
// - startswith
// - endswith
// - istartswith
// - iendswith
PatternOpsRHS map[string]string
}
func (*ExpressionLookupInfo) FormatLogicalOpRHS ¶
func (*ExpressionLookupInfo) FormatOpRHS ¶
func (inf *ExpressionLookupInfo) FormatOpRHS(op string, fmtArgs ...any) string
func (*ExpressionLookupInfo) PatternOpRHS ¶
func (inf *ExpressionLookupInfo) PatternOpRHS(op string, fmtArgs ...any) string
type ExpressionStatement ¶
type ExpressionStatement struct {
Statement string
Values []any
// contains filtered or unexported fields
}
func ParseExprStatement ¶
func ParseExprStatement(statement string, value []any) *ExpressionStatement
The statement should contain placeholders for the fields and values, which will be replaced with the actual values.
The placeholders for fields should be in the format ![FieldName], and the placeholders for values should be in the format ?[Index], or the values should use the regular SQL placeholder directly (database driver dependent).
Example usage:
stmt := ParseExprStatement(
"SELECT * FROM ![Table] WHERE ![Field1] = ?[0] AND ![Field2] = ?[1] AND EXPR(MyExpression)",
"users", 42, "active",
expr.PARSER.Expressions(map[string]expr.Expression{
"MyExpression": expr.Q("Field2", "MyTitle")
})
)
func (*ExpressionStatement) Clone ¶
func (s *ExpressionStatement) Clone() *ExpressionStatement
func (*ExpressionStatement) Raw ¶
func (s *ExpressionStatement) Raw(which string) []string
func (*ExpressionStatement) Resolve ¶
func (s *ExpressionStatement) Resolve(inf *ExpressionInfo) *ExpressionStatement
func (*ExpressionStatement) SQL ¶
func (s *ExpressionStatement) SQL() (string, []any)
type FieldResolver ¶
type FieldResolver interface {
Alias() *alias.Generator
Peek() QueryInformation
Context() context.Context
Resolve(fieldName string, inf *ExpressionInfo) (model attrs.Definer, field attrs.FieldDefinition, col *TableColumn, err error)
}
type Function ¶
type Function struct {
// contains filtered or unexported fields
}
func (*Function) Clone ¶
func (e *Function) Clone() Expression
func (*Function) Resolve ¶
func (e *Function) Resolve(inf *ExpressionInfo) Expression
type InLookup ¶
type InLookup struct {
BaseLookup
}
func (*InLookup) NormalizeArgs ¶
func (l *InLookup) NormalizeArgs(inf *ExpressionInfo, values []any) ([]any, error)
func (*InLookup) Resolve ¶
func (l *InLookup) Resolve(inf *ExpressionInfo, resolvedExpression ResolvedExpression, values []any) func(sb *strings.Builder) []any
type IsNullLookup ¶
type IsNullLookup struct {
BaseLookup
}
func (*IsNullLookup) Arity ¶
func (l *IsNullLookup) Arity() (min, max int)
func (*IsNullLookup) NormalizeArgs ¶
func (l *IsNullLookup) NormalizeArgs(inf *ExpressionInfo, values []any) ([]any, error)
func (*IsNullLookup) Resolve ¶
func (l *IsNullLookup) Resolve(inf *ExpressionInfo, resolvedExpression ResolvedExpression, values []any) func(sb *strings.Builder) []any
type Join ¶
type Join interface {
TableName() string
TableAlias() string
Type() JoinType
Condition() JoinCondition
}
type JoinCondition ¶
type JoinCondition interface {
// LHS returns the left-hand side of the join condition.
LHS() TableColumn
// RHS returns the right-hand side of the join condition.
RHS() TableColumn
// Op returns the operator used in the join condition.
Op() LogicalOp
// NextCondition returns the next join condition, if any.
NextCondition() JoinCondition
}
type JoinType ¶
type JoinType string
JoinType represents the type of join to use in a query.
It is used to specify how to join two tables in a query.
type LogicalExpression ¶
type LogicalExpression interface {
Expression
Scope(LogicalOp, Expression) LogicalExpression
EQ(key interface{}, vals ...interface{}) LogicalExpression
NE(key interface{}, vals ...interface{}) LogicalExpression
GT(key interface{}, vals ...interface{}) LogicalExpression
LT(key interface{}, vals ...interface{}) LogicalExpression
GTE(key interface{}, vals ...interface{}) LogicalExpression
LTE(key interface{}, vals ...interface{}) LogicalExpression
ADD(key interface{}, vals ...interface{}) LogicalExpression
SUB(key interface{}, vals ...interface{}) LogicalExpression
MUL(key interface{}, vals ...interface{}) LogicalExpression
DIV(key interface{}, vals ...interface{}) LogicalExpression
MOD(key interface{}, vals ...interface{}) LogicalExpression
BITAND(key interface{}, vals ...interface{}) LogicalExpression
BITOR(key interface{}, vals ...interface{}) LogicalExpression
BITXOR(key interface{}, vals ...interface{}) LogicalExpression
BITLSH(key interface{}, vals ...interface{}) LogicalExpression
BITRSH(key interface{}, vals ...interface{}) LogicalExpression
BITNOT(key interface{}, vals ...interface{}) LogicalExpression
}
func Logical ¶
func Logical(expr ...any) LogicalExpression
type LogicalLookup ¶
type LogicalLookup struct {
BaseLookup
Operator LogicalOp
}
func (*LogicalLookup) NormalizeArgs ¶
func (l *LogicalLookup) NormalizeArgs(inf *ExpressionInfo, values []any) ([]any, error)
func (*LogicalLookup) Resolve ¶
func (l *LogicalLookup) Resolve(inf *ExpressionInfo, lhsResolved ResolvedExpression, values []any) func(sb *strings.Builder) []any
type LogicalNamedExpressionFunc ¶
type LogicalNamedExpressionFunc interface {
NamedExpression
LogicalExpression
}
func AVG ¶
func AVG(expr ...any) LogicalNamedExpressionFunc
func COALESCE ¶
func COALESCE(expr ...any) LogicalNamedExpressionFunc
func CONCAT ¶
func CONCAT(expr ...any) LogicalNamedExpressionFunc
func COUNT ¶
func COUNT(expr ...any) LogicalNamedExpressionFunc
func DATE ¶
func DATE(expr any) LogicalNamedExpressionFunc
func DATE_FORMAT ¶
func DATE_FORMAT(expr any, format string) LogicalNamedExpressionFunc
func EXISTS ¶
func EXISTS(expr any) LogicalNamedExpressionFunc
func LENGTH ¶
func LENGTH(expr any) LogicalNamedExpressionFunc
func LOCALTIMESTAMP ¶
func LOCALTIMESTAMP() LogicalNamedExpressionFunc
func LOWER ¶
func LOWER(expr any) LogicalNamedExpressionFunc
func MAX ¶
func MAX(expr ...any) LogicalNamedExpressionFunc
func MIN ¶
func MIN(expr ...any) LogicalNamedExpressionFunc
func NOW ¶
func NOW() LogicalNamedExpressionFunc
func SUBSTR ¶
func SUBSTR(expr any, start, length any) LogicalNamedExpressionFunc
func SUM ¶
func SUM(expr ...any) LogicalNamedExpressionFunc
func UPPER ¶
func UPPER(expr any) LogicalNamedExpressionFunc
func UTCNOW ¶
func UTCNOW() LogicalNamedExpressionFunc
type LogicalOp ¶
type LogicalOp string
LogicalOp represents the logical operator to use in a query.
It is used to compare two values in a logical expression. The logical operators are used in the WHERE clause of a SQL query, or inside of queryset join conditions.
const ( EQ LogicalOp = "=" NE LogicalOp = "!=" GT LogicalOp = ">" LT LogicalOp = "<" GTE LogicalOp = ">=" LTE LogicalOp = "<=" IN LogicalOp = "IN" ADD LogicalOp = "+" SUB LogicalOp = "-" MUL LogicalOp = "*" DIV LogicalOp = "/" MOD LogicalOp = "%" BITAND LogicalOp = "&" BITOR LogicalOp = "|" BITXOR LogicalOp = "^" BITLSH LogicalOp = "<<" BITRSH LogicalOp = ">>" BITNOT LogicalOp = "~" )
func (LogicalOp) Clone ¶
func (op LogicalOp) Clone() Expression
func (LogicalOp) Resolve ¶
func (op LogicalOp) Resolve(*ExpressionInfo) Expression
type Lookup ¶
type Lookup interface {
// returns the drivers that support this lookup
// if empty, the lookup is supported by all drivers
Drivers() []driver.Driver
// name of the lookup
Name() string
// number of arguments the lookup expects, or -1 for variable arguments
Arity() (min, max int)
// normalize the arguments for the lookup
NormalizeArgs(inf *ExpressionInfo, value []any) ([]any, error)
// Resolve resolves the lookup for the given field and value
// and generates an expression for the lookup.
Resolve(inf *ExpressionInfo, lhsResolved ResolvedExpression, args []any) LookupExpression
}
type LookupExpression ¶
type LookupField ¶
type LookupField interface {
attrs.FieldDefinition
AllowedTransforms() []string
AllowedLookups() []string
}
type LookupFilter ¶
type LookupFilter = string
const ( LOOKUP_EXACT LookupFilter = "exact" LOOKUP_NOT LookupFilter = "not" LOOKUP_GT LookupFilter = "gt" LOOKUP_LT LookupFilter = "lt" LOOKUP_GTE LookupFilter = "gte" LOOKUP_LTE LookupFilter = "lte" LOOKUP_BITAND LookupFilter = "bitand" LOOKUP_BITOR LookupFilter = "bitor" LOOKUP_BITXOR LookupFilter = "bitxor" LOOKUP_BITLSH LookupFilter = "bitlsh" LOOKUP_BITRSH LookupFilter = "bitrsh" LOOKUP_BITNOT LookupFilter = "bitnot" LOOKUP_IEXACT LookupFilter = "iexact" LOOKUP_CONTAINS LookupFilter = "contains" LOOKUP_ICONTANS LookupFilter = "icontains" LOOKUP_STARTSWITH LookupFilter = "startswith" LOOKUP_ISTARTSWITH LookupFilter = "istartswith" LOOKUP_IENDSWITH LookupFilter = "iendswith" LOOKUP_ENDSWITH LookupFilter = "endswith" LOOKUP_IN LookupFilter = "in" LOOKUP_ISNULL LookupFilter = "isnull" LOOKUP_RANGE LookupFilter = "range" DEFAULT_LOOKUP = LOOKUP_EXACT )
type LookupTransform ¶
type LookupTransform interface {
// returns the drivers that support this transform
// if empty, the transform is supported by all drivers
Drivers() []driver.Driver
// name of the transform
Name() string
// Resolves the expression and generates a new expressionq
Resolve(inf *ExpressionInfo, lhsResolved ResolvedExpression) (ResolvedExpression, error)
}
type NamedExpression ¶
type NamedExpression interface {
Expression
FieldName() string
}
func As ¶
func As(name string, expr Expression) NamedExpression
As creates a NamedExpression with a specified field name and an expression.
It is used to give a name to an expression, which can be useful for annotations, or for updating fields in a model using [Expression]s.
func Chain ¶
func Chain(expr ...any) NamedExpression
func F ¶
func F(statement any, value ...any) NamedExpression
F creates a new RawNamedExpression or chainExpr with the given statement and values. It parses the statement to extract the fields and values, and returns a pointer to the new RawNamedExpression.
The first field in the statement is used as the field name for the expression, and the rest of the fields are used as placeholders for the values.
The statement should contain placeholders for the fields and values, which will be replaced with the actual values.
The placeholders for fields should be in the format ![FieldName], and the placeholders for values should be in the format ?[Index], or the values should use the regular SQL placeholder directly (database driver dependent).
Example usage:
# sets the field name to the first field found in the statement, I.E. ![Age]:
expr := F("![Age] + ?[1] + ![Height] + ?[2] * ?[1]", 3, 4)
fmt.Println(expr.SQL()) // prints: "table.age + ? + table.height + ? * ?"
fmt.Println(expr.Args()) // prints: [3, 4, 3]
# sets the field name to the first field found in the statement, I.E. ![Height]:
expr := F("? + ? + ![Height] + ? * ?", 4, 5, 6, 7)
fmt.Println(expr.SQL()) // prints: "? + ? + table.height + ? * ?"
fmt.Println(expr.Args()) // prints: [4, 5, 6, 7]
func Field ¶
func Field(fld string) NamedExpression
func OuterRef ¶
func OuterRef(fld string) NamedExpression
type OrderBy ¶
type OrderBy struct {
Column TableColumn // The field to order by
Desc bool
}
OrderBy represents an order by clause in a query.
It contains the table to order by, the field to order by, an optional alias for the field, and a boolean indicating whether to order in descending order.
It is used to specify how to order the results of a query.
type PatternLookup ¶
type PatternLookup struct {
BaseLookup
Pattern string
}
func (*PatternLookup) Arity ¶
func (l *PatternLookup) Arity() (min, max int)
func (*PatternLookup) NormalizeArgs ¶
func (l *PatternLookup) NormalizeArgs(inf *ExpressionInfo, value []any) ([]any, error)
func (*PatternLookup) Resolve ¶
func (l *PatternLookup) Resolve(inf *ExpressionInfo, resolvedExpression ResolvedExpression, values []any) func(sb *strings.Builder) []any
type QueryInformation ¶
type QueryInformation struct {
Meta ModelMeta
Select []attrs.FieldDefinition
GroupBy []attrs.FieldDefinition
Joins []Join
Where []ClauseExpression
Having []ClauseExpression
Unions []FieldResolver
OrderBy []OrderBy
Limit int
Offset int
ForUpdate bool
Distinct bool
}
type RangeLookup ¶
type RangeLookup struct {
BaseLookup
}
func (*RangeLookup) Arity ¶
func (l *RangeLookup) Arity() (min, max int)
func (*RangeLookup) Resolve ¶
func (l *RangeLookup) Resolve(inf *ExpressionInfo, resolvedExpression ResolvedExpression, values []any) func(sb *strings.Builder) []any
type RawExpr ¶
type RawExpr = RawNamedExpression
RawExpr is a function expression for SQL queries. It is used to represent a function call in SQL queries.
It can be used like so:
RawExpr{
// Represent the SQL function call, with each %s being replaced by the corresponding field in fields.
Statement: `SUBSTR(TRIM(%s, " "), 0, 2) = ?``,
// The fields to be used in the SQL function call. Each field will be replaced by the corresponding value in args.
Fields: []string{"myField"},
// The arguments to be used in the SQL function call. Each argument will be replaced by the corresponding value in args.
Params: []any{"ab"},
}
type RawNamedExpression ¶
type RawNamedExpression struct {
Statement *ExpressionStatement // The statement to be executed, containing placeholders for fields and values.
Field string
// contains filtered or unexported fields
}
func (*RawNamedExpression) Clone ¶
func (e *RawNamedExpression) Clone() Expression
func (*RawNamedExpression) FieldName ¶
func (e *RawNamedExpression) FieldName() string
func (*RawNamedExpression) Resolve ¶
func (e *RawNamedExpression) Resolve(inf *ExpressionInfo) Expression
type ResolvedExpression ¶
type ResolvedField ¶
type StatementParser ¶
type StatementParser interface {
// return the type / identifier of the statement parser, e.g. "field", "table", "value", "expr"
Type() string
// should return a value created by StatementParserArg of type parserArg
Data(v any) any
// Compiled returns the compiled regex for the statement parser
Compiled() *regexp.Regexp
// CompiledAbs returns the compiled regex for the statement parser with anchors
CompiledAbs() *regexp.Regexp
// RawText returns the raw text of the statement parser, given the matched input, I.E. ![FieldName] -> FieldName
RawText(in []string) string
// Resolve resolves the statement parser, given the matched input, the expression info, the arguments and any additional data
Resolve(nodesIndex int, typIndex int, in []string, info *ExpressionInfo, args []any, data any) (string, []any, error)
}
type String ¶
type String string
StringExpr is a string type which implements the Expression interface. It is used to represent a string value in SQL queries.
It can be used like so, and supports no arguments:
StringExpr("a = b")
func (String) Clone ¶
func (e String) Clone() Expression
func (String) Resolve ¶
func (e String) Resolve(inf *ExpressionInfo) Expression
type TableColumn ¶
type TableColumn struct {
// The table or alias to use in the join condition
// If this is set, the FieldColumn must be specified
TableOrAlias string
// The alias for the field in the join condition.
FieldAlias string
// RawSQL is the raw SQL to use in the join condition
RawSQL string
// The field or column to use in the join condition
FieldColumn attrs.FieldDefinition
// ForUpdate specifies if the field should be used in an UPDATE statement
// This will automatically append "= ?" to the SQL statement
ForUpdate bool
// The value to use for the placeholder if the field column is not specified
Values []any
}
func (*TableColumn) Validate ¶
func (c *TableColumn) Validate() error
type VirtualField ¶
type VirtualField interface {
attrs.FieldDefinition
SQL(inf *ExpressionInfo) (string, []any)
}
A field can adhere to this interface to indicate that the field should be rendered as SQL.
For example: this is used in fields.ExpressionField to render the expression as SQL.
type WhenExpression ¶
type WhenExpression = *when
func When ¶
func When(keyOrExpr interface{}, vals ...any) WhenExpression