From 66388cf40b0221c0b889c431254b6b3873bffd1c Mon Sep 17 00:00:00 2001 From: Wendell Sun Date: Mon, 11 Oct 2021 13:44:18 +0800 Subject: [PATCH] fix: automigrate error caused by indexes while using dynamic table name #4752 --- migrator/migrator.go | 19 +++++++++++++------ tests/migrate_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/migrator/migrator.go b/migrator/migrator.go index 48db151e..c5e664c5 100644 --- a/migrator/migrator.go +++ b/migrator/migrator.go @@ -687,10 +687,10 @@ func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []i parsedSchemas = map[*schema.Schema]bool{} valuesMap = map[string]Dependency{} insertIntoOrderedList func(name string) - parseDependence func(value interface{}, addToList bool) + parseDependence func(value interface{}, addToList, useSchemaTable bool) ) - parseDependence = func(value interface{}, addToList bool) { + parseDependence = func(value interface{}, addToList, useSchemaTable bool) { dep := Dependency{ Statement: &gorm.Statement{DB: m.DB, Dest: value}, } @@ -698,6 +698,13 @@ func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []i if err := dep.Parse(value); err != nil { m.DB.Logger.Error(context.Background(), "failed to parse value %#v, got error %v", value, err) } + + if useSchemaTable { + if m.DB.Statement != nil && m.DB.Statement.Table != "" { + dep.Schema.Table = m.DB.Statement.Table + } + } + if _, ok := parsedSchemas[dep.Statement.Schema]; ok { return } @@ -719,9 +726,9 @@ func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []i dep.Depends = append(dep.Depends, rel.FieldSchema) } else { fieldValue := reflect.New(rel.FieldSchema.ModelType).Interface() - parseDependence(fieldValue, autoAdd) + parseDependence(fieldValue, autoAdd, false) } - parseDependence(joinValue, autoAdd) + parseDependence(joinValue, autoAdd, false) }(rel, reflect.New(rel.JoinTable.ModelType).Interface()) } } @@ -745,7 +752,7 @@ func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []i if _, ok := valuesMap[d.Table]; ok { insertIntoOrderedList(d.Table) } else { - parseDependence(reflect.New(d.ModelType).Interface(), autoAdd) + parseDependence(reflect.New(d.ModelType).Interface(), autoAdd, false) insertIntoOrderedList(d.Table) } } @@ -758,7 +765,7 @@ func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []i if v, ok := value.(string); ok { results = append(results, v) } else { - parseDependence(value, true) + parseDependence(value, true, true) } } diff --git a/tests/migrate_test.go b/tests/migrate_test.go index ba271478..8c0fb6e7 100644 --- a/tests/migrate_test.go +++ b/tests/migrate_test.go @@ -381,3 +381,40 @@ func TestMigrateConstraint(t *testing.T) { } } } + +type NewUser struct { + gorm.Model + Name string `gorm:"index"` + Table string `gorm:"-"` +} + +func TestMigrateIndexesWithDynamicTableName(t *testing.T) { + tableNameFunc := func(v string) string { + return "newuser_" + strings.ToLower(v) + } + userTableFunc := func(u *NewUser) func(*gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + return db.Table(tableNameFunc(u.Table)) + } + } + + tableName := []string{"a", "b", "c"} + for _, v := range tableName { + nu := &NewUser{ + Table: v, + } + + tableName := tableNameFunc(nu.Table) + m := DB.Scopes(userTableFunc(nu)).Migrator() + if err := m.AutoMigrate(&nu); err != nil { + t.Fatalf("Failed to create table for %#v---", tableName) + } + + if !m.HasTable(tableName) { + t.Fatalf("Failed to create table for %#v---", tableName) + } + if !m.HasIndex(&NewUser{}, "Name") { + t.Fatalf("Should find index for %s's name after AutoMigrate", tableName) + } + } +}