mirror of https://github.com/go-gorm/gorm.git
Improve support for AutoMigrate
This commit is contained in:
parent
e0b4e0ec8f
commit
48ced75d1d
|
@ -11,7 +11,7 @@ type ColumnType struct {
|
|||
NameValue sql.NullString
|
||||
DataTypeValue sql.NullString
|
||||
ColumnTypeValue sql.NullString
|
||||
PrimayKeyValue sql.NullBool
|
||||
PrimaryKeyValue sql.NullBool
|
||||
UniqueValue sql.NullBool
|
||||
AutoIncrementValue sql.NullBool
|
||||
LengthValue sql.NullInt64
|
||||
|
@ -51,7 +51,7 @@ func (ct ColumnType) ColumnType() (columnType string, ok bool) {
|
|||
|
||||
// PrimaryKey returns the column is primary key or not.
|
||||
func (ct ColumnType) PrimaryKey() (isPrimaryKey bool, ok bool) {
|
||||
return ct.PrimayKeyValue.Bool, ct.PrimayKeyValue.Valid
|
||||
return ct.PrimaryKeyValue.Bool, ct.PrimaryKeyValue.Valid
|
||||
}
|
||||
|
||||
// AutoIncrement returns the column is auto increment or not.
|
||||
|
|
|
@ -436,6 +436,30 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy
|
|||
}
|
||||
}
|
||||
|
||||
// check unique
|
||||
if unique, ok := columnType.Unique(); ok && unique != field.Unique {
|
||||
// not primary key
|
||||
if !field.PrimaryKey {
|
||||
alterColumn = true
|
||||
}
|
||||
}
|
||||
|
||||
// check default value
|
||||
if v, ok := columnType.DefaultValue(); ok && v != field.DefaultValue {
|
||||
// not primary key
|
||||
if !field.PrimaryKey {
|
||||
alterColumn = true
|
||||
}
|
||||
}
|
||||
|
||||
// check comment
|
||||
if comment, ok := columnType.Comment(); ok && comment != field.Comment {
|
||||
// not primary key
|
||||
if !field.PrimaryKey {
|
||||
alterColumn = true
|
||||
}
|
||||
}
|
||||
|
||||
if alterColumn && !field.IgnoreMigration {
|
||||
return m.DB.Migrator().AlterColumn(value, field.Name)
|
||||
}
|
||||
|
|
10
tests/go.mod
10
tests/go.mod
|
@ -9,11 +9,11 @@ require (
|
|||
github.com/lib/pq v1.10.4
|
||||
github.com/mattn/go-sqlite3 v1.14.11 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect
|
||||
gorm.io/driver/mysql v1.3.0
|
||||
gorm.io/driver/postgres v1.3.0
|
||||
gorm.io/driver/sqlite v1.3.0
|
||||
gorm.io/driver/sqlserver v1.3.0
|
||||
gorm.io/gorm v1.22.5
|
||||
gorm.io/driver/mysql v1.3.1
|
||||
gorm.io/driver/postgres v1.3.1
|
||||
gorm.io/driver/sqlite v1.3.1
|
||||
gorm.io/driver/sqlserver v1.3.1
|
||||
gorm.io/gorm v1.23.0
|
||||
)
|
||||
|
||||
replace gorm.io/gorm => ../
|
||||
|
|
|
@ -45,7 +45,7 @@ func TestMigrate(t *testing.T) {
|
|||
|
||||
for _, m := range allModels {
|
||||
if !DB.Migrator().HasTable(m) {
|
||||
t.Fatalf("Failed to create table for %#v---", m)
|
||||
t.Fatalf("Failed to create table for %#v", m)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,15 +313,16 @@ func TestMigrateIndexes(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMigrateColumns(t *testing.T) {
|
||||
fullSupported := map[string]bool{"sqlite": true, "mysql": true, "postgres": true, "sqlserver": true}[DB.Dialector.Name()]
|
||||
sqlite := DB.Dialector.Name() == "sqlite"
|
||||
sqlserver := DB.Dialector.Name() == "sqlserver"
|
||||
|
||||
type ColumnStruct struct {
|
||||
gorm.Model
|
||||
Name string
|
||||
Age int `gorm:"default:18;comment:my age"`
|
||||
Code string `gorm:"unique"`
|
||||
Name string
|
||||
Age int `gorm:"default:18;comment:my age"`
|
||||
Code string `gorm:"unique;comment:my code;"`
|
||||
Code2 string
|
||||
Code3 string `gorm:"unique"`
|
||||
}
|
||||
|
||||
DB.Migrator().DropTable(&ColumnStruct{})
|
||||
|
@ -332,13 +333,20 @@ func TestMigrateColumns(t *testing.T) {
|
|||
|
||||
type ColumnStruct2 struct {
|
||||
gorm.Model
|
||||
Name string `gorm:"size:100"`
|
||||
Name string `gorm:"size:100"`
|
||||
Code string `gorm:"unique;comment:my code2;default:hello"`
|
||||
Code2 string `gorm:"unique"`
|
||||
// Code3 string
|
||||
}
|
||||
|
||||
if err := DB.Table("column_structs").Migrator().AlterColumn(&ColumnStruct2{}, "Name"); err != nil {
|
||||
if err := DB.Table("column_structs").Migrator().AlterColumn(&ColumnStruct{}, "Name"); err != nil {
|
||||
t.Fatalf("no error should happened when alter column, but got %v", err)
|
||||
}
|
||||
|
||||
if err := DB.Table("column_structs").AutoMigrate(&ColumnStruct2{}); err != nil {
|
||||
t.Fatalf("no error should happened when auto migrate column, but got %v", err)
|
||||
}
|
||||
|
||||
if columnTypes, err := DB.Migrator().ColumnTypes(&ColumnStruct{}); err != nil {
|
||||
t.Fatalf("no error should returns for ColumnTypes")
|
||||
} else {
|
||||
|
@ -348,7 +356,7 @@ func TestMigrateColumns(t *testing.T) {
|
|||
for _, columnType := range columnTypes {
|
||||
switch columnType.Name() {
|
||||
case "id":
|
||||
if v, ok := columnType.PrimaryKey(); (fullSupported || ok) && !v {
|
||||
if v, ok := columnType.PrimaryKey(); !ok || !v {
|
||||
t.Fatalf("column id primary key should be correct, name: %v, column: %#v", columnType.Name(), columnType)
|
||||
}
|
||||
case "name":
|
||||
|
@ -356,20 +364,35 @@ func TestMigrateColumns(t *testing.T) {
|
|||
if !strings.Contains(strings.ToUpper(dataType), strings.ToUpper(columnType.DatabaseTypeName())) {
|
||||
t.Fatalf("column name type should be correct, name: %v, length: %v, expects: %v, column: %#v", columnType.Name(), columnType.DatabaseTypeName(), dataType, columnType)
|
||||
}
|
||||
if length, ok := columnType.Length(); ((fullSupported && !sqlite) || ok) && length != 100 {
|
||||
if length, ok := columnType.Length(); !sqlite && (!ok || length != 100) {
|
||||
t.Fatalf("column name length should be correct, name: %v, length: %v, expects: %v, column: %#v", columnType.Name(), length, 100, columnType)
|
||||
}
|
||||
case "age":
|
||||
if v, ok := columnType.DefaultValue(); (fullSupported || ok) && v != "18" {
|
||||
if v, ok := columnType.DefaultValue(); !ok || v != "18" {
|
||||
t.Fatalf("column age default value should be correct, name: %v, column: %#v", columnType.Name(), columnType)
|
||||
}
|
||||
if v, ok := columnType.Comment(); ((fullSupported && !sqlite && !sqlserver) || ok) && v != "my age" {
|
||||
if v, ok := columnType.Comment(); !sqlite && !sqlserver && (!ok || v != "my age") {
|
||||
t.Fatalf("column age comment should be correct, name: %v, column: %#v", columnType.Name(), columnType)
|
||||
}
|
||||
case "code":
|
||||
if v, ok := columnType.Unique(); (fullSupported || ok) && !v {
|
||||
if v, ok := columnType.Unique(); !ok || !v {
|
||||
t.Fatalf("column code unique should be correct, name: %v, column: %#v", columnType.Name(), columnType)
|
||||
}
|
||||
if v, ok := columnType.DefaultValue(); !sqlserver && (!ok || v != "hello") {
|
||||
t.Fatalf("column code default value should be correct, name: %v, column: %#v", columnType.Name(), columnType)
|
||||
}
|
||||
if v, ok := columnType.Comment(); !sqlite && !sqlserver && (!ok || v != "my code2") {
|
||||
t.Fatalf("column code comment should be correct, name: %v, column: %#v", columnType.Name(), columnType)
|
||||
}
|
||||
case "code2":
|
||||
if v, ok := columnType.Unique(); !sqlserver && (!ok || !v) {
|
||||
t.Fatalf("column code2 unique should be correct, name: %v, column: %#v", columnType.Name(), columnType)
|
||||
}
|
||||
case "code3":
|
||||
// TODO
|
||||
// if v, ok := columnType.Unique(); !ok || v {
|
||||
// t.Fatalf("column code unique should be correct, name: %v, column: %#v", columnType.Name(), columnType)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue