Skip to content
Snippets Groups Projects
Commit b42f9cc6 authored by ko_oler's avatar ko_oler
Browse files

Изменить сигнатура функции ConvertToMongo для работы с массивом строк

parent 2d55e02b
No related branches found
No related tags found
No related merge requests found
Subproject commit 63410745d6008eaa9d9b00626b5f5b6891ac9189
Subproject commit 78fe6a1ea7e2fe588e4107bf14ac85293b201163
......@@ -20,44 +20,55 @@ var geoTypes = map[string]string{
"polygon": "$polygon",
}
func ConvertToMongo(ctx context.Context, exp string, env map[string]interface{}, identifierRenameFn func(string) string, ops ...expr.Option) (b bson.M, err error) {
if exp == "" {
type MongoExprConfig struct {
Env map[string]any
IdentifierRenameFn func(s string) string
Ops []expr.Option
}
func ConvertToMongo(ctx context.Context, config *MongoExprConfig, expressions ...string) (b bson.M, err error) {
if len(expressions) == 0 {
return bson.M{}, nil
}
tree, err := parser.Parse(exp)
tree, err := parser.Parse("(" + strings.Join(expressions, ") && (") + ")")
if err != nil {
return nil, err
}
return convertToMongo(ctx, tree, env, identifierRenameFn, ops...)
return convertToMongo(ctx, config, tree)
}
func convertToMongo(ctx context.Context, tree *parser.Tree, env map[string]interface{}, identifierRenameFn func(string) string, ops ...expr.Option) (b bson.M, err error) {
func convertToMongo(ctx context.Context, config *MongoExprConfig, tree *parser.Tree) (b bson.M, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("%v", r)
}
}()
if config == nil {
config = new(MongoExprConfig)
}
env := config.Env
if env == nil {
env = make(map[string]interface{})
}
env[EnvContextKey] = ctx
config := GetDefaultConfig(env)
exprConfig := GetDefaultConfig(env)
for _, op := range ops {
op(config)
for _, op := range config.Ops {
op(exprConfig)
}
env = config.Env.(map[string]interface{})
env = exprConfig.Env.(map[string]interface{})
if len(config.Visitors) >= 0 {
for _, v := range config.Visitors {
if len(exprConfig.Visitors) >= 0 {
for _, v := range exprConfig.Visitors {
ast.Walk(&tree.Node, v)
}
}
c := &compiler{tree: tree, env: env, config: config, identifierRenameFn: identifierRenameFn}
c := &compiler{tree: tree, env: env, config: exprConfig, identifierRenameFn: config.IdentifierRenameFn}
v, ok := c.compile(tree.Node).(bson.M)
if !ok || v == nil {
return nil, fmt.Errorf("invalid expression")
......
......@@ -22,12 +22,14 @@ func TestConvertToMongo(t *testing.T) {
tests := []struct {
name string
eval string
eval any
env map[string]interface{}
wantB bson.M
wantErr bool
}{
{"equal", "s == 3", nil, bson.M{"s": 3}, false},
{"equal (with []string)", []string{"object.space_id == 'sp'", "object.organization_id == 'org'"}, nil, bson.M{"$and": bson.A{bson.M{"object.space_id": "sp"}, bson.M{"object.organization_id": "org"}}}, false},
{"equal (with nil []string)", nil, nil, bson.M{}, false},
{"in array", "s in [1,2,3]", nil, bson.M{"s": bson.M{"$in": []interface{}{1, 2, 3}}}, false},
{"not in array", "s not in [1,2,3]", nil, bson.M{"s": bson.M{"$nin": []interface{}{1, 2, 3}}}, false},
{"exists#1", "exists(s)", nil, bson.M{"s": bson.M{"$exists": true}}, false},
......@@ -80,7 +82,17 @@ func TestConvertToMongo(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotB, err := ConvertToMongo(ctx, tt.eval, tt.env, nil)
var exprs []string
switch v := tt.eval.(type) {
case []string:
exprs = v
case string:
exprs = []string{v}
}
config := &MongoExprConfig{Env: tt.env}
gotB, err := ConvertToMongo(ctx, config, exprs...)
if tt.wantErr {
require.Error(t, err)
return
......@@ -102,8 +114,10 @@ func BenchmarkConvertToMongo(b *testing.B) {
exp := InStringArray("id", ids)
//fmt.Println(len(exp))
config := &MongoExprConfig{Ops: []expr.Option{expr.Patch(&testVisitor{})}}
for i := 0; i < b.N; i++ {
_, _ = ConvertToMongo(ctx, exp, nil, nil, expr.Patch(&testVisitor{}))
_, _ = ConvertToMongo(ctx, config, exp)
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment