This repository was archived by the owner on Jul 9, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathcode.go
103 lines (93 loc) · 2.17 KB
/
code.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package tablestruct
import (
"bytes"
"fmt"
"go/format"
"go/parser"
"go/token"
"io"
"log"
"strings"
"text/template"
)
// Code generates Go code that maps database tables to structs.
type Code struct {
buf *bytes.Buffer
tmpl *template.Template
}
// NewCode creates a new code generator.
func NewCode() *Code {
funcMap := template.FuncMap{"add": func(a, b int) int { return a + b }}
return &Code{
buf: bytes.NewBuffer(nil),
tmpl: template.Must(template.New("tablestruct").Funcs(funcMap).Parse(mapperTemplate)),
}
}
func (c *Code) write(format string, param ...interface{}) {
c.buf.WriteString(fmt.Sprintf(format, param...))
}
type tableMapTmpl struct {
Mapper TableMap
MapperType string
MapperFields []string
VarName string
StructType string
ColumnList string
Table string
Fields []string
UpdateList string
UpdateCount int
InsertList string
}
// Gen generates Go code for a set of table mappings.
func (c *Code) Gen(mapper *Map, pkg string, out io.Writer) {
data := struct {
Package string
Imports []importSpec
TableMaps []tableMapTmpl
}{
Package: pkg,
Imports: mapper.Imports(),
}
for i, tableMap := range *mapper {
log.Printf("%d: generating map %s -> %s", i, tableMap.Table, tableMap.Struct)
data.TableMaps = append(data.TableMaps, c.genMapper(tableMap))
}
if err := c.tmpl.Execute(c.buf, data); err != nil {
// TODO(paulsmith): return error
log.Fatal(err)
}
// gofmt
fset := token.NewFileSet()
ast, err := parser.ParseFile(fset, "", c.buf.Bytes(), parser.ParseComments)
if err != nil {
// TODO(paulsmith): return error
log.Fatal(err)
}
err = format.Node(out, fset, ast)
if err != nil {
// TODO(paulsmith): return error
log.Fatal(err)
}
}
func (c *Code) genMapper(mapper TableMap) tableMapTmpl {
// TODO(paulsmith): move this.
mapperFields := []string{
"db *sql.DB",
"sql map[string]string",
"stmt map[string]*sql.Stmt",
}
return tableMapTmpl{
mapper,
mapper.Struct + "Mapper",
mapperFields,
strings.ToLower(mapper.Struct[0:1]),
mapper.Struct,
mapper.ColumnList(),
mapper.Table,
mapper.Fields(),
mapper.UpdateList(),
len(mapper.Columns) + 1,
mapper.InsertList(),
}
}