fix: migrator run with nil schema
This commit is contained in:
parent
a1b7e47e75
commit
a0c4a21718
@ -55,8 +55,6 @@ func (m Migrator) RunWithValue(value interface{}, fc func(*gorm.Statement) error
|
|||||||
|
|
||||||
if table, ok := value.(string); ok {
|
if table, ok := value.(string); ok {
|
||||||
stmt.Table = table
|
stmt.Table = table
|
||||||
// set schema to avoid panic
|
|
||||||
stmt.Schema = &schema.Schema{}
|
|
||||||
} else if err := stmt.ParseWithSpecialTableName(value, stmt.Table); err != nil {
|
} else if err := stmt.ParseWithSpecialTableName(value, stmt.Table); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -347,7 +345,10 @@ func (m Migrator) RenameTable(oldName, newName interface{}) error {
|
|||||||
func (m Migrator) AddColumn(value interface{}, name string) error {
|
func (m Migrator) AddColumn(value interface{}, name string) error {
|
||||||
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
||||||
// avoid using the same name field
|
// avoid using the same name field
|
||||||
f := stmt.Schema.LookUpField(name)
|
var f *schema.Field
|
||||||
|
if stmt.Schema != nil {
|
||||||
|
f = stmt.Schema.LookUpField(name)
|
||||||
|
}
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return fmt.Errorf("failed to look up field with name: %s", name)
|
return fmt.Errorf("failed to look up field with name: %s", name)
|
||||||
}
|
}
|
||||||
@ -366,9 +367,11 @@ func (m Migrator) AddColumn(value interface{}, name string) error {
|
|||||||
// DropColumn drop value's `name` column
|
// DropColumn drop value's `name` column
|
||||||
func (m Migrator) DropColumn(value interface{}, name string) error {
|
func (m Migrator) DropColumn(value interface{}, name string) error {
|
||||||
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
||||||
|
if stmt.Schema != nil {
|
||||||
if field := stmt.Schema.LookUpField(name); field != nil {
|
if field := stmt.Schema.LookUpField(name); field != nil {
|
||||||
name = field.DBName
|
name = field.DBName
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return m.DB.Exec(
|
return m.DB.Exec(
|
||||||
"ALTER TABLE ? DROP COLUMN ?", m.CurrentTable(stmt), clause.Column{Name: name},
|
"ALTER TABLE ? DROP COLUMN ?", m.CurrentTable(stmt), clause.Column{Name: name},
|
||||||
@ -379,13 +382,14 @@ func (m Migrator) DropColumn(value interface{}, name string) error {
|
|||||||
// AlterColumn alter value's `field` column' type based on schema definition
|
// AlterColumn alter value's `field` column' type based on schema definition
|
||||||
func (m Migrator) AlterColumn(value interface{}, field string) error {
|
func (m Migrator) AlterColumn(value interface{}, field string) error {
|
||||||
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
||||||
|
if stmt.Schema != nil {
|
||||||
if field := stmt.Schema.LookUpField(field); field != nil {
|
if field := stmt.Schema.LookUpField(field); field != nil {
|
||||||
fileType := m.FullDataTypeOf(field)
|
fileType := m.FullDataTypeOf(field)
|
||||||
return m.DB.Exec(
|
return m.DB.Exec(
|
||||||
"ALTER TABLE ? ALTER COLUMN ? TYPE ?",
|
"ALTER TABLE ? ALTER COLUMN ? TYPE ?",
|
||||||
m.CurrentTable(stmt), clause.Column{Name: field.DBName}, fileType,
|
m.CurrentTable(stmt), clause.Column{Name: field.DBName}, fileType,
|
||||||
).Error
|
).Error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return fmt.Errorf("failed to look up field with name: %s", field)
|
return fmt.Errorf("failed to look up field with name: %s", field)
|
||||||
})
|
})
|
||||||
@ -397,9 +401,11 @@ func (m Migrator) HasColumn(value interface{}, field string) bool {
|
|||||||
m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
||||||
currentDatabase := m.DB.Migrator().CurrentDatabase()
|
currentDatabase := m.DB.Migrator().CurrentDatabase()
|
||||||
name := field
|
name := field
|
||||||
|
if stmt.Schema != nil {
|
||||||
if field := stmt.Schema.LookUpField(field); field != nil {
|
if field := stmt.Schema.LookUpField(field); field != nil {
|
||||||
name = field.DBName
|
name = field.DBName
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return m.DB.Raw(
|
return m.DB.Raw(
|
||||||
"SELECT count(*) FROM INFORMATION_SCHEMA.columns WHERE table_schema = ? AND table_name = ? AND column_name = ?",
|
"SELECT count(*) FROM INFORMATION_SCHEMA.columns WHERE table_schema = ? AND table_name = ? AND column_name = ?",
|
||||||
@ -413,6 +419,7 @@ func (m Migrator) HasColumn(value interface{}, field string) bool {
|
|||||||
// RenameColumn rename value's field name from oldName to newName
|
// RenameColumn rename value's field name from oldName to newName
|
||||||
func (m Migrator) RenameColumn(value interface{}, oldName, newName string) error {
|
func (m Migrator) RenameColumn(value interface{}, oldName, newName string) error {
|
||||||
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
||||||
|
if stmt.Schema != nil {
|
||||||
if field := stmt.Schema.LookUpField(oldName); field != nil {
|
if field := stmt.Schema.LookUpField(oldName); field != nil {
|
||||||
oldName = field.DBName
|
oldName = field.DBName
|
||||||
}
|
}
|
||||||
@ -420,6 +427,7 @@ func (m Migrator) RenameColumn(value interface{}, oldName, newName string) error
|
|||||||
if field := stmt.Schema.LookUpField(newName); field != nil {
|
if field := stmt.Schema.LookUpField(newName); field != nil {
|
||||||
newName = field.DBName
|
newName = field.DBName
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return m.DB.Exec(
|
return m.DB.Exec(
|
||||||
"ALTER TABLE ? RENAME COLUMN ? TO ?",
|
"ALTER TABLE ? RENAME COLUMN ? TO ?",
|
||||||
@ -756,6 +764,7 @@ type BuildIndexOptionsInterface interface {
|
|||||||
// CreateIndex create index `name`
|
// CreateIndex create index `name`
|
||||||
func (m Migrator) CreateIndex(value interface{}, name string) error {
|
func (m Migrator) CreateIndex(value interface{}, name string) error {
|
||||||
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
||||||
|
if stmt.Schema != nil {
|
||||||
if idx := stmt.Schema.LookIndex(name); idx != nil {
|
if idx := stmt.Schema.LookIndex(name); idx != nil {
|
||||||
opts := m.DB.Migrator().(BuildIndexOptionsInterface).BuildIndexOptions(idx.Fields, stmt)
|
opts := m.DB.Migrator().(BuildIndexOptionsInterface).BuildIndexOptions(idx.Fields, stmt)
|
||||||
values := []interface{}{clause.Column{Name: idx.Name}, m.CurrentTable(stmt), opts}
|
values := []interface{}{clause.Column{Name: idx.Name}, m.CurrentTable(stmt), opts}
|
||||||
@ -780,6 +789,7 @@ func (m Migrator) CreateIndex(value interface{}, name string) error {
|
|||||||
|
|
||||||
return m.DB.Exec(createIndexSQL, values...).Error
|
return m.DB.Exec(createIndexSQL, values...).Error
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return fmt.Errorf("failed to create index with name %s", name)
|
return fmt.Errorf("failed to create index with name %s", name)
|
||||||
})
|
})
|
||||||
@ -788,9 +798,11 @@ func (m Migrator) CreateIndex(value interface{}, name string) error {
|
|||||||
// DropIndex drop index `name`
|
// DropIndex drop index `name`
|
||||||
func (m Migrator) DropIndex(value interface{}, name string) error {
|
func (m Migrator) DropIndex(value interface{}, name string) error {
|
||||||
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
||||||
|
if stmt.Schema != nil {
|
||||||
if idx := stmt.Schema.LookIndex(name); idx != nil {
|
if idx := stmt.Schema.LookIndex(name); idx != nil {
|
||||||
name = idx.Name
|
name = idx.Name
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return m.DB.Exec("DROP INDEX ? ON ?", clause.Column{Name: name}, m.CurrentTable(stmt)).Error
|
return m.DB.Exec("DROP INDEX ? ON ?", clause.Column{Name: name}, m.CurrentTable(stmt)).Error
|
||||||
})
|
})
|
||||||
@ -801,9 +813,11 @@ func (m Migrator) HasIndex(value interface{}, name string) bool {
|
|||||||
var count int64
|
var count int64
|
||||||
m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
||||||
currentDatabase := m.DB.Migrator().CurrentDatabase()
|
currentDatabase := m.DB.Migrator().CurrentDatabase()
|
||||||
|
if stmt.Schema != nil {
|
||||||
if idx := stmt.Schema.LookIndex(name); idx != nil {
|
if idx := stmt.Schema.LookIndex(name); idx != nil {
|
||||||
name = idx.Name
|
name = idx.Name
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return m.DB.Raw(
|
return m.DB.Raw(
|
||||||
"SELECT count(*) FROM information_schema.statistics WHERE table_schema = ? AND table_name = ? AND index_name = ?",
|
"SELECT count(*) FROM information_schema.statistics WHERE table_schema = ? AND table_name = ? AND index_name = ?",
|
||||||
|
@ -384,6 +384,22 @@ func TestMigrateIndexes(t *testing.T) {
|
|||||||
if DB.Migrator().HasIndex(&IndexStruct{}, "idx_users_name_1") {
|
if DB.Migrator().HasIndex(&IndexStruct{}, "idx_users_name_1") {
|
||||||
t.Fatalf("Should not find index for user's name after delete")
|
t.Fatalf("Should not find index for user's name after delete")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := DB.Migrator().CreateIndex(&IndexStruct{}, "Name"); err != nil {
|
||||||
|
t.Fatalf("Got error when tried to create index: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DB.Migrator().RenameIndex("index_structs", "idx_index_structs_name", "idx_users_name_1"); err != nil {
|
||||||
|
t.Fatalf("no error should happen when rename index, but got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !DB.Migrator().HasIndex("index_structs", "idx_users_name_1") {
|
||||||
|
t.Fatalf("Should find index for user's name after rename")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DB.Migrator().DropIndex("index_structs", "idx_users_name_1"); err != nil {
|
||||||
|
t.Fatalf("Failed to drop index for user's name, got err %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTiDBMigrateColumns(t *testing.T) {
|
func TestTiDBMigrateColumns(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user