Documentation
¶
Overview ¶
Package gormfilter provides powerful and type-safe filtering capabilities for GORM queries.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ClauseNot ¶
func ClauseNot(exprs ...clause.Expression) clause.Expression
ClauseNot builds a NOT clause that correctly handles De Morgan's laws. This implementation applies negation to expressions with proper OR/AND conversion.
This is based on gorm.io/gorm/clause.Not but uses clause.OrWithSpace for proper negation. See: https://github.com/go-gorm/gorm/pull/7371
func Scope ¶
Scope returns a GORM scope function that applies the given filter to the query. The filter parameter should be a struct with fields matching the model's schema. Fields use filter types from the filter package (filter.String, filter.Int, etc.).
The filter struct can include:
- Field filters using types from the filter package
- Logical operators: And, Or, Not
- Relationship filters (BelongsTo, HasOne)
Example:
type UserFilter struct {
Name *filter.String
Age *filter.Int
Company *CompanyFilter // BelongsTo relationship
Profile *ProfileFilter // HasOne relationship
And []*UserFilter
Or []*UserFilter
Not *UserFilter
}
// Simple filter
db.Scopes(gormfilter.Scope(&UserFilter{
Name: &filter.String{Contains: lo.ToPtr("john"), Fold: true},
})).Find(&users)
// Complex filter with relationships
db.Scopes(gormfilter.Scope(&UserFilter{
Age: &filter.Int{Gte: lo.ToPtr(18)},
Company: &CompanyFilter{
Name: &filter.String{Eq: lo.ToPtr("Tech Corp")},
},
})).Find(&users)
// Logical combinations
db.Scopes(gormfilter.Scope(&UserFilter{
Or: []*UserFilter{
{Age: &filter.Int{Lt: lo.ToPtr(25)}},
{Age: &filter.Int{Gt: lo.ToPtr(60)}},
},
})).Find(&users)
Options:
- WithDisableBelongsTo: Disables filtering by belongs_to relationships
- WithDisableHasOne: Disables filtering by has_one relationships
- WithDisableRelationships: Disables filtering by all relationship types
Types ¶
type FieldColumnFunc ¶ added in v0.9.0
type FieldColumnFunc func(input *FieldColumnInput) (*FieldColumnOutput, error)
FieldColumnFunc builds a column for a given field.
type FieldColumnInput ¶ added in v0.9.0
FieldColumnInput provides context for building a field's column.
type FieldColumnOutput ¶ added in v0.9.0
type FieldColumnOutput struct {
Column any // clause.Column or clause.Expr (for computed expressions like LOWER())
}
FieldColumnOutput specifies the column to use for filtering. Column can be clause.Column or clause.Expr (for computed expressions like LOWER()).
type NotConditions ¶
type NotConditions struct {
Exprs []clause.Expression
}
NotConditions represents a NOT clause with support for proper negation of complex expressions.
func (NotConditions) Build ¶
func (not NotConditions) Build(builder clause.Builder)
type Option ¶
type Option func(*options)
func WithDisableBelongsTo ¶
func WithDisableBelongsTo() Option
WithDisableBelongsTo returns an option that disables filtering by belongs_to relationships. This can be useful when you want to prevent complex subqueries or restrict filtering to direct fields only.
func WithDisableHasOne ¶ added in v0.6.1
func WithDisableHasOne() Option
WithDisableHasOne returns an option that disables filtering by has_one relationships. This can be useful when you want to prevent complex subqueries or restrict filtering to direct fields only.
func WithDisableRelationships ¶ added in v0.6.1
func WithDisableRelationships() Option
WithDisableRelationships returns an option that disables filtering by all relationship types.
func WithFieldColumnHook ¶ added in v0.9.0
func WithFieldColumnHook(hooks ...func(next FieldColumnFunc) FieldColumnFunc) Option
WithFieldColumnHook installs a hook to customize how field columns are built. This allows dynamic column resolution based on field name and filter context (e.g., Fold). Multiple hooks can be chained together.
Example:
// Filter on JSON field: WHERE "snapshot"->>'name' = 'Old Name'
snapshotHook := func(next gormfilter.FieldColumnFunc) gormfilter.FieldColumnFunc {
return func(input *gormfilter.FieldColumnInput) (*gormfilter.FieldColumnOutput, error) {
if input.FieldName == "SnapshotName" {
var column any = clause.Column{Name: `"snapshot"->>'name'`, Raw: true}
if input.Fold {
column = clause.Expr{SQL: "LOWER(?)", Vars: []any{column}}
}
return &gormfilter.FieldColumnOutput{Column: column}, nil
}
return next(input)
}
}
db.Scopes(gormfilter.Scope(&ProductFilter{
Name: &filter.String{Eq: lo.ToPtr("Old Name")},
}, gormfilter.WithFieldColumnHook(snapshotHook)))
type RelationshipInExpr ¶ added in v0.6.1
RelationshipInExpr represents an IN subquery expression for relationship filters (BelongsTo, HasOne)
func (*RelationshipInExpr) Build ¶ added in v0.6.1
func (in *RelationshipInExpr) Build(builder clause.Builder)
func (*RelationshipInExpr) NegationBuild ¶ added in v0.6.1
func (in *RelationshipInExpr) NegationBuild(builder clause.Builder)