Update migrator.go

This commit is contained in:
Jinzhu 2022-12-24 12:05:30 +08:00 committed by GitHub
parent c035852cb1
commit ac9262f736
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -424,32 +424,49 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy
fullDataType := strings.TrimSpace(strings.ToLower(m.DB.Migrator().FullDataTypeOf(field).SQL)) fullDataType := strings.TrimSpace(strings.ToLower(m.DB.Migrator().FullDataTypeOf(field).SQL))
realDataType := strings.ToLower(columnType.DatabaseTypeName()) realDataType := strings.ToLower(columnType.DatabaseTypeName())
alterColumn := false var (
alterColumn, isSameType bool
)
// check type if !field.PrimaryKey {
if !field.PrimaryKey && !strings.HasPrefix(fullDataType, realDataType) { // check type
alterColumn = true if !strings.HasPrefix(fullDataType, realDataType) {
} // check type aliases
aliases := m.DB.Migrator().GetTypeAliases(realDataType)
for _, alias := range aliases {
if strings.HasPrefix(fullDataType, alias) {
isSameType = true
break
}
}
// check size if !isSameType {
if length, ok := columnType.Length(); length != int64(field.Size) {
if length > 0 && field.Size > 0 {
alterColumn = true
} else {
// has size in data type and not equal
// Since the following code is frequently called in the for loop, reg optimization is needed here
matches2 := regFullDataType.FindAllStringSubmatch(fullDataType, -1)
if !field.PrimaryKey &&
(len(matches2) == 1 && matches2[0][1] != fmt.Sprint(length) && ok) {
alterColumn = true alterColumn = true
} }
} }
} }
// check precision if !isSameType {
if precision, _, ok := columnType.DecimalSize(); ok && int64(field.Precision) != precision { // check size
if regexp.MustCompile(fmt.Sprintf("[^0-9]%d[^0-9]", field.Precision)).MatchString(m.DataTypeOf(field)) { if length, ok := columnType.Length(); length != int64(field.Size) {
alterColumn = true if length > 0 && field.Size > 0 {
alterColumn = true
} else {
// has size in data type and not equal
// Since the following code is frequently called in the for loop, reg optimization is needed here
matches2 := regFullDataType.FindAllStringSubmatch(fullDataType, -1)
if !field.PrimaryKey &&
(len(matches2) == 1 && matches2[0][1] != fmt.Sprint(length) && ok) {
alterColumn = true
}
}
}
// check precision
if precision, _, ok := columnType.DecimalSize(); ok && int64(field.Precision) != precision {
if regexp.MustCompile(fmt.Sprintf("[^0-9]%d[^0-9]", field.Precision)).MatchString(m.DataTypeOf(field)) {
alterColumn = true
}
} }
} }
@ -471,17 +488,19 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy
// check default value // check default value
if !field.PrimaryKey { if !field.PrimaryKey {
currentDefaultNotNull := field.HasDefaultValue && !strings.EqualFold(field.DefaultValue, "NULL")
dv, dvNotNull := columnType.DefaultValue() dv, dvNotNull := columnType.DefaultValue()
if dvNotNull && field.DefaultValueInterface == nil { if dvNotNull && !currentDefaultNotNull {
// defalut value -> null // defalut value -> null
alterColumn = true alterColumn = true
} else if !dvNotNull && field.DefaultValueInterface != nil { } else if !dvNotNull && currentDefaultNotNull {
// null -> default value // null -> default value
alterColumn = true alterColumn = true
} else if dv != field.DefaultValue { } else if (field.GORMDataType != schema.Time && dv != field.DefaultValue) ||
(field.GORMDataType == schema.Time && !strings.EqualFold(strings.TrimSuffix(dv, "()"), strings.TrimSuffix(field.DefaultValue, "()"))) {
// default value not equal // default value not equal
// not both null // not both null
if !(field.DefaultValueInterface == nil && !dvNotNull) { if currentDefaultNotNull || dvNotNull {
alterColumn = true alterColumn = true
} }
} }
@ -496,7 +515,7 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy
} }
if alterColumn && !field.IgnoreMigration { if alterColumn && !field.IgnoreMigration {
return m.DB.Migrator().AlterColumn(value, field.Name) return m.DB.Migrator().AlterColumn(value, field.DBName)
} }
return nil return nil
@ -881,3 +900,8 @@ func (m Migrator) CurrentTable(stmt *gorm.Statement) interface{} {
func (m Migrator) GetIndexes(dst interface{}) ([]gorm.Index, error) { func (m Migrator) GetIndexes(dst interface{}) ([]gorm.Index, error) {
return nil, errors.New("not support") return nil, errors.New("not support")
} }
// GetTypeAliases return database type aliases
func (m Migrator) GetTypeAliases(databaseTypeName string) []string {
return nil
}