/
schema.go
132 lines (115 loc) · 3.6 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
125
126
127
128
129
130
131
132
// Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0.
package utils
import (
"context"
"fmt"
"strings"
"github.com/pingcap/errors"
backuppb "github.com/pingcap/kvproto/pkg/brpb"
"github.com/wuhuizuo/tidb6/br/pkg/metautil"
"github.com/wuhuizuo/tidb6/parser/model"
"github.com/wuhuizuo/tidb6/parser/mysql"
)
// temporaryDBNamePrefix is the prefix name of system db, e.g. mysql system db will be rename to __TiDB_BR_Temporary_mysql
const temporaryDBNamePrefix = "__TiDB_BR_Temporary_"
const temporarySysDB = temporaryDBNamePrefix + "mysql"
// NeedAutoID checks whether the table needs backing up with an autoid.
func NeedAutoID(tblInfo *model.TableInfo) bool {
hasRowID := !tblInfo.PKIsHandle && !tblInfo.IsCommonHandle
hasAutoIncID := tblInfo.GetAutoIncrementColInfo() != nil
return hasRowID || hasAutoIncID
}
// Database wraps the schema and tables of a database.
type Database struct {
Info *model.DBInfo
Tables []*metautil.Table
}
// GetTable returns a table of the database by name.
func (db *Database) GetTable(name string) *metautil.Table {
for _, table := range db.Tables {
if table.Info.Name.String() == name {
return table
}
}
return nil
}
// LoadBackupTables loads schemas from BackupMeta.
func LoadBackupTables(ctx context.Context, reader *metautil.MetaReader) (map[string]*Database, error) {
ch := make(chan *metautil.Table)
errCh := make(chan error)
go func() {
if err := reader.ReadSchemasFiles(ctx, ch); err != nil {
errCh <- errors.Trace(err)
}
close(ch)
}()
databases := make(map[string]*Database)
for {
select {
case <-ctx.Done():
return nil, ctx.Err()
case err := <-errCh:
return nil, errors.Trace(err)
case table, ok := <-ch:
if !ok {
close(errCh)
return databases, nil
}
dbName := table.DB.Name.String()
db, ok := databases[dbName]
if !ok {
db = &Database{
Info: table.DB,
Tables: make([]*metautil.Table, 0),
}
databases[dbName] = db
}
db.Tables = append(db.Tables, table)
}
}
}
// ArchiveSize returns the total size of the backup archive.
func ArchiveSize(meta *backuppb.BackupMeta) uint64 {
total := uint64(meta.Size())
for _, file := range meta.Files {
total += file.Size_
}
return total
}
// EncloseName formats name in sql.
func EncloseName(name string) string {
return "`" + strings.ReplaceAll(name, "`", "``") + "`"
}
// EncloseDBAndTable formats the database and table name in sql.
func EncloseDBAndTable(database, table string) string {
return fmt.Sprintf("%s.%s", EncloseName(database), EncloseName(table))
}
// IsTemplateSysDB checks wheterh the dbname is temporary system database(__TiDB_BR_Temporary_mysql).
func IsTemplateSysDB(dbname model.CIStr) bool {
return dbname.O == temporarySysDB
}
// IsSysDB tests whether the database is system DB.
// Currently, the only system DB is mysql.
func IsSysDB(dbLowerName string) bool {
return dbLowerName == mysql.SystemDB
}
// TemporaryDBName makes a 'private' database name.
func TemporaryDBName(db string) model.CIStr {
return model.NewCIStr(temporaryDBNamePrefix + db)
}
// GetSysDBName get the original name of system DB
func GetSysDBName(tempDB model.CIStr) (string, bool) {
if ok := strings.HasPrefix(tempDB.O, temporaryDBNamePrefix); !ok {
return tempDB.O, false
}
return tempDB.O[len(temporaryDBNamePrefix):], true
}
// GetSysDBCIStrName get the CIStr name of system DB
func GetSysDBCIStrName(tempDB model.CIStr) (model.CIStr, bool) {
if ok := strings.HasPrefix(tempDB.O, temporaryDBNamePrefix); !ok {
return tempDB, false
}
tempDB.O = tempDB.O[len(temporaryDBNamePrefix):]
tempDB.L = tempDB.L[len(temporaryDBNamePrefix):]
return tempDB, true
}