-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexplain.go
80 lines (69 loc) · 1.4 KB
/
explain.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package anystore
import (
"sort"
"strings"
"zombiezen.com/go/sqlite"
)
func scanExplainStmt(stmt *sqlite.Stmt) ([]string, error) {
var es = &explainString{}
for {
hasRow, stepErr := stmt.Step()
if stepErr != nil {
return nil, stepErr
}
if !hasRow {
break
}
es.addRow(explainRow{
id: stmt.ColumnInt64(0),
parent: stmt.ColumnInt64(1),
detail: stmt.ColumnText(3),
})
}
return es.Result(), nil
}
type explainRow struct {
id int64
parent int64
detail string
}
type explainString struct {
byParent map[int64][]explainRow
buf []string
}
func (es *explainString) addRow(r explainRow) {
if es.byParent == nil {
es.byParent = make(map[int64][]explainRow)
}
es.byParent[r.parent] = append(es.byParent[r.parent], r)
}
func (es *explainString) String() string {
es.buf = es.buf[:0]
es.string(0, 0)
return strings.Join(es.buf, "\n")
}
func (es *explainString) Result() []string {
es.buf = es.buf[:0]
es.string(0, 0)
return es.buf
}
func (es *explainString) string(parent, nest int64) {
if _, ok := es.byParent[parent]; !ok {
return
}
sort.Slice(es.byParent[parent], func(i, j int) bool {
return es.byParent[parent][i].id < es.byParent[parent][j].id
})
for _, r := range es.byParent[parent] {
var res string
for range nest {
res += "-"
}
if nest > 0 {
res += " "
}
res += r.detail
es.buf = append(es.buf, res)
es.string(r.id, nest+1)
}
}