funcs_obj.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright 2023 EMQ Technologies Co., Ltd.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package function
  15. import (
  16. "fmt"
  17. "github.com/lf-edge/ekuiper/pkg/api"
  18. "github.com/lf-edge/ekuiper/pkg/ast"
  19. )
  20. func registerObjectFunc() {
  21. builtins["keys"] = builtinFunc{
  22. fType: ast.FuncTypeScalar,
  23. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  24. arg := args[0]
  25. if arg, ok := arg.(map[string]interface{}); ok {
  26. list := make([]string, 0, len(arg))
  27. for key := range arg {
  28. list = append(list, key)
  29. }
  30. return list, true
  31. }
  32. return fmt.Errorf("the argument should be map[string]interface{}"), false
  33. },
  34. val: ValidateOneArg,
  35. check: returnNilIfHasAnyNil,
  36. }
  37. builtins["values"] = builtinFunc{
  38. fType: ast.FuncTypeScalar,
  39. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  40. arg := args[0]
  41. if arg, ok := arg.(map[string]interface{}); ok {
  42. list := make([]interface{}, 0, len(arg))
  43. for _, value := range arg {
  44. list = append(list, value)
  45. }
  46. return list, true
  47. }
  48. return fmt.Errorf("the argument should be map[string]interface{}"), false
  49. },
  50. val: ValidateOneArg,
  51. check: returnNilIfHasAnyNil,
  52. }
  53. builtins["object"] = builtinFunc{
  54. fType: ast.FuncTypeScalar,
  55. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  56. keys, ok := args[0].([]interface{})
  57. if !ok {
  58. return fmt.Errorf("first argument should be []string"), false
  59. }
  60. values, ok := args[1].([]interface{})
  61. if !ok {
  62. return fmt.Errorf("second argument should be []interface{}"), false
  63. }
  64. if len(keys) != len(values) {
  65. return fmt.Errorf("the length of the arguments should be same"), false
  66. }
  67. if len(keys) == 0 {
  68. return nil, true
  69. }
  70. m := make(map[string]interface{}, len(keys))
  71. for i, k := range keys {
  72. key, ok := k.(string)
  73. if !ok {
  74. return fmt.Errorf("first argument should be []string"), false
  75. }
  76. m[key] = values[i]
  77. }
  78. return m, true
  79. },
  80. val: func(ctx api.FunctionContext, args []ast.Expr) error {
  81. return ValidateLen(2, len(args))
  82. },
  83. check: returnNilIfHasAnyNil,
  84. }
  85. builtins["zip"] = builtinFunc{
  86. fType: ast.FuncTypeScalar,
  87. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  88. lists, ok := args[0].([]interface{})
  89. if !ok {
  90. return fmt.Errorf("each argument should be [][2]interface{}"), false
  91. }
  92. if len(lists) == 0 {
  93. return nil, true
  94. }
  95. m := make(map[string]interface{}, len(lists))
  96. for _, item := range lists {
  97. a, ok := item.([]interface{})
  98. if !ok {
  99. return fmt.Errorf("each argument should be [][2]interface{}"), false
  100. }
  101. if len(a) != 2 {
  102. return fmt.Errorf("each argument should be [][2]interface{}"), false
  103. }
  104. key, ok := a[0].(string)
  105. if !ok {
  106. return fmt.Errorf("the first element in the list item should be string"), false
  107. }
  108. m[key] = a[1]
  109. }
  110. return m, true
  111. },
  112. val: ValidateOneArg,
  113. check: returnNilIfHasAnyNil,
  114. }
  115. builtins["items"] = builtinFunc{
  116. fType: ast.FuncTypeScalar,
  117. exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
  118. m, ok := args[0].(map[string]interface{})
  119. if !ok {
  120. return fmt.Errorf("first argument should be map[string]interface{}"), false
  121. }
  122. if len(m) < 1 {
  123. return nil, true
  124. }
  125. list := make([]interface{}, 0, len(m))
  126. for k, v := range m {
  127. list = append(list, []interface{}{k, v})
  128. }
  129. return list, true
  130. },
  131. val: ValidateOneArg,
  132. check: returnNilIfHasAnyNil,
  133. }
  134. }