From f7e3ba81acf891944fb26766265f47898dc9fac7 Mon Sep 17 00:00:00 2001 From: Terry Zhao Date: Tue, 21 May 2024 15:25:24 -0700 Subject: [PATCH] add when not present predicate --- go.mod | 2 +- go.sum | 4 ++-- view/extension/init.go | 1 + view/extension/predicates.go | 18 ++++++++++++++++++ view/predicate.go | 22 +++++++++++++++++----- 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 89eaa917..527f0a33 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,7 @@ require ( require ( firebase.google.com/go/v4 v4.14.0 github.com/viant/structology v0.5.6-0.20231127181208-736f8ad06193 - github.com/viant/tagly v0.2.1-0.20240417022938-8b3b65de980b + github.com/viant/tagly v0.2.1-0.20240521205717-55de744e893c github.com/viant/xdatly v0.3.1-0.20240503144018-bce51af60365 github.com/viant/xdatly/extension v0.0.0-20231013204918-ecf3c2edf259 github.com/viant/xdatly/handler v0.0.0-20240503144018-bce51af60365 diff --git a/go.sum b/go.sum index 877e29ff..7ba57282 100644 --- a/go.sum +++ b/go.sum @@ -1118,8 +1118,8 @@ github.com/viant/structology v0.5.6-0.20231127181208-736f8ad06193 h1:wKs4BXSTV0V github.com/viant/structology v0.5.6-0.20231127181208-736f8ad06193/go.mod h1:oGgckfRCArsyzFpRqem+U0EEyzxjoNx3o21MXO43uh0= github.com/viant/structql v0.4.2-0.20240406183616-cff48e18d922 h1:w/h5njGTM1Pxw2WHeYsS391btY+bXr6XK3IdBFecenU= github.com/viant/structql v0.4.2-0.20240406183616-cff48e18d922/go.mod h1:1ko0M6tIUv2nafHo94cnUGG65GmAXYmkEcgeUU/+kCM= -github.com/viant/tagly v0.2.1-0.20240417022938-8b3b65de980b h1:/gjKZOnfZXzIRJSkfOIBP3OmCZSG3D5VimfXG7k/wkg= -github.com/viant/tagly v0.2.1-0.20240417022938-8b3b65de980b/go.mod h1:vV8QgJkhug+X+qyKds8av0fhjD+4u7IhNtowL1KGQ5A= +github.com/viant/tagly v0.2.1-0.20240521205717-55de744e893c h1:j16wc8v05VpZXLaBDqbLZOAjSyN/XrmzjqgcPm6K2FI= +github.com/viant/tagly v0.2.1-0.20240521205717-55de744e893c/go.mod h1:vV8QgJkhug+X+qyKds8av0fhjD+4u7IhNtowL1KGQ5A= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/viant/toolbox v0.34.5/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/viant/toolbox v0.36.0 h1:UYKY3WokI/hn4IBDz8fLe8mYt9YQiJf/q+GCRt7HpUY= diff --git a/view/extension/init.go b/view/extension/init.go index b6456658..7e2fde76 100644 --- a/view/extension/init.go +++ b/view/extension/init.go @@ -117,6 +117,7 @@ func InitRegistry() { PredicateCriteriaIn: NewInCriteriaPredicate(), PredicateCriteriaNotIn: NewNotInCriteriaPredicate(), PredicateWhenPresent: NewWhenPresent(), + PredicateWhenNotPresent: NewWhenNotPresent(), }, }, Docs: docs.New(), diff --git a/view/extension/predicates.go b/view/extension/predicates.go index 5f33d13c..007ea153 100644 --- a/view/extension/predicates.go +++ b/view/extension/predicates.go @@ -35,6 +35,7 @@ const ( PredicateBetween = "between" PredicateDuration = "duration" PredicateWhenPresent = "when_present" + PredicateWhenNotPresent = "when_not_present" ) type ( @@ -427,6 +428,10 @@ func NewWhenPresent() *Predicate { return newWhenPredicate(PredicateWhenPresent) } +func NewWhenNotPresent() *Predicate { + return NewWhenNotPredicate(PredicateWhenNotPresent) +} + func newExistsPredicate(name string, withCriteria bool, negated bool) *Predicate { args := []*predicate.NamedArgument{ { @@ -519,3 +524,16 @@ func newWhenPredicate(name string) *Predicate { }, } } + +func NewWhenNotPredicate(name string) *Predicate { + condition := `#if(!$HasFilterValue) ${Criterion} #end` + return &Predicate{ + Template: &predicate.Template{ + Name: name, + Source: " " + condition, + Args: []*predicate.NamedArgument{ + {Name: "Criterion", Position: 0}, + }, + }, + } +} diff --git a/view/predicate.go b/view/predicate.go index 55b3a2f2..69eb438f 100644 --- a/view/predicate.go +++ b/view/predicate.go @@ -36,7 +36,7 @@ type ( handler codec.PredicateHandler } - predicateEvaluator struct { + PredicateEvaluator struct { ctx *expand.Variable evaluator *expand.Evaluator valueState *expand.NamedVariable @@ -44,7 +44,7 @@ type ( } ) -func (e *predicateEvaluator) Compute(ctx context.Context, value interface{}) (*codec.Criteria, error) { +func (e *PredicateEvaluator) Compute(ctx context.Context, value interface{}) (*codec.Criteria, error) { cuxtomCtx, ok := ctx.Value(expand.PredicateCtx).(*expand.Context) if !ok { panic("not found custom ctx") @@ -68,12 +68,24 @@ func (e *predicateEvaluator) Compute(ctx context.Context, value interface{}) (*c return criteria, nil } -func (e *predicateEvaluator) Evaluate(ctx *expand.Context, state *structology.State, value interface{}) (*expand.State, error) { +func (e *PredicateEvaluator) Evaluate(ctx *expand.Context, state *structology.State, value interface{}) (*expand.State, error) { + + hasValue := value != nil + if value != nil { + switch actual := value.(type) { + case []int: + hasValue = actual != nil + case *int: + hasValue = actual != nil + case *string: + hasValue = actual != nil + } + } return e.evaluator.Evaluate(ctx, expand.WithParameterState(state), expand.WithNamedVariables( e.valueState.New(value), - e.hasValueState.New(value != nil), + e.hasValueState.New(hasValue), ), expand.WithCustomContext(e.ctx), ) @@ -133,7 +145,7 @@ func (p *predicateEvaluatorProvider) new(predicateConfig *extension.PredicateCon Value: dst, } - return &predicateEvaluator{ + return &PredicateEvaluator{ ctx: customCtx, evaluator: p.evaluator, valueState: p.state,