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.

113 lines
2.5 KiB

package apijson
import (
"fmt"
"net/http"
"strings"
)
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]
}