github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/utils/schema.go (about)

     1  // Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0.
     2  
     3  package utils
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/pingcap/errors"
    11  	backuppb "github.com/pingcap/kvproto/pkg/backup"
    12  	"github.com/pingcap/parser/model"
    13  	"github.com/pingcap/parser/mysql"
    14  
    15  	"github.com/pingcap/br/pkg/metautil"
    16  )
    17  
    18  // temporaryDBNamePrefix is the prefix name of system db, e.g. mysql system db will be rename to __TiDB_BR_Temporary_mysql
    19  const temporaryDBNamePrefix = "__TiDB_BR_Temporary_"
    20  
    21  // NeedAutoID checks whether the table needs backing up with an autoid.
    22  func NeedAutoID(tblInfo *model.TableInfo) bool {
    23  	hasRowID := !tblInfo.PKIsHandle && !tblInfo.IsCommonHandle
    24  	hasAutoIncID := tblInfo.GetAutoIncrementColInfo() != nil
    25  	return hasRowID || hasAutoIncID
    26  }
    27  
    28  // Database wraps the schema and tables of a database.
    29  type Database struct {
    30  	Info   *model.DBInfo
    31  	Tables []*metautil.Table
    32  }
    33  
    34  // GetTable returns a table of the database by name.
    35  func (db *Database) GetTable(name string) *metautil.Table {
    36  	for _, table := range db.Tables {
    37  		if table.Info.Name.String() == name {
    38  			return table
    39  		}
    40  	}
    41  	return nil
    42  }
    43  
    44  // LoadBackupTables loads schemas from BackupMeta.
    45  func LoadBackupTables(ctx context.Context, reader *metautil.MetaReader) (map[string]*Database, error) {
    46  	ch := make(chan *metautil.Table)
    47  	errCh := make(chan error)
    48  	go func() {
    49  		if err := reader.ReadSchemasFiles(ctx, ch); err != nil {
    50  			errCh <- errors.Trace(err)
    51  		}
    52  		close(ch)
    53  	}()
    54  
    55  	databases := make(map[string]*Database)
    56  	for {
    57  		select {
    58  		case <-ctx.Done():
    59  			return nil, ctx.Err()
    60  		case err := <-errCh:
    61  			return nil, errors.Trace(err)
    62  		case table, ok := <-ch:
    63  			if !ok {
    64  				close(errCh)
    65  				return databases, nil
    66  			}
    67  			dbName := table.DB.Name.String()
    68  			db, ok := databases[dbName]
    69  			if !ok {
    70  				db = &Database{
    71  					Info:   table.DB,
    72  					Tables: make([]*metautil.Table, 0),
    73  				}
    74  				databases[dbName] = db
    75  			}
    76  			db.Tables = append(db.Tables, table)
    77  		}
    78  	}
    79  }
    80  
    81  // ArchiveSize returns the total size of the backup archive.
    82  func ArchiveSize(meta *backuppb.BackupMeta) uint64 {
    83  	total := uint64(meta.Size())
    84  	for _, file := range meta.Files {
    85  		total += file.Size_
    86  	}
    87  	return total
    88  }
    89  
    90  // EncloseName formats name in sql.
    91  func EncloseName(name string) string {
    92  	return "`" + strings.ReplaceAll(name, "`", "``") + "`"
    93  }
    94  
    95  // EncloseDBAndTable formats the database and table name in sql.
    96  func EncloseDBAndTable(database, table string) string {
    97  	return fmt.Sprintf("%s.%s", EncloseName(database), EncloseName(table))
    98  }
    99  
   100  // IsSysDB tests whether the database is system DB.
   101  // Currently, the only system DB is mysql.
   102  func IsSysDB(dbLowerName string) bool {
   103  	return dbLowerName == mysql.SystemDB
   104  }
   105  
   106  // TemporaryDBName makes a 'private' database name.
   107  func TemporaryDBName(db string) model.CIStr {
   108  	return model.NewCIStr(temporaryDBNamePrefix + db)
   109  }
   110  
   111  // GetSysDBName get the original name of system DB
   112  func GetSysDBName(tempDB model.CIStr) (string, bool) {
   113  	if ok := strings.HasPrefix(tempDB.O, temporaryDBNamePrefix); !ok {
   114  		return tempDB.O, false
   115  	}
   116  	return tempDB.O[len(temporaryDBNamePrefix):], true
   117  }