-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
124 lines (109 loc) · 2.34 KB
/
config.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main
import (
"database/sql"
"fmt"
"log"
"strings"
"time"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclparse"
"github.com/pingcap/tidb/parser/ast"
)
type Config struct {
Databases map[string]*Database
Options *Options
File *hcl.File
Started time.Time
Conn *sql.DB
}
var configSchema = &hcl.BodySchema{
Blocks: []hcl.BlockHeaderSchema{
{
Type: "database",
LabelNames: []string{"name"},
},
},
}
type Column struct {
Name string
Position int64
Type string
MaxLength sql.NullInt64
Table *Table
}
func (c *Column) String() string {
return fmt.Sprintf(c.Table.Name, c.Name)
}
type Row struct {
Table *Table
Values *[]ast.ExprNode
}
func NewConfig(opts *Options) (config *Config, err error) {
parser := hclparse.NewParser()
f, diags := parser.ParseHCLFile(opts.ConfigFile)
conn, err := NewConnection(opts)
if err != nil {
return nil, err
}
defer conn.Close()
config = &Config{
Databases: make(map[string]*Database),
Options: opts,
File: f,
Started: time.Now(),
Conn: conn,
}
moreDiags := config.Read()
diags = append(diags, moreDiags...)
var sb strings.Builder
wr := hcl.NewDiagnosticTextWriter(&sb, parser.Files(), 78, true)
wr.WriteDiagnostics(diags)
if diags.HasErrors() {
err = fmt.Errorf("Could not read config")
}
log.Println(sb.String())
return
}
func NewConnection(opts *Options) (*sql.DB, error) {
var dsn string
if len(opts.Socket) != 0 {
dsn = fmt.Sprintf(
"%s:%s@unix(%s)/",
opts.User,
opts.Password,
opts.Socket,
)
} else {
dsn = fmt.Sprintf(
"%s:%s@tcp(%s:%s)/",
opts.User,
opts.Password,
opts.Host,
opts.Port,
)
}
return sql.Open("mysql", dsn)
}
func (c *Config) Read() (diags hcl.Diagnostics) {
configContent, diags := c.File.Body.Content(configSchema)
if diags.HasErrors() {
return
}
for _, dbBlock := range configContent.Blocks {
name := dbBlock.Labels[0]
database, moreDiags := NewDatabase(name, dbBlock, c)
c.Databases[name] = database
if diags = append(diags, moreDiags...); moreDiags.HasErrors() {
continue
}
moreDiags = database.ReadSchema()
if diags = append(diags, moreDiags...); moreDiags.HasErrors() {
continue
}
moreDiags = database.ReadDynamicConfig()
if diags = append(diags, moreDiags...); moreDiags.HasErrors() {
continue
}
}
return
}