diff --git a/pkg/expr/mongo.go b/pkg/expr/mongo.go index bb4187dda74adce707798781b77d23a648db0eb1..5a503a7ee76eaa7a7d0197b955868a298b5fad73 100644 --- a/pkg/expr/mongo.go +++ b/pkg/expr/mongo.go @@ -23,6 +23,7 @@ var geoTypes = map[string]string{ type MongoExprConfig struct { Env map[string]any IdentifierRenameFn func(s string) string + Visitors []ast.Visitor Ops []expr.Option } @@ -55,6 +56,7 @@ func convertToMongo(ctx context.Context, config *MongoExprConfig, tree *parser.T env[EnvContextKey] = ctx exprConfig := GetDefaultConfig(env) + exprConfig.Visitors = config.Visitors for _, op := range config.Ops { op(exprConfig) @@ -62,13 +64,16 @@ func convertToMongo(ctx context.Context, config *MongoExprConfig, tree *parser.T env = exprConfig.Env.(map[string]interface{}) - if len(exprConfig.Visitors) >= 0 { - for _, v := range exprConfig.Visitors { - ast.Walk(&tree.Node, v) - } + c := &compiler{ + tree: tree, + env: env, + config: exprConfig, + identifierRenameFn: config.IdentifierRenameFn, + visitors: config.Visitors, + } + for _, v := range c.visitors { + ast.Walk(&tree.Node, v) } - - 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") @@ -81,6 +86,7 @@ type compiler struct { tree *parser.Tree config *conf.Config identifierRenameFn func(string) string + visitors []ast.Visitor } func (c *compiler) eval(node ast.Node) interface{} { @@ -162,43 +168,43 @@ func (c *compiler) IdentifierNode(node *ast.IdentifierNode) string { func (c *compiler) IntegerNode(node *ast.IntegerNode) int { return node.Value - //t := node.Type() - //if t == nil { + // t := node.Type() + // if t == nil { // c.emitPush(node.Value) // return - //} + // } // - //switch t.Kind() { - //case reflect.Float32: + // switch t.Kind() { + // case reflect.Float32: // c.emitPush(float32(node.Value)) - //case reflect.Float64: + // case reflect.Float64: // c.emitPush(float64(node.Value)) // - //case reflect.Int: + // case reflect.Int: // c.emitPush(int(node.Value)) - //case reflect.Int8: + // case reflect.Int8: // c.emitPush(int8(node.Value)) - //case reflect.Int16: + // case reflect.Int16: // c.emitPush(int16(node.Value)) - //case reflect.Int32: + // case reflect.Int32: // c.emitPush(int32(node.Value)) - //case reflect.Int64: + // case reflect.Int64: // c.emitPush(int64(node.Value)) // - //case reflect.Uint: + // case reflect.Uint: // c.emitPush(uint(node.Value)) - //case reflect.Uint8: + // case reflect.Uint8: // c.emitPush(uint8(node.Value)) - //case reflect.Uint16: + // case reflect.Uint16: // c.emitPush(uint16(node.Value)) - //case reflect.Uint32: + // case reflect.Uint32: // c.emitPush(uint32(node.Value)) - //case reflect.Uint64: + // case reflect.Uint64: // c.emitPush(uint64(node.Value)) // - //default: + // default: // c.emitPush(node.Value) - //} + // } } func (c *compiler) FloatNode(node *ast.FloatNode) float64 { @@ -277,32 +283,32 @@ func (c *compiler) BinaryNode(node *ast.BinaryNode) interface{} { case ">=": return bson.M{c.identifier(node.Left): bson.M{"$gte": c.eval(node.Right)}} - //case "+": + // case "+": // c.compile(node.Left) // c.compile(node.Right) // c.emit(OpAdd) // - //case "-": + // case "-": // c.compile(node.Left) // c.compile(node.Right) // c.emit(OpSubtract) // - //case "*": + // case "*": // c.compile(node.Left) // c.compile(node.Right) // c.emit(OpMultiply) // - //case "/": + // case "/": // c.compile(node.Left) // c.compile(node.Right) // c.emit(OpDivide) // - //case "%": + // case "%": // c.compile(node.Left) // c.compile(node.Right) // c.emit(OpModulo) // - //case "**": + // case "**": // c.compile(node.Left) // c.compile(node.Right) // c.emit(OpExponent) @@ -454,26 +460,26 @@ func (c *compiler) CallNode(node *ast.CallNode) interface{} { return bson.M{v: bson.M{"$regex": fmt.Sprintf(".*%s$", regexp.QuoteMeta(t)), "$options": "i"}} } panic("unsupported function") - //for _, arg := range node.Arguments { + // for _, arg := range node.Arguments { // c.compile(arg) - //} - //op := OpCall - //if node.Fast { + // } + // op := OpCall + // if node.Fast { // op = OpCallFast - //} - //c.emit(op, c.makeConstant(Call{Name: node.Name, Size: len(node.Arguments)})...) + // } + // c.emit(op, c.makeConstant(Call{Name: node.Name, Size: len(node.Arguments)})...) } func (c *compiler) BuiltinNode(node *ast.BuiltinNode) interface{} { panic("unsupported builin node") - //switch node.Name { - //case "len": + // switch node.Name { + // case "len": // c.compile(node.Arguments[0]) // c.emit(OpLen) // c.emit(OpRot) // c.emit(OpPop) // - //case "all": + // case "all": // c.compile(node.Arguments[0]) // c.emit(OpBegin) // var loopBreak int @@ -486,7 +492,7 @@ func (c *compiler) BuiltinNode(node *ast.BuiltinNode) interface{} { // c.patchJump(loopBreak) // c.emit(OpEnd) // - //case "none": + // case "none": // c.compile(node.Arguments[0]) // c.emit(OpBegin) // var loopBreak int @@ -500,7 +506,7 @@ func (c *compiler) BuiltinNode(node *ast.BuiltinNode) interface{} { // c.patchJump(loopBreak) // c.emit(OpEnd) // - //case "any": + // case "any": // c.compile(node.Arguments[0]) // c.emit(OpBegin) // var loopBreak int @@ -513,7 +519,7 @@ func (c *compiler) BuiltinNode(node *ast.BuiltinNode) interface{} { // c.patchJump(loopBreak) // c.emit(OpEnd) // - //case "one": + // case "one": // count := c.makeConstant("count") // c.compile(node.Arguments[0]) // c.emit(OpBegin) @@ -530,7 +536,7 @@ func (c *compiler) BuiltinNode(node *ast.BuiltinNode) interface{} { // c.emit(OpEqual) // c.emit(OpEnd) // - //case "filter": + // case "filter": // count := c.makeConstant("count") // c.compile(node.Arguments[0]) // c.emit(OpBegin) @@ -550,7 +556,7 @@ func (c *compiler) BuiltinNode(node *ast.BuiltinNode) interface{} { // c.emit(OpEnd) // c.emit(OpArray) // - //case "map": + // case "map": // c.compile(node.Arguments[0]) // c.emit(OpBegin) // size := c.emitLoop(func() { @@ -560,7 +566,7 @@ func (c *compiler) BuiltinNode(node *ast.BuiltinNode) interface{} { // c.emit(OpEnd) // c.emit(OpArray) // - //case "count": + // case "count": // count := c.makeConstant("count") // c.compile(node.Arguments[0]) // c.emit(OpBegin) @@ -575,12 +581,12 @@ func (c *compiler) BuiltinNode(node *ast.BuiltinNode) interface{} { // c.emit(OpLoad, count...) // c.emit(OpEnd) // - //default: + // default: // panic(fmt.Sprintf("unknown builtin %v", node.Name)) - //} + // } } -//func (c *compiler) emitLoop(body func()) []byte { +// func (c *compiler) emitLoop(body func()) []byte { // i := c.makeConstant("i") // size := c.makeConstant("size") // array := c.makeConstant("array") @@ -607,7 +613,7 @@ func (c *compiler) BuiltinNode(node *ast.BuiltinNode) interface{} { // c.emit(OpPop) // // return size -//} +// } func (c *compiler) ClosureNode(node *ast.ClosureNode) interface{} { return c.compile(node.Node) @@ -615,25 +621,25 @@ func (c *compiler) ClosureNode(node *ast.ClosureNode) interface{} { func (c *compiler) PointerNode(node *ast.PointerNode) interface{} { panic("unsupported pointer node") - //c.emit(OpLoad, c.makeConstant("array")...) - //c.emit(OpLoad, c.makeConstant("i")...) - //c.emit(OpIndex) + // c.emit(OpLoad, c.makeConstant("array")...) + // c.emit(OpLoad, c.makeConstant("i")...) + // c.emit(OpIndex) } func (c *compiler) ConditionalNode(node *ast.ConditionalNode) interface{} { panic("unsupported conditional node") - //c.compile(node.Cond) - //otherwise := c.emit(OpJumpIfFalse, c.placeholder()...) + // c.compile(node.Cond) + // otherwise := c.emit(OpJumpIfFalse, c.placeholder()...) // - //c.emit(OpPop) - //c.compile(node.Exp1) - //end := c.emit(OpJump, c.placeholder()...) + // c.emit(OpPop) + // c.compile(node.Exp1) + // end := c.emit(OpJump, c.placeholder()...) // - //c.patchJump(otherwise) - //c.emit(OpPop) - //c.compile(node.Exp2) + // c.patchJump(otherwise) + // c.emit(OpPop) + // c.compile(node.Exp2) // - //c.patchJump(end) + // c.patchJump(end) } func (c *compiler) VariableDeclaratorNode(node *ast.VariableDeclaratorNode) int { @@ -642,28 +648,28 @@ func (c *compiler) VariableDeclaratorNode(node *ast.VariableDeclaratorNode) int func (c *compiler) ArrayNode(node *ast.ArrayNode) interface{} { panic("unsupported array node") - //for _, node := range node.Nodes { + // for _, node := range node.Nodes { // c.compile(node) - //} + // } // - //c.emitPush(len(node.Nodes)) - //c.emit(OpArray) + // c.emitPush(len(node.Nodes)) + // c.emit(OpArray) } func (c *compiler) MapNode(node *ast.MapNode) interface{} { panic("unsupported map node") - //for _, pair := range node.Pairs { + // for _, pair := range node.Pairs { // c.compile(pair) - //} + // } // - //c.emitPush(len(node.Pairs)) - //c.emit(OpMap) + // c.emitPush(len(node.Pairs)) + // c.emit(OpMap) } func (c *compiler) PairNode(node *ast.PairNode) interface{} { panic("unsupported pair node") - //c.compile(node.Key) - //c.compile(node.Value) + // c.compile(node.Key) + // c.compile(node.Value) } // handleLenNode получает узел AST и возвращает запрос для mongo, @@ -731,6 +737,9 @@ func (c *compiler) handleTryNode(node *ast.CallNode) (result interface{}) { if err != nil { panic(err) } + for _, v := range c.visitors { + ast.Walk(&tree.Node, v) + } subcompiler := &compiler{tree: tree, env: c.env, config: c.config, identifierRenameFn: c.identifierRenameFn} result = subcompiler.compile(tree.Node).(bson.M) return diff --git a/pkg/schema/schema.go b/pkg/schema/schema.go index 4fec4c174684745be718abf4c2a595f7fe1ae3fe..bb91b4203cf6c7e44991a41f5bdc31294aeedb4d 100644 --- a/pkg/schema/schema.go +++ b/pkg/schema/schema.go @@ -111,6 +111,11 @@ func (s Schema) SetMetadata(md map[string]string) *Schema { return &s } +func (f Schema) SetSingleLocale(r bool) *Schema { + f.SingleLocale = r + return &f +} + func (s *Schema) ConvertTypes() error { b, err := s.MarshalJSON() if err != nil {