refactor: part 2 of distinguish between Unique and UniqueIndex (#6822)
This commit is contained in:
		
							parent
							
								
									9514d5f9e6
								
							
						
					
					
						commit
						8fb9a31775
					
				| @ -93,10 +93,6 @@ func (m Migrator) FullDataTypeOf(field *schema.Field) (expr clause.Expr) { | |||||||
| 		expr.SQL += " NOT NULL" | 		expr.SQL += " NOT NULL" | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if field.Unique { |  | ||||||
| 		expr.SQL += " UNIQUE" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if field.HasDefaultValue && (field.DefaultValueInterface != nil || field.DefaultValue != "") { | 	if field.HasDefaultValue && (field.DefaultValueInterface != nil || field.DefaultValue != "") { | ||||||
| 		if field.DefaultValueInterface != nil { | 		if field.DefaultValueInterface != nil { | ||||||
| 			defaultStmt := &gorm.Statement{Vars: []interface{}{field.DefaultValueInterface}} | 			defaultStmt := &gorm.Statement{Vars: []interface{}{field.DefaultValueInterface}} | ||||||
| @ -512,14 +508,6 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// check unique
 |  | ||||||
| 	if unique, ok := columnType.Unique(); ok && unique != (field.Unique || field.UniqueIndex != "") { |  | ||||||
| 		// not primary key
 |  | ||||||
| 		if !field.PrimaryKey { |  | ||||||
| 			alterColumn = true |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// check default value
 | 	// check default value
 | ||||||
| 	if !field.PrimaryKey { | 	if !field.PrimaryKey { | ||||||
| 		currentDefaultNotNull := field.HasDefaultValue && (field.DefaultValueInterface != nil || !strings.EqualFold(field.DefaultValue, "NULL")) | 		currentDefaultNotNull := field.HasDefaultValue && (field.DefaultValueInterface != nil || !strings.EqualFold(field.DefaultValue, "NULL")) | ||||||
| @ -548,8 +536,14 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if alterColumn && !field.IgnoreMigration { | 	if alterColumn { | ||||||
| 		return m.DB.Migrator().AlterColumn(value, field.DBName) | 		if err := m.DB.Migrator().AlterColumn(value, field.DBName); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err := m.DB.Migrator().MigrateColumnUnique(value, field, columnType); err != nil { | ||||||
|  | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
|  | |||||||
							
								
								
									
										22
									
								
								tests/go.mod
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								tests/go.mod
									
									
									
									
									
								
							| @ -3,28 +3,34 @@ module gorm.io/gorm/tests | |||||||
| go 1.18 | go 1.18 | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
| 	github.com/google/uuid v1.5.0 | 	github.com/google/uuid v1.6.0 | ||||||
| 	github.com/jinzhu/now v1.1.5 | 	github.com/jinzhu/now v1.1.5 | ||||||
| 	github.com/lib/pq v1.10.9 | 	github.com/lib/pq v1.10.9 | ||||||
| 	gorm.io/driver/mysql v1.5.2 | 	github.com/stretchr/testify v1.8.4 | ||||||
| 	gorm.io/driver/postgres v1.5.4 | 	gorm.io/driver/mysql v1.5.4 | ||||||
| 	gorm.io/driver/sqlite v1.5.4 | 	gorm.io/driver/postgres v1.5.6 | ||||||
| 	gorm.io/driver/sqlserver v1.5.2 | 	gorm.io/driver/sqlite v1.5.5 | ||||||
| 	gorm.io/gorm v1.25.5 | 	gorm.io/driver/sqlserver v1.5.3 | ||||||
|  | 	gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
|  | 	github.com/davecgh/go-spew v1.1.1 // indirect | ||||||
| 	github.com/go-sql-driver/mysql v1.7.1 // indirect | 	github.com/go-sql-driver/mysql v1.7.1 // indirect | ||||||
| 	github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect | 	github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect | ||||||
| 	github.com/golang-sql/sqlexp v0.1.0 // indirect | 	github.com/golang-sql/sqlexp v0.1.0 // indirect | ||||||
| 	github.com/jackc/pgpassfile v1.0.0 // indirect | 	github.com/jackc/pgpassfile v1.0.0 // indirect | ||||||
| 	github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect | 	github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect | ||||||
| 	github.com/jackc/pgx/v5 v5.5.1 // indirect | 	github.com/jackc/pgx/v5 v5.5.3 // indirect | ||||||
| 	github.com/jinzhu/inflection v1.0.0 // indirect | 	github.com/jinzhu/inflection v1.0.0 // indirect | ||||||
| 	github.com/mattn/go-sqlite3 v1.14.19 // indirect | 	github.com/kr/text v0.2.0 // indirect | ||||||
|  | 	github.com/mattn/go-sqlite3 v1.14.22 // indirect | ||||||
| 	github.com/microsoft/go-mssqldb v1.6.0 // indirect | 	github.com/microsoft/go-mssqldb v1.6.0 // indirect | ||||||
|  | 	github.com/pmezard/go-difflib v1.0.0 // indirect | ||||||
|  | 	github.com/rogpeppe/go-internal v1.12.0 // indirect | ||||||
| 	golang.org/x/crypto v0.18.0 // indirect | 	golang.org/x/crypto v0.18.0 // indirect | ||||||
| 	golang.org/x/text v0.14.0 // indirect | 	golang.org/x/text v0.14.0 // indirect | ||||||
|  | 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| replace gorm.io/gorm => ../ | replace gorm.io/gorm => ../ | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ package tests_test | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"database/sql" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math/rand" | 	"math/rand" | ||||||
| 	"os" | 	"os" | ||||||
| @ -10,10 +11,15 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
| 	"gorm.io/driver/postgres" | 	"gorm.io/driver/postgres" | ||||||
|  | 
 | ||||||
| 	"gorm.io/gorm" | 	"gorm.io/gorm" | ||||||
|  | 	"gorm.io/gorm/clause" | ||||||
| 	"gorm.io/gorm/logger" | 	"gorm.io/gorm/logger" | ||||||
|  | 	"gorm.io/gorm/migrator" | ||||||
| 	"gorm.io/gorm/schema" | 	"gorm.io/gorm/schema" | ||||||
|  | 	"gorm.io/gorm/utils" | ||||||
| 	. "gorm.io/gorm/utils/tests" | 	. "gorm.io/gorm/utils/tests" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -984,7 +990,8 @@ func TestCurrentTimestamp(t *testing.T) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("AutoMigrate err:%v", err) | 		t.Fatalf("AutoMigrate err:%v", err) | ||||||
| 	} | 	} | ||||||
| 	AssertEqual(t, true, DB.Migrator().HasIndex(&CurrentTimestampTest{}, "time_at")) | 	AssertEqual(t, true, DB.Migrator().HasConstraint(&CurrentTimestampTest{}, "uni_current_timestamp_tests_time_at")) | ||||||
|  | 	AssertEqual(t, false, DB.Migrator().HasIndex(&CurrentTimestampTest{}, "time_at")) | ||||||
| 	AssertEqual(t, false, DB.Migrator().HasIndex(&CurrentTimestampTest{}, "time_at_2")) | 	AssertEqual(t, false, DB.Migrator().HasIndex(&CurrentTimestampTest{}, "time_at_2")) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -1046,7 +1053,8 @@ func TestUniqueColumn(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// not trigger alert column
 | 	// not trigger alert column
 | ||||||
| 	AssertEqual(t, true, DB.Migrator().HasIndex(&UniqueTest{}, "name")) | 	AssertEqual(t, true, DB.Migrator().HasConstraint(&UniqueTest{}, "uni_unique_tests_name")) | ||||||
|  | 	AssertEqual(t, false, DB.Migrator().HasIndex(&UniqueTest{}, "name")) | ||||||
| 	AssertEqual(t, false, DB.Migrator().HasIndex(&UniqueTest{}, "name_1")) | 	AssertEqual(t, false, DB.Migrator().HasIndex(&UniqueTest{}, "name_1")) | ||||||
| 	AssertEqual(t, false, DB.Migrator().HasIndex(&UniqueTest{}, "name_2")) | 	AssertEqual(t, false, DB.Migrator().HasIndex(&UniqueTest{}, "name_2")) | ||||||
| 
 | 
 | ||||||
| @ -1712,3 +1720,218 @@ func TestTableType(t *testing.T) { | |||||||
| 		t.Fatalf("expected comment %s got %s", tblComment, comment) | 		t.Fatalf("expected comment %s got %s", tblComment, comment) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func TestMigrateWithUniqueIndexAndUnique(t *testing.T) { | ||||||
|  | 	const table = "unique_struct" | ||||||
|  | 
 | ||||||
|  | 	checkField := func(model interface{}, fieldName string, unique bool, uniqueIndex string) { | ||||||
|  | 		stmt := &gorm.Statement{DB: DB} | ||||||
|  | 		err := stmt.Parse(model) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("%v: failed to parse schema, got error: %v", utils.FileWithLineNum(), err) | ||||||
|  | 		} | ||||||
|  | 		_ = stmt.Schema.ParseIndexes() | ||||||
|  | 		field := stmt.Schema.LookUpField(fieldName) | ||||||
|  | 		if field == nil { | ||||||
|  | 			t.Fatalf("%v: failed to find column %q", utils.FileWithLineNum(), fieldName) | ||||||
|  | 		} | ||||||
|  | 		if field.Unique != unique { | ||||||
|  | 			t.Fatalf("%v: %q column %q unique should be %v but got %v", utils.FileWithLineNum(), stmt.Schema.Table, fieldName, unique, field.Unique) | ||||||
|  | 		} | ||||||
|  | 		if field.UniqueIndex != uniqueIndex { | ||||||
|  | 			t.Fatalf("%v: %q column %q uniqueIndex should be %v but got %v", utils.FileWithLineNum(), stmt.Schema, fieldName, uniqueIndex, field.UniqueIndex) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	type ( // not unique
 | ||||||
|  | 		UniqueStruct1 struct { | ||||||
|  | 			Name string `gorm:"size:10"` | ||||||
|  | 		} | ||||||
|  | 		UniqueStruct2 struct { | ||||||
|  | 			Name string `gorm:"size:20"` | ||||||
|  | 		} | ||||||
|  | 	) | ||||||
|  | 	checkField(&UniqueStruct1{}, "name", false, "") | ||||||
|  | 	checkField(&UniqueStruct2{}, "name", false, "") | ||||||
|  | 
 | ||||||
|  | 	type ( // unique
 | ||||||
|  | 		UniqueStruct3 struct { | ||||||
|  | 			Name string `gorm:"size:30;unique"` | ||||||
|  | 		} | ||||||
|  | 		UniqueStruct4 struct { | ||||||
|  | 			Name string `gorm:"size:40;unique"` | ||||||
|  | 		} | ||||||
|  | 	) | ||||||
|  | 	checkField(&UniqueStruct3{}, "name", true, "") | ||||||
|  | 	checkField(&UniqueStruct4{}, "name", true, "") | ||||||
|  | 
 | ||||||
|  | 	type ( // uniqueIndex
 | ||||||
|  | 		UniqueStruct5 struct { | ||||||
|  | 			Name string `gorm:"size:50;uniqueIndex"` | ||||||
|  | 		} | ||||||
|  | 		UniqueStruct6 struct { | ||||||
|  | 			Name string `gorm:"size:60;uniqueIndex"` | ||||||
|  | 		} | ||||||
|  | 		UniqueStruct7 struct { | ||||||
|  | 			Name     string `gorm:"size:70;uniqueIndex:idx_us6_all_names"` | ||||||
|  | 			NickName string `gorm:"size:70;uniqueIndex:idx_us6_all_names"` | ||||||
|  | 		} | ||||||
|  | 	) | ||||||
|  | 	checkField(&UniqueStruct5{}, "name", false, "idx_unique_struct5_name") | ||||||
|  | 	checkField(&UniqueStruct6{}, "name", false, "idx_unique_struct6_name") | ||||||
|  | 
 | ||||||
|  | 	checkField(&UniqueStruct7{}, "name", false, "") | ||||||
|  | 	checkField(&UniqueStruct7{}, "nick_name", false, "") | ||||||
|  | 	checkField(&UniqueStruct7{}, "nick_name", false, "") | ||||||
|  | 
 | ||||||
|  | 	type UniqueStruct8 struct { // unique and uniqueIndex
 | ||||||
|  | 		Name string `gorm:"size:60;unique;index:my_us8_index,unique;"` | ||||||
|  | 	} | ||||||
|  | 	checkField(&UniqueStruct8{}, "name", true, "my_us8_index") | ||||||
|  | 
 | ||||||
|  | 	type TestCase struct { | ||||||
|  | 		name      string | ||||||
|  | 		from, to  interface{} | ||||||
|  | 		checkFunc func(t *testing.T) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	checkColumnType := func(t *testing.T, fieldName string, unique bool) { | ||||||
|  | 		columnTypes, err := DB.Migrator().ColumnTypes(table) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("%v: failed to get column types, got error: %v", utils.FileWithLineNum(), err) | ||||||
|  | 		} | ||||||
|  | 		var found gorm.ColumnType | ||||||
|  | 		for _, columnType := range columnTypes { | ||||||
|  | 			if columnType.Name() == fieldName { | ||||||
|  | 				found = columnType | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if found == nil { | ||||||
|  | 			t.Fatalf("%v: failed to find column type %q", utils.FileWithLineNum(), fieldName) | ||||||
|  | 		} | ||||||
|  | 		if actualUnique, ok := found.Unique(); !ok || actualUnique != unique { | ||||||
|  | 			t.Fatalf("%v: column %q unique should be %v but got %v", utils.FileWithLineNum(), fieldName, unique, actualUnique) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	checkIndex := func(t *testing.T, expected []gorm.Index) { | ||||||
|  | 		indexes, err := DB.Migrator().GetIndexes(table) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("%v: failed to get indexes, got error: %v", utils.FileWithLineNum(), err) | ||||||
|  | 		} | ||||||
|  | 		assert.ElementsMatch(t, expected, indexes) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	uniqueIndex := &migrator.Index{TableName: table, NameValue: DB.Config.NamingStrategy.IndexName(table, "name"), ColumnList: []string{"name"}, PrimaryKeyValue: sql.NullBool{Bool: false, Valid: true}, UniqueValue: sql.NullBool{Bool: true, Valid: true}} | ||||||
|  | 	myIndex := &migrator.Index{TableName: table, NameValue: "my_us8_index", ColumnList: []string{"name"}, PrimaryKeyValue: sql.NullBool{Bool: false, Valid: true}, UniqueValue: sql.NullBool{Bool: true, Valid: true}} | ||||||
|  | 	mulIndex := &migrator.Index{TableName: table, NameValue: "idx_us6_all_names", ColumnList: []string{"name", "nick_name"}, PrimaryKeyValue: sql.NullBool{Bool: false, Valid: true}, UniqueValue: sql.NullBool{Bool: true, Valid: true}} | ||||||
|  | 
 | ||||||
|  | 	var checkNotUnique, checkUnique, checkUniqueIndex, checkMyIndex, checkMulIndex func(t *testing.T) | ||||||
|  | 	// UniqueAffectedByUniqueIndex is true
 | ||||||
|  | 	if DB.Dialector.Name() == "mysql" { | ||||||
|  | 		uniqueConstraintIndex := &migrator.Index{TableName: table, NameValue: DB.Config.NamingStrategy.UniqueName(table, "name"), ColumnList: []string{"name"}, PrimaryKeyValue: sql.NullBool{Bool: false, Valid: true}, UniqueValue: sql.NullBool{Bool: true, Valid: true}} | ||||||
|  | 		checkNotUnique = func(t *testing.T) { | ||||||
|  | 			checkColumnType(t, "name", false) | ||||||
|  | 			checkIndex(t, nil) | ||||||
|  | 		} | ||||||
|  | 		checkUnique = func(t *testing.T) { | ||||||
|  | 			checkColumnType(t, "name", true) | ||||||
|  | 			checkIndex(t, []gorm.Index{uniqueConstraintIndex}) | ||||||
|  | 		} | ||||||
|  | 		checkUniqueIndex = func(t *testing.T) { | ||||||
|  | 			checkColumnType(t, "name", true) | ||||||
|  | 			checkIndex(t, []gorm.Index{uniqueIndex}) | ||||||
|  | 		} | ||||||
|  | 		checkMyIndex = func(t *testing.T) { | ||||||
|  | 			checkColumnType(t, "name", true) | ||||||
|  | 			checkIndex(t, []gorm.Index{uniqueConstraintIndex, myIndex}) | ||||||
|  | 		} | ||||||
|  | 		checkMulIndex = func(t *testing.T) { | ||||||
|  | 			checkColumnType(t, "name", false) | ||||||
|  | 			checkColumnType(t, "nick_name", false) | ||||||
|  | 			checkIndex(t, []gorm.Index{mulIndex}) | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		checkNotUnique = func(t *testing.T) { checkColumnType(t, "name", false) } | ||||||
|  | 		checkUnique = func(t *testing.T) { checkColumnType(t, "name", true) } | ||||||
|  | 		checkUniqueIndex = func(t *testing.T) { | ||||||
|  | 			checkColumnType(t, "name", false) | ||||||
|  | 			checkIndex(t, []gorm.Index{uniqueIndex}) | ||||||
|  | 		} | ||||||
|  | 		checkMyIndex = func(t *testing.T) { | ||||||
|  | 			checkColumnType(t, "name", true) | ||||||
|  | 			if !DB.Migrator().HasIndex(table, myIndex.Name()) { | ||||||
|  | 				t.Errorf("%v: should has index %s but not", utils.FileWithLineNum(), myIndex.Name()) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		checkMulIndex = func(t *testing.T) { | ||||||
|  | 			checkColumnType(t, "name", false) | ||||||
|  | 			checkColumnType(t, "nick_name", false) | ||||||
|  | 			if !DB.Migrator().HasIndex(table, mulIndex.Name()) { | ||||||
|  | 				t.Errorf("%v: should has index %s but not", utils.FileWithLineNum(), mulIndex.Name()) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tests := []TestCase{ | ||||||
|  | 		{name: "notUnique to notUnique", from: &UniqueStruct1{}, to: &UniqueStruct2{}, checkFunc: checkNotUnique}, | ||||||
|  | 		{name: "notUnique to unique", from: &UniqueStruct1{}, to: &UniqueStruct3{}, checkFunc: checkUnique}, | ||||||
|  | 		{name: "notUnique to uniqueIndex", from: &UniqueStruct1{}, to: &UniqueStruct5{}, checkFunc: checkUniqueIndex}, | ||||||
|  | 		{name: "notUnique to uniqueAndUniqueIndex", from: &UniqueStruct1{}, to: &UniqueStruct8{}, checkFunc: checkMyIndex}, | ||||||
|  | 		{name: "unique to unique", from: &UniqueStruct3{}, to: &UniqueStruct4{}, checkFunc: checkUnique}, | ||||||
|  | 		{name: "unique to uniqueIndex", from: &UniqueStruct3{}, to: &UniqueStruct5{}, checkFunc: checkUniqueIndex}, | ||||||
|  | 		{name: "unique to uniqueAndUniqueIndex", from: &UniqueStruct3{}, to: &UniqueStruct8{}, checkFunc: checkMyIndex}, | ||||||
|  | 		{name: "uniqueIndex to uniqueIndex", from: &UniqueStruct5{}, to: &UniqueStruct6{}, checkFunc: checkUniqueIndex}, | ||||||
|  | 		{name: "uniqueIndex to uniqueAndUniqueIndex", from: &UniqueStruct5{}, to: &UniqueStruct8{}, checkFunc: checkMyIndex}, | ||||||
|  | 		{name: "uniqueIndex to multi uniqueIndex", from: &UniqueStruct5{}, to: &UniqueStruct7{}, checkFunc: checkMulIndex}, | ||||||
|  | 	} | ||||||
|  | 	for _, test := range tests { | ||||||
|  | 		t.Run(test.name, func(t *testing.T) { | ||||||
|  | 			if err := DB.Migrator().DropTable(table); err != nil { | ||||||
|  | 				t.Fatalf("failed to drop table, got error: %v", err) | ||||||
|  | 			} | ||||||
|  | 			if err := DB.Table(table).AutoMigrate(test.from); err != nil { | ||||||
|  | 				t.Fatalf("failed to migrate table, got error: %v", err) | ||||||
|  | 			} | ||||||
|  | 			if err := DB.Table(table).AutoMigrate(test.to); err != nil { | ||||||
|  | 				t.Fatalf("failed to migrate table, got error: %v", err) | ||||||
|  | 			} | ||||||
|  | 			test.checkFunc(t) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if DB.Dialector.Name() != "sqlserver" { | ||||||
|  | 		// In SQLServer, If an index or constraint depends on the column,
 | ||||||
|  | 		// this column will not be able to run ALTER
 | ||||||
|  | 		// see https://stackoverflow.com/questions/19460912/the-object-df-is-dependent-on-column-changing-int-to-double/19461205#19461205
 | ||||||
|  | 		// may we need to create another PR to fix it, see https://github.com/go-gorm/sqlserver/pull/106
 | ||||||
|  | 		tests = []TestCase{ | ||||||
|  | 			{name: "unique to notUnique", from: &UniqueStruct3{}, to: &UniqueStruct1{}, checkFunc: checkNotUnique}, | ||||||
|  | 			{name: "uniqueIndex to notUnique", from: &UniqueStruct5{}, to: &UniqueStruct2{}, checkFunc: checkNotUnique}, | ||||||
|  | 			{name: "uniqueIndex to unique", from: &UniqueStruct5{}, to: &UniqueStruct3{}, checkFunc: checkUnique}, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if DB.Dialector.Name() == "mysql" { | ||||||
|  | 		compatibilityTests := []TestCase{ | ||||||
|  | 			{name: "oldUnique to notUnique", to: UniqueStruct1{}, checkFunc: checkNotUnique}, | ||||||
|  | 			{name: "oldUnique to unique", to: UniqueStruct3{}, checkFunc: checkUnique}, | ||||||
|  | 			{name: "oldUnique to uniqueIndex", to: UniqueStruct5{}, checkFunc: checkUniqueIndex}, | ||||||
|  | 			{name: "oldUnique to uniqueAndUniqueIndex", to: UniqueStruct8{}, checkFunc: checkMyIndex}, | ||||||
|  | 		} | ||||||
|  | 		for _, test := range compatibilityTests { | ||||||
|  | 			t.Run(test.name, func(t *testing.T) { | ||||||
|  | 				if err := DB.Migrator().DropTable(table); err != nil { | ||||||
|  | 					t.Fatalf("failed to drop table, got error: %v", err) | ||||||
|  | 				} | ||||||
|  | 				if err := DB.Exec("CREATE TABLE ? (`name` varchar(10) UNIQUE)", clause.Table{Name: table}).Error; err != nil { | ||||||
|  | 					t.Fatalf("failed to create table, got error: %v", err) | ||||||
|  | 				} | ||||||
|  | 				if err := DB.Table(table).AutoMigrate(test.to); err != nil { | ||||||
|  | 					t.Fatalf("failed to migrate table, got error: %v", err) | ||||||
|  | 				} | ||||||
|  | 				test.checkFunc(t) | ||||||
|  | 			}) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 black-06
						black-06