package query import ( "path/filepath" "strings" "github.com/glennliao/apijson-go/consts" "github.com/glennliao/apijson-go/model" ) type structNode struct { node *Node } func newStructNode(n *Node) *structNode { return &structNode{node: n} } func (h *structNode) parse() { n := h.node for _, childNode := range n.children { childNode.parse() } if n.isList { // []èç¹ hasPrimary := false // æ¯å¦åå¨ä¸»æ¥è¯¢è¡¨ for _, child := range n.children { if child.err != nil { n.err = child.err return } if child.primaryTableKey != "" { if hasPrimary { n.err = consts.NewValidReqErr("node must only one primary table: " + n.Path) return } hasPrimary = true n.primaryTableKey = filepath.Base(child.Key) child.page = n.page } } if n.Key == consts.ListKeySuffix && !hasPrimary { n.err = consts.NewValidReqErr("node must have primary table: " + n.Path) return } } } func (h *structNode) fetch() { n := h.node // ç®åç»æèç¹ç»è£ æ°æ®å¨result, å¦æè¢«ä¾èµçæ¯ç»è£ åç, åæ æ³æ¥è¯¢ã å¦éå°æ¤æ åµåç if n.isList && n.needTotal { n.total = n.children[n.primaryTableKey].total } } func (h *structNode) result() { n := h.node if n.isList { var retList []model.Map var primaryList []model.Map if n.children[n.primaryTableKey].ret != nil { primaryList = n.children[n.primaryTableKey].ret.([]model.Map) for i := 0; i < len(primaryList); i++ { pItem := primaryList[i] item := model.Map{ n.primaryTableKey: pItem, } // éåç»è£ æ°æ®, åç»èè使ç¨å«çæ¹æ¡ä¼å (ææªç®å使ç¨mapçid->item ,主è¦èèå¤å段é®é¢) for childK, childNode := range n.children { if childNode.primaryTableKey == "" { if childNode.ret != nil { var resultList []model.Map for _, depRetItem := range childNode.ret.([]model.Map) { match := true for refK, refNode := range childNode.refKeyMap { if pItem[refNode.column] != depRetItem[refK] { match = false break } } if match { resultList = append(resultList, depRetItem) } } if len(resultList) > 0 { if strings.HasSuffix(childK, consts.ListKeySuffix) { item[childK] = resultList } else { item[childK] = resultList[0] } } } } } retList = append(retList, item) } } n.ret = retList if len(n.ret.([]model.Map)) == 0 { n.ret = []model.Map{} } } else { retMap := model.Map{} for k, node := range n.children { var err error if strings.HasSuffix(k, consts.RefKeySuffix) { k = k[0 : len(k)-1] } if strings.HasSuffix(k, consts.FunctionsKeySuffix) { k = k[0 : len(k)-2] } // å¢å alias ç¨æ¥éå½åè¿åçkeyï¼é¿å åç«¯è°æ´åå¼ if node.req[consts.Alias] != nil { k = node.req[consts.Alias].(string) } retMap[k], err = node.Result() if node.Type == NodeTypeFunc && retMap[k] == nil { delete(retMap, k) } if err != nil { n.err = err } } if len(retMap) > 0 && n.simpleReqVal == "" { n.ret = retMap } else { n.ret = n.simpleReqVal } } } func (h *structNode) nodeType() int { return NodeTypeStruct }