// GetSchema is part of the MysqlDaemon interface func (fmd *FakeMysqlDaemon) GetSchema(dbName string, tables, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) { if fmd.SchemaFunc != nil { return fmd.SchemaFunc() } if fmd.Schema == nil { return nil, fmt.Errorf("no schema defined") } return tmutils.FilterTables(fmd.Schema, tables, excludeTables, includeViews) }
// GetSchema returns the schema for database for tables listed in // tables. If tables is empty, return the schema for all tables. func (mysqld *Mysqld) GetSchema(dbName string, tables, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) { sd := &tabletmanagerdatapb.SchemaDefinition{} // get the database creation command qr, fetchErr := mysqld.FetchSuperQuery("SHOW CREATE DATABASE IF NOT EXISTS " + dbName) if fetchErr != nil { return nil, fetchErr } if len(qr.Rows) == 0 { return nil, fmt.Errorf("empty create database statement for %v", dbName) } sd.DatabaseSchema = strings.Replace(qr.Rows[0][1].String(), "`"+dbName+"`", "`{{.DatabaseName}}`", 1) // get the list of tables we're interested in sql := "SELECT table_name, table_type, data_length, table_rows FROM information_schema.tables WHERE table_schema = '" + dbName + "'" if !includeViews { sql += " AND table_type = '" + tmutils.TableBaseTable + "'" } qr, err := mysqld.FetchSuperQuery(sql) if err != nil { return nil, err } if len(qr.Rows) == 0 { return sd, nil } sd.TableDefinitions = make([]*tabletmanagerdatapb.TableDefinition, 0, len(qr.Rows)) for _, row := range qr.Rows { tableName := row[0].String() tableType := row[1].String() // compute dataLength var dataLength uint64 if !row[2].IsNull() { // dataLength is NULL for views, then we use 0 dataLength, err = row[2].ParseUint64() if err != nil { return nil, err } } // get row count var rowCount uint64 if !row[3].IsNull() { rowCount, err = row[3].ParseUint64() if err != nil { return nil, err } } qr, fetchErr := mysqld.FetchSuperQuery("SHOW CREATE TABLE " + dbName + "." + tableName) if fetchErr != nil { return nil, fetchErr } if len(qr.Rows) == 0 { return nil, fmt.Errorf("empty create table statement for %v", tableName) } // Normalize & remove auto_increment because it changes on every insert // FIXME(alainjobart) find a way to share this with // vt/tabletserver/table_info.go:162 norm := qr.Rows[0][1].String() norm = autoIncr.ReplaceAllLiteralString(norm, "") if tableType == tmutils.TableView { // Views will have the dbname in there, replace it // with {{.DatabaseName}} norm = strings.Replace(norm, "`"+dbName+"`", "`{{.DatabaseName}}`", -1) } td := &tabletmanagerdatapb.TableDefinition{} td.Name = tableName td.Schema = norm td.Columns, err = mysqld.GetColumns(dbName, tableName) if err != nil { return nil, err } td.PrimaryKeyColumns, err = mysqld.GetPrimaryKeyColumns(dbName, tableName) if err != nil { return nil, err } td.Type = tableType td.DataLength = dataLength td.RowCount = rowCount sd.TableDefinitions = append(sd.TableDefinitions, td) } sd, err = tmutils.FilterTables(sd, tables, excludeTables, includeViews) if err != nil { return nil, err } tmutils.GenerateSchemaVersion(sd) return sd, nil }