|
4 | 4 | "context" |
5 | 5 | "fmt" |
6 | 6 | "github.com/glennliao/apijson-go/config" |
| 7 | + "github.com/gogf/gf/v2/errors/gerror" |
7 | 8 | "github.com/gogf/gf/v2/frame/g" |
8 | 9 | "github.com/gogf/gf/v2/util/gconv" |
9 | 10 | "time" |
@@ -62,80 +63,83 @@ func printNode(n *Node, deep int) { |
62 | 63 |
|
63 | 64 | } |
64 | 65 |
|
65 | | -func analysisRef(p *Node, fetchNodeQueue *[]*Node, fetchNodeQueueWithRef *[]*Node, fetchNodeQueueRefNode *[]*Node) { |
| 66 | +func analysisOrder(prerequisites [][]string) ([]string, error) { |
66 | 67 |
|
67 | | - // 分析依赖关系, 让无依赖的先执行, 然后在执行后续的 |
68 | | - // 需优化调整 更通用的 (目前问题点在于依赖的节点也有依赖时的优先顺序问题) |
69 | | - for _, node := range p.children { |
70 | | - if node.Type == NodeTypeQuery && len(node.refKeyMap) == 0 { |
71 | | - *fetchNodeQueue = append(*fetchNodeQueue, node) |
72 | | - } else { |
73 | | - if node.Type == NodeTypeRef { |
74 | | - *fetchNodeQueueRefNode = append(*fetchNodeQueueRefNode, node) |
75 | | - } else { |
76 | | - *fetchNodeQueueWithRef = append(*fetchNodeQueueWithRef, node) |
77 | | - } |
78 | | - } |
79 | | - //if node.primaryTableKey != "" { |
80 | | - // |
81 | | - //} else { |
82 | | - // |
83 | | - //} |
84 | | - analysisRef(node, fetchNodeQueue, fetchNodeQueueWithRef, fetchNodeQueueRefNode) |
| 68 | + var pointMap = make(map[string]bool) |
| 69 | + for _, prerequisite := range prerequisites { |
| 70 | + pointMap[prerequisite[0]] = true |
| 71 | + pointMap[prerequisite[1]] = true |
85 | 72 | } |
86 | 73 |
|
87 | | -} |
88 | | - |
89 | | -func (q *Query) fetch() { |
90 | | - // 分析依赖关系 |
91 | | - |
92 | | - var fetchNodeQueue []*Node |
93 | | - var fetchNodeQueueWithRef []*Node |
94 | | - var fetchNodeQueueRefNode []*Node |
| 74 | + var pointNum = len(pointMap) |
| 75 | + var edgesMap = make(map[string][]string) |
| 76 | + var indeg = make(map[string]int) |
| 77 | + var result []string |
95 | 78 |
|
96 | | - analysisRef(q.rootNode, &fetchNodeQueue, &fetchNodeQueueWithRef, &fetchNodeQueueRefNode) |
| 79 | + for _, prerequisite := range prerequisites { |
| 80 | + edgesMap[prerequisite[1]] = append(edgesMap[prerequisite[1]], prerequisite[0]) |
| 81 | + indeg[prerequisite[0]]++ |
| 82 | + } |
97 | 83 |
|
98 | | - //fetchNodeQueue = lo.Reverse(fetchNodeQueue) |
99 | | - //fetchNodeQueueWithRef = lo.Reverse(fetchNodeQueueWithRef) |
| 84 | + var queue []string |
100 | 85 |
|
101 | | - //for _, node := range fetchNodeQueueWithRef { |
102 | | - // fmt.Printf("%s\n", node.Path) |
103 | | - // for k, refPath := range node.refKeyMap { |
104 | | - // fmt.Printf("%s -> %s\n", k, refPath) |
105 | | - // } |
106 | | - // fmt.Println("---------------------") |
107 | | - //} |
| 86 | + for point, _ := range pointMap { |
| 87 | + if indeg[point] == 0 { |
| 88 | + queue = append(queue, point) |
| 89 | + } |
| 90 | + } |
108 | 91 |
|
109 | | - fmt.Println("fetch queue") |
110 | | - for _, node := range append(fetchNodeQueue) { |
111 | | - fmt.Printf(" 【%s】 > ", node.Path) |
| 92 | + for len(queue) > 0 { |
| 93 | + var first string |
| 94 | + first, queue = queue[0], queue[1:] |
| 95 | + result = append(result, first) |
| 96 | + for _, point := range edgesMap[first] { |
| 97 | + indeg[point]-- |
| 98 | + if indeg[point] == 0 { |
| 99 | + queue = append(queue, point) |
| 100 | + } |
| 101 | + } |
112 | 102 | } |
113 | | - fmt.Println("") |
114 | 103 |
|
115 | | - for _, node := range append(fetchNodeQueueWithRef) { |
116 | | - fmt.Printf(" 【%s】 > ", node.Path) |
| 104 | + if len(result) != pointNum { |
| 105 | + return nil, gerror.New("依赖循环, 请检查请求") |
117 | 106 | } |
118 | 107 |
|
119 | | - fmt.Println("") |
| 108 | + return result, nil |
120 | 109 |
|
121 | | - for _, node := range append(fetchNodeQueueRefNode) { |
122 | | - fmt.Printf(" 【%s】 > ", node.Path) |
123 | | - } |
| 110 | +} |
124 | 111 |
|
125 | | - fmt.Println("") |
| 112 | +func analysisRef(p *Node, prerequisites *[][]string) { |
126 | 113 |
|
127 | | - for _, node := range fetchNodeQueue { |
128 | | - node.fetch() |
| 114 | + // 分析依赖关系, 让无依赖的先执行, 然后在执行后续的 |
| 115 | + for _, node := range p.children { |
| 116 | + for _, refNode := range node.refKeyMap { |
| 117 | + *prerequisites = append(*prerequisites, []string{node.Path, refNode.node.Path}) |
| 118 | + } |
| 119 | + analysisRef(node, prerequisites) |
129 | 120 | } |
130 | 121 |
|
131 | | - for _, node := range fetchNodeQueueWithRef { |
132 | | - node.fetch() |
| 122 | +} |
| 123 | + |
| 124 | +func (q *Query) fetch() { |
| 125 | + // 分析依赖关系 |
| 126 | + |
| 127 | + var prerequisites [][]string |
| 128 | + analysisRef(q.rootNode, &prerequisites) |
| 129 | + fetchQueue, err := analysisOrder(prerequisites) |
| 130 | + |
| 131 | + if err != nil { |
| 132 | + q.err = err |
133 | 133 | } |
134 | 134 |
|
135 | | - for _, node := range fetchNodeQueueRefNode { |
136 | | - node.fetch() |
| 135 | + fmt.Println("fetch queue") |
| 136 | + for _, path := range fetchQueue { |
| 137 | + fmt.Printf(" 【%s】 > ", path) |
137 | 138 | } |
138 | 139 |
|
| 140 | + for _, path := range fetchQueue { |
| 141 | + q.pathNodes[path].fetch() |
| 142 | + } |
139 | 143 | } |
140 | 144 |
|
141 | 145 | func (q *Query) Result() (g.Map, error) { |
@@ -163,6 +167,10 @@ func (q *Query) Result() (g.Map, error) { |
163 | 167 |
|
164 | 168 | q.fetch() |
165 | 169 |
|
| 170 | + if q.err != nil { |
| 171 | + return nil, err |
| 172 | + } |
| 173 | + |
166 | 174 | resultMap, err := q.rootNode.Result() |
167 | 175 |
|
168 | 176 | if err != nil { |
|
0 commit comments