github.com/MontFerret/ferret@v0.18.0/pkg/runtime/expressions/operators/like.go (about)

     1  package operators
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/gobwas/glob"
     7  	"github.com/pkg/errors"
     8  
     9  	"github.com/MontFerret/ferret/pkg/runtime/core"
    10  	"github.com/MontFerret/ferret/pkg/runtime/values"
    11  	"github.com/MontFerret/ferret/pkg/runtime/values/types"
    12  )
    13  
    14  type LikeOperator struct {
    15  	*baseOperator
    16  	negate bool
    17  }
    18  
    19  func NewLikeOperator(
    20  	src core.SourceMap,
    21  	left core.Expression,
    22  	right core.Expression,
    23  	negate bool,
    24  ) (*LikeOperator, error) {
    25  	if left == nil {
    26  		return nil, core.Error(core.ErrMissedArgument, "left expression")
    27  	}
    28  
    29  	if right == nil {
    30  		return nil, core.Error(core.ErrMissedArgument, "right expression")
    31  	}
    32  
    33  	return &LikeOperator{&baseOperator{src, left, right}, negate}, nil
    34  }
    35  
    36  func (operator *LikeOperator) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) {
    37  	left, err := operator.left.Exec(ctx, scope)
    38  
    39  	if err != nil {
    40  		return values.False, core.SourceError(operator.src, err)
    41  	}
    42  
    43  	right, err := operator.right.Exec(ctx, scope)
    44  
    45  	if err != nil {
    46  		return values.False, core.SourceError(operator.src, err)
    47  	}
    48  
    49  	return operator.Eval(ctx, left, right)
    50  }
    51  
    52  func (operator *LikeOperator) Eval(_ context.Context, left, right core.Value) (core.Value, error) {
    53  	err := core.ValidateType(right, types.String)
    54  
    55  	if err != nil {
    56  		// TODO: Return the error? AQL just returns false
    57  		return values.False, nil
    58  	}
    59  
    60  	err = core.ValidateType(left, types.String)
    61  
    62  	if err != nil {
    63  		// TODO: Return the error? AQL just returns false
    64  		return values.False, nil
    65  	}
    66  
    67  	r, err := glob.Compile(right.String())
    68  
    69  	if err != nil {
    70  		return nil, errors.Wrap(err, "invalid glob pattern")
    71  	}
    72  
    73  	result := r.Match(left.String())
    74  
    75  	if operator.negate {
    76  		return values.NewBoolean(!result), nil
    77  	}
    78  
    79  	return values.NewBoolean(result), nil
    80  }