You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
2.1 KiB

5 years ago
  1. package json
  2. import (
  3. "strconv"
  4. "github.com/chrislusf/seaweedfs/weed/query/sqltypes"
  5. "github.com/tidwall/gjson"
  6. "github.com/tidwall/match"
  7. )
  8. type Query struct {
  9. Field string
  10. Op string
  11. Value string
  12. }
  13. func QueryJson(jsonLine string, projections []string, query Query) (passedFilter bool, values []sqltypes.Value) {
  14. if filterJson(jsonLine, query) {
  15. passedFilter = true
  16. fields := gjson.GetMany(jsonLine, projections...)
  17. for _, f := range fields {
  18. values = append(values, sqltypes.MakeTrusted(sqltypes.Type(f.Type), sqltypes.StringToBytes(f.Raw)))
  19. }
  20. return
  21. }
  22. return false, nil
  23. }
  24. func filterJson(jsonLine string, query Query) bool {
  25. value := gjson.Get(jsonLine, query.Field)
  26. // copied from gjson.go queryMatches() function
  27. rpv := query.Value
  28. if !value.Exists() {
  29. return false
  30. }
  31. if query.Op == "" {
  32. // the query is only looking for existence, such as:
  33. // friends.#(name)
  34. // which makes sure that the array "friends" has an element of
  35. // "name" that exists
  36. return true
  37. }
  38. switch value.Type {
  39. case gjson.String:
  40. switch query.Op {
  41. case "=":
  42. return value.Str == rpv
  43. case "!=":
  44. return value.Str != rpv
  45. case "<":
  46. return value.Str < rpv
  47. case "<=":
  48. return value.Str <= rpv
  49. case ">":
  50. return value.Str > rpv
  51. case ">=":
  52. return value.Str >= rpv
  53. case "%":
  54. return match.Match(value.Str, rpv)
  55. case "!%":
  56. return !match.Match(value.Str, rpv)
  57. }
  58. case gjson.Number:
  59. rpvn, _ := strconv.ParseFloat(rpv, 64)
  60. switch query.Op {
  61. case "=":
  62. return value.Num == rpvn
  63. case "!=":
  64. return value.Num != rpvn
  65. case "<":
  66. return value.Num < rpvn
  67. case "<=":
  68. return value.Num <= rpvn
  69. case ">":
  70. return value.Num > rpvn
  71. case ">=":
  72. return value.Num >= rpvn
  73. }
  74. case gjson.True:
  75. switch query.Op {
  76. case "=":
  77. return rpv == "true"
  78. case "!=":
  79. return rpv != "true"
  80. case ">":
  81. return rpv == "false"
  82. case ">=":
  83. return true
  84. }
  85. case gjson.False:
  86. switch query.Op {
  87. case "=":
  88. return rpv == "false"
  89. case "!=":
  90. return rpv != "false"
  91. case "<":
  92. return rpv == "true"
  93. case "<=":
  94. return true
  95. }
  96. }
  97. return false
  98. }