package apijson import ( "fmt" "net/http" "strings" "github.com/micro/go-micro/logger" ) type QueryContext struct { req map[string]interface{} code int nodeTree map[string]*QueryNode nodePathMap map[string]*QueryNode Data interface{} ExtensionValue map[string]string err error explain bool } func NewQueryContext(req map[string]interface{}) *QueryContext { return &QueryContext{ req: req, code: 0, nodeTree: make(map[string]*QueryNode), nodePathMap: make(map[string]*QueryNode), } } func (c *QueryContext) Response() map[string]interface{} { c.doParse() if c.err == nil { c.doQuery() } resultMap := make(map[string]interface{}) resultMap["ok"] = c.code == http.StatusOK resultMap["code"] = c.code if c.err != nil { resultMap["msg"] = c.err.Error() } else { for k, v := range c.nodeTree { //logger.Debugf("response.nodeMap K: %s, V: %v", k, v) resultMap[k] = v.Result() } } return resultMap } func (c *QueryContext) doParse() { //startTime := time.Now().Nanosecond() for key := range c.req { if c.err != nil { return } if key == "@explain" { c.explain = c.req[key].(bool) } else if c.nodeTree[key] == nil { c.parseByKey(key) } } } func (c *QueryContext) doQuery() { for _, n := range c.nodeTree { if c.err != nil { return } n.doQueryData(c) } } func (c *QueryContext) parseByKey(key string) { queryObject := c.req[key] if queryObject == nil { c.err = fmt.Errorf("值不能为空, key: %s, value: %v", key, queryObject) return } if queryMap, ok := queryObject.(map[string]interface{}); !ok { c.err = fmt.Errorf("值类型不对, key: %s, value: %v", key, queryObject) } else { node := NewQueryNode(c, key, key, queryMap) logger.Debugf("parse %s: %+v", key, node) c.nodeTree[key] = node } } func (c *QueryContext) End(code int, msg string) { c.code = code logger.Errorf("发生错误,终止处理, code: %d, msg: %s", code, msg) } func (c *QueryContext) findResult(value string) interface{} { i := strings.LastIndex(value, "/") path := value[0:i] node := c.nodePathMap[path] if node == nil { c.err = fmt.Errorf("关联查询参数有误: %s", value) return nil } if node.running { c.err = fmt.Errorf("有循环依赖") return nil } node.doQueryData(c) if c.err != nil { return nil } if node.CurrentData == nil { logger.Info("查询结果为空,queryPath: " + value) return nil } key := value[i+1:] return node.CurrentData[key] }