project_operator.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package plans
  2. import (
  3. "context"
  4. "encoding/json"
  5. "engine/xsql"
  6. "fmt"
  7. "strconv"
  8. "strings"
  9. )
  10. type ProjectPlan struct {
  11. Fields xsql.Fields
  12. }
  13. func (pp *ProjectPlan) Apply(ctx context.Context, data interface{}) interface{} {
  14. var input map[string]interface{}
  15. if d, ok := data.(map[string]interface{}); !ok {
  16. fmt.Printf("Expect map[string]interface{} type.\n")
  17. return nil
  18. } else {
  19. input = d
  20. }
  21. var result = make(map[string]interface{})
  22. ve := &xsql.ValuerEval{Valuer: xsql.MultiValuer(xsql.MapValuer(input), &xsql.FunctionValuer{}, &xsql.WildcardValuer{Data: input})}
  23. for _, f := range pp.Fields {
  24. v := ve.Eval(f.Expr)
  25. if val, ok := v.(map[string]interface{}); ok { //It should be the asterisk in fields list.
  26. result = val
  27. break
  28. } else {
  29. result[assignName(f.Name, f.AName, result)] = v
  30. }
  31. }
  32. if ret, err := json.Marshal(result); err == nil {
  33. return ret
  34. } else {
  35. fmt.Printf("Found error: %v.\n", err)
  36. return nil
  37. }
  38. }
  39. const DEFAULT_FIELD_NAME_PREFIX string = "rengine_field_"
  40. func assignName(name, alias string, fields map[string] interface{}) string {
  41. if result := strings.Trim(alias, " "); result != "" {
  42. return result
  43. }
  44. if result := strings.Trim(name, " "); result != "" {
  45. return result
  46. }
  47. for i := 0; i < 2048; i++ {
  48. key := DEFAULT_FIELD_NAME_PREFIX + strconv.Itoa(i)
  49. if _, ok := fields[key]; !ok {
  50. return key
  51. }
  52. }
  53. fmt.Printf("Cannot assign a default field name.\n")
  54. return ""
  55. }