diff --git a/migration_test.go b/migration_test.go index 3e385466..b344514a 100644 --- a/migration_test.go +++ b/migration_test.go @@ -367,3 +367,68 @@ func TestAutoMigration(t *testing.T) { t.Error("Big Emails should be saved and fetched correctly") } } + +type MultipleIndexes struct { + ID int64 + UserID int64 `sql:"unique_index:uix_multipleindexes_user_name,uix_multipleindexes_user_email;index:idx_multipleindexes_user_other"` + Name string `sql:"unique_index:uix_multipleindexes_user_name"` + Email string `sql:"unique_index:,uix_multipleindexes_user_email"` + Other string `sql:"index:,idx_multipleindexes_user_other"` +} + +func TestMultipleIndexes(t *testing.T) { + if err := DB.DropTableIfExists(&MultipleIndexes{}).Error; err != nil { + fmt.Printf("Got error when try to delete table multiple_indexes, %+v\n", err) + } + + DB.Debug().AutoMigrate(&MultipleIndexes{}) + if err := DB.AutoMigrate(&BigEmail{}).Error; err != nil { + t.Errorf("Auto Migrate should not raise any error") + } + + DB.Save(&MultipleIndexes{UserID: 1, Name: "jinzhu", Email: "jinzhu@example.org", Other: "foo"}) + + scope := DB.NewScope(&MultipleIndexes{}) + if !scope.Dialect().HasIndex(scope.TableName(), "uix_multipleindexes_user_name") { + t.Errorf("Failed to create index") + } + + if !scope.Dialect().HasIndex(scope.TableName(), "uix_multipleindexes_user_email") { + t.Errorf("Failed to create index") + } + + if !scope.Dialect().HasIndex(scope.TableName(), "uix_multiple_indexes_email") { + t.Errorf("Failed to create index") + } + + if !scope.Dialect().HasIndex(scope.TableName(), "idx_multipleindexes_user_other") { + t.Errorf("Failed to create index") + } + + if !scope.Dialect().HasIndex(scope.TableName(), "idx_multiple_indexes_other") { + t.Errorf("Failed to create index") + } + + var mutipleIndexes MultipleIndexes + DB.First(&mutipleIndexes, "name = ?", "jinzhu") + if mutipleIndexes.Email != "jinzhu@example.org" || mutipleIndexes.Name != "jinzhu" { + t.Error("MutipleIndexes should be saved and fetched correctly") + } + + // Check unique constraints + if err := DB.Save(&MultipleIndexes{UserID: 1, Name: "name1", Email: "jinzhu@example.org", Other: "foo"}).Error; err == nil { + t.Error("MultipleIndexes unique index failed") + } + + if err := DB.Save(&MultipleIndexes{UserID: 1, Name: "name1", Email: "foo@example.org", Other: "foo"}).Error; err != nil { + t.Error("MultipleIndexes unique index failed") + } + + if err := DB.Save(&MultipleIndexes{UserID: 2, Name: "name1", Email: "jinzhu@example.org", Other: "foo"}).Error; err == nil { + t.Error("MultipleIndexes unique index failed") + } + + if err := DB.Save(&MultipleIndexes{UserID: 2, Name: "name1", Email: "foo2@example.org", Other: "foo"}).Error; err != nil { + t.Error("MultipleIndexes unique index failed") + } +} diff --git a/scope.go b/scope.go index 1e755626..f4a21548 100644 --- a/scope.go +++ b/scope.go @@ -1157,17 +1157,25 @@ func (scope *Scope) autoIndex() *Scope { for _, field := range scope.GetStructFields() { if name, ok := field.TagSettings["INDEX"]; ok { - if name == "INDEX" { - name = fmt.Sprintf("idx_%v_%v", scope.TableName(), field.DBName) + names := strings.Split(name, ",") + + for _, name := range names { + if name == "INDEX" || name == "" { + name = fmt.Sprintf("idx_%v_%v", scope.TableName(), field.DBName) + } + indexes[name] = append(indexes[name], field.DBName) } - indexes[name] = append(indexes[name], field.DBName) } if name, ok := field.TagSettings["UNIQUE_INDEX"]; ok { - if name == "UNIQUE_INDEX" { - name = fmt.Sprintf("uix_%v_%v", scope.TableName(), field.DBName) + names := strings.Split(name, ",") + + for _, name := range names { + if name == "UNIQUE_INDEX" || name == "" { + name = fmt.Sprintf("uix_%v_%v", scope.TableName(), field.DBName) + } + uniqueIndexes[name] = append(uniqueIndexes[name], field.DBName) } - uniqueIndexes[name] = append(uniqueIndexes[name], field.DBName) } }