-
Notifications
You must be signed in to change notification settings - Fork 9
/
template.go
88 lines (80 loc) · 1.81 KB
/
template.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
81
82
83
84
85
86
87
88
package tqla
import (
"fmt"
"io"
"text/template"
"text/template/parse"
)
type sqlTemplate struct {
text *template.Template
}
func newSqlTemplate(name string, funcs template.FuncMap) *sqlTemplate {
return &sqlTemplate{
text: template.New(name).Funcs(funcs),
}
}
func (st *sqlTemplate) parse(text string) error {
if st.text == nil {
return fmt.Errorf("nil template")
}
tmpl, err := st.text.Parse(text)
if err != nil {
return err
}
formatTemplate(tmpl)
return nil
}
func (st *sqlTemplate) execute(wr io.Writer, data any) error {
return st.text.Execute(wr, data)
}
// formatTemplate formats all the templates defined in a template.
func formatTemplate(t *template.Template) {
for _, tmpl := range t.Templates() {
formatTree(tmpl.Tree)
}
}
func formatTree(t *parse.Tree) *parse.Tree {
if t.Root == nil {
return t
}
formatNode(t, t.Root)
return t
}
func formatNode(t *parse.Tree, n parse.Node) {
switch v := n.(type) {
case *parse.ActionNode:
formatNode(t, v.Pipe)
case *parse.IfNode:
formatNode(t, v.List)
formatNode(t, v.ElseList)
case *parse.RangeNode:
formatNode(t, v.List)
formatNode(t, v.ElseList)
case *parse.ListNode:
if v == nil {
return
}
for _, n := range v.Nodes {
formatNode(t, n)
}
case *parse.WithNode:
formatNode(t, v.List)
formatNode(t, v.ElseList)
case *parse.PipeNode:
if len(v.Decl) > 0 {
// If the pipe sets variables then don't try to format it
return
}
if len(v.Cmds) < 1 {
return
}
cmd := v.Cmds[len(v.Cmds)-1]
if len(cmd.Args) == 1 && cmd.Args[0].Type() == parse.NodeIdentifier && cmd.Args[0].(*parse.IdentifierNode).Ident == "_sql_parser_" {
return
}
v.Cmds = append(v.Cmds, &parse.CommandNode{
NodeType: parse.NodeCommand,
Args: []parse.Node{parse.NewIdentifier("_sql_parser_").SetTree(t).SetPos(cmd.Pos)},
})
}
}