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
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]
|
|
}
|