funcs_str.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package xsql
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/emqx/kuiper/common"
  6. "regexp"
  7. "strings"
  8. "unicode"
  9. "unicode/utf8"
  10. )
  11. func strCall(name string, args []interface{}) (interface{}, bool) {
  12. switch name {
  13. case "concat":
  14. var b bytes.Buffer
  15. for _, arg := range args {
  16. b.WriteString(common.ToStringAlways(arg))
  17. }
  18. return b.String(), true
  19. case "endswith":
  20. arg0, arg1 := common.ToStringAlways(args[0]), common.ToStringAlways(args[1])
  21. return strings.HasSuffix(arg0, arg1), true
  22. case "indexof":
  23. arg0, arg1 := common.ToStringAlways(args[0]), common.ToStringAlways(args[1])
  24. return strings.Index(arg0, arg1), true
  25. case "length":
  26. arg0 := common.ToStringAlways(args[0])
  27. return utf8.RuneCountInString(arg0), true
  28. case "lower":
  29. arg0 := common.ToStringAlways(args[0])
  30. return strings.ToLower(arg0), true
  31. case "lpad":
  32. arg0 := common.ToStringAlways(args[0])
  33. arg1, err := common.ToInt(args[1], common.STRICT)
  34. if err != nil {
  35. return err, false
  36. }
  37. return strings.Repeat(" ", arg1) + arg0, true
  38. case "ltrim":
  39. arg0 := common.ToStringAlways(args[0])
  40. return strings.TrimLeftFunc(arg0, unicode.IsSpace), true
  41. case "numbytes":
  42. arg0 := common.ToStringAlways(args[0])
  43. return len(arg0), true
  44. case "format_time":
  45. arg0, err := common.InterfaceToTime(args[0], "")
  46. if err != nil {
  47. return err, false
  48. }
  49. arg1 := common.ToStringAlways(args[1])
  50. if s, err := common.FormatTime(arg0, arg1); err == nil {
  51. return s, true
  52. } else {
  53. return err, false
  54. }
  55. case "regexp_matches":
  56. arg0, arg1 := common.ToStringAlways(args[0]), common.ToStringAlways(args[1])
  57. if matched, err := regexp.MatchString(arg1, arg0); err != nil {
  58. return err, false
  59. } else {
  60. return matched, true
  61. }
  62. case "regexp_replace":
  63. arg0, arg1, arg2 := common.ToStringAlways(args[0]), common.ToStringAlways(args[1]), common.ToStringAlways(args[2])
  64. if re, err := regexp.Compile(arg1); err != nil {
  65. return err, false
  66. } else {
  67. return re.ReplaceAllString(arg0, arg2), true
  68. }
  69. case "regexp_substr":
  70. arg0, arg1 := common.ToStringAlways(args[0]), common.ToStringAlways(args[1])
  71. if re, err := regexp.Compile(arg1); err != nil {
  72. return err, false
  73. } else {
  74. return re.FindString(arg0), true
  75. }
  76. case "rpad":
  77. arg0 := common.ToStringAlways(args[0])
  78. arg1, err := common.ToInt(args[1], common.STRICT)
  79. if err != nil {
  80. return err, false
  81. }
  82. return arg0 + strings.Repeat(" ", arg1), true
  83. case "rtrim":
  84. arg0 := common.ToStringAlways(args[0])
  85. return strings.TrimRightFunc(arg0, unicode.IsSpace), true
  86. case "substring":
  87. arg0 := common.ToStringAlways(args[0])
  88. arg1, err := common.ToInt(args[1], common.STRICT)
  89. if err != nil {
  90. return err, false
  91. }
  92. if len(args) > 2 {
  93. arg2, err := common.ToInt(args[2], common.STRICT)
  94. if err != nil {
  95. return err, false
  96. }
  97. return arg0[arg1:arg2], true
  98. } else {
  99. return arg0[arg1:], true
  100. }
  101. case "startswith":
  102. arg0, arg1 := common.ToStringAlways(args[0]), common.ToStringAlways(args[1])
  103. return strings.HasPrefix(arg0, arg1), true
  104. case "split_value":
  105. arg0, arg1 := common.ToStringAlways(args[0]), common.ToStringAlways(args[1])
  106. ss := strings.Split(arg0, arg1)
  107. v, _ := common.ToInt(args[2], common.STRICT)
  108. if v > (len(ss) - 1) {
  109. return fmt.Errorf("%d out of index array (size = %d)", v, len(ss)), false
  110. } else {
  111. return ss[v], true
  112. }
  113. case "trim":
  114. arg0 := common.ToStringAlways(args[0])
  115. return strings.TrimSpace(arg0), true
  116. case "upper":
  117. arg0 := common.ToStringAlways(args[0])
  118. return strings.ToUpper(arg0), true
  119. default:
  120. return fmt.Errorf("unknown string function name %s", name), false
  121. }
  122. }