query.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package query
  2. import (
  3. "regexp"
  4. "github.com/porter-dev/porter/cli/cmd/switchboard/query/jsonpath"
  5. )
  6. // PopulateQuery reads through config to detect queries. If a query is found, the data
  7. // is queried and the relevant field is populated in the config. This method is recursive.
  8. func PopulateQueries(config map[string]interface{}, data map[string]interface{}) (map[string]interface{}, error) {
  9. iter := queryIterator{data, make([]error, 0)}
  10. res := iter.iterMap(config)
  11. return res, nil
  12. }
  13. type queryIterator struct {
  14. data map[string]interface{}
  15. errors []error
  16. }
  17. func (q *queryIterator) iterSlice(arr []interface{}) []interface{} {
  18. res := make([]interface{}, 0)
  19. for _, arrVal := range arr {
  20. res = append(res, q.iterInterface(arrVal))
  21. }
  22. return res
  23. }
  24. func (q *queryIterator) iterMap(mapVal map[string]interface{}) map[string]interface{} {
  25. res := make(map[string]interface{})
  26. for key, val := range mapVal {
  27. res[key] = q.iterInterface(val)
  28. }
  29. return res
  30. }
  31. func (q *queryIterator) iterInterface(val interface{}) interface{} {
  32. switch val.(type) {
  33. case []interface{}:
  34. return q.iterSlice(val.([]interface{}))
  35. case map[string]interface{}:
  36. return q.iterMap(val.(map[string]interface{}))
  37. case string:
  38. // TODO: move out to higher-level func
  39. bracesReg := regexp.MustCompile(`\{(.+)\}`)
  40. if bracesReg.MatchString(val.(string)) {
  41. // get the query value from data
  42. res, err := jsonpath.GetResult(q.data, val.(string))
  43. if err != nil {
  44. q.errors = append(q.errors, err)
  45. return val
  46. }
  47. return res
  48. }
  49. return val
  50. default:
  51. return val
  52. }
  53. }