forked from hidu/mysql-schema-sync
-
Notifications
You must be signed in to change notification settings - Fork 0
/
schema.go
124 lines (110 loc) · 2.55 KB
/
schema.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 internal
import (
"fmt"
"strings"
)
func NewSchema(schema string) *MySchema {
return &MySchema{
SchemaRaw: schema,
Fields: make(map[string]string),
IndexAll: make(map[string]*DbIndex, 0),
ForeignAll: make(map[string]*DbIndex, 0),
}
}
// MySchema table schema
type MySchema struct {
SchemaRaw string
Fields map[string]string
IndexAll map[string]*DbIndex
ForeignAll map[string]*DbIndex
}
func (mys *MySchema) String() string {
s := "Fields:\n"
fl := maxMapKeyLen(mys.Fields, 2)
for name, v := range mys.Fields {
s += fmt.Sprintf(" %"+fl+"s : %s\n", name, v)
}
s += "Index:\n"
fl = maxMapKeyLen(mys.IndexAll, 2)
for name, idx := range mys.IndexAll {
s += fmt.Sprintf(" %"+fl+"s : %s\n", name, idx.SQL)
}
s += "ForeignKey:\n"
fl = maxMapKeyLen(mys.ForeignAll, 2)
for name, idx := range mys.ForeignAll {
s += fmt.Sprintf(" %"+fl+"s : %s\n", name, idx.SQL)
}
return s
}
// GetFieldNames table names
func (mys *MySchema) GetFieldNames() []string {
var names []string
for name := range mys.Fields {
names = append(names, name)
}
return names
}
func (mys *MySchema) RelationTables() []string {
tbs := make(map[string]int)
for _, idx := range mys.ForeignAll {
for _, tb := range idx.RelationTables {
tbs[tb] = 1
}
}
var tables []string
for tb := range tbs {
tables = append(tables, tb)
}
return tables
}
// ParseSchema parse table's schema
func ParseSchema(schema string) *MySchema {
schema = strings.TrimSpace(schema)
lines := strings.Split(schema, "\n")
mys := NewSchema(schema)
for i := 1; i < len(lines)-1; i++ {
line := strings.TrimSpace(lines[i])
if line == "" {
continue
}
line = strings.TrimRight(line, ",")
if line[0] == '`' {
index := strings.Index(line[1:], "`")
name := line[1 : index+1]
mys.Fields[name] = line
} else {
idx := parseDbIndexLine(line)
if idx == nil {
continue
}
switch idx.IndexType {
case IndexTypeForeignKey:
mys.ForeignAll[idx.Name] = idx
default:
mys.IndexAll[idx.Name] = idx
}
}
}
// fmt.Println(schema)
// fmt.Println(mys)
// fmt.Println("-----")
return mys
}
type SchemaDiff struct {
Table string
Source *MySchema
Dest *MySchema
}
func NewSchemaDiff(table string, source *MySchema, dest *MySchema) *SchemaDiff {
return &SchemaDiff{
Table: table,
Source: source,
Dest: dest,
}
}
func newSchemaDiff(table, source, dest string) *SchemaDiff {
return NewSchemaDiff(table, ParseSchema(source), ParseSchema(dest))
}
func (sdiff *SchemaDiff) RelationTables() []string {
return sdiff.Source.RelationTables()
}