-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathschema.go
122 lines (113 loc) · 3.05 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
// Copyright 2019 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package sqlsmith
import (
"regexp"
"strings"
"github.com/chaos-mesh/go-sqlsmith/types"
)
const typeRegex = `\(\d+\)`
// LoadSchema init schemas, tables and columns
// record[0] dbname
// record[1] table name
// record[2] table type
// record[3] column name
// record[4] column type
func (s *SQLSmith) LoadSchema(records [][5]string, indexes map[string][]string) {
// init databases
for _, record := range records {
dbname := record[0]
tableName := record[1]
tableType := record[2]
columnName := record[3]
columnType := record[4]
index, ok := indexes[tableName]
if !ok {
index = []string{}
}
if _, ok := s.Databases[dbname]; !ok {
s.Databases[dbname] = &types.Database{
Name: dbname,
Tables: make(map[string]*types.Table),
}
}
if _, ok := s.Databases[dbname].Tables[tableName]; !ok {
s.Databases[dbname].Tables[tableName] = &types.Table{
DB: dbname,
Table: tableName,
Type: tableType,
Columns: make(map[string]*types.Column),
Indexes: index,
}
}
if _, ok := s.Databases[dbname].Tables[tableName].Columns[columnName]; !ok {
s.Databases[dbname].Tables[tableName].Columns[columnName] = &types.Column{
DB: dbname,
Table: tableName,
Column: columnName,
// remove the data size in type definition
DataType: regexp.MustCompile(typeRegex).ReplaceAllString(strings.ToLower(columnType), ""),
}
}
}
}
// BeginWithOnlineTables begins a transaction with some online tables
func (s *SQLSmith) BeginWithOnlineTables(opt *DMLOptions) []string {
if !opt.OnlineTable {
return []string{}
}
var (
res = []string{}
db = s.GetDB(s.GetCurrDBName())
tables = db.RandTables()
)
for _, t := range tables {
res = append(res, t.Table)
t.Online = true
}
db.Online = true
return res
}
// EndTransaction ends transaction and set every table offline
func (s *SQLSmith) EndTransaction() []string {
var (
res = []string{}
db = s.GetDB(s.GetCurrDBName())
tables = db.Tables
)
for _, t := range tables {
res = append(res, t.Table)
t.Online = false
}
db.Online = false
return res
}
// setOnlineOtherTables is for avoiding online DDL
func (s *SQLSmith) setOnlineOtherTables(opt *DDLOptions) {
if opt.OnlineDDL {
return
}
db := s.GetDB(s.currDB)
for _, table := range opt.Tables {
if db.Tables[table] != nil {
db.Tables[table].OnlineOther = true
}
}
}
// freeOnlineOtherTables clear online tables obtain by other instances
func (s *SQLSmith) freeOnlineOtherTables() {
db := s.GetDB(s.currDB)
for _, table := range db.Tables {
table.OnlineOther = false
}
}