diff --git a/go.mod b/go.mod index 291611b..b5747bf 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/microsoft/go-mssqldb v1.6.0 - gorm.io/gorm v1.25.2-0.20230610234218-206613868439 + gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde ) diff --git a/go.sum b/go.sum index b79d5c4..a21ee96 100644 --- a/go.sum +++ b/go.sum @@ -136,5 +136,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/gorm v1.25.2-0.20230610234218-206613868439 h1:LerZWOlV0e/6u9dEoVhe7Ehg+o7QvQKIxrI4Ccb2aV8= -gorm.io/gorm v1.25.2-0.20230610234218-206613868439/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde h1:9DShaph9qhkIYw7QF91I/ynrr4cOO2PZra2PFD7Mfeg= +gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= diff --git a/migrator.go b/migrator.go index 75a288c..bea2422 100644 --- a/migrator.go +++ b/migrator.go @@ -12,6 +12,22 @@ import ( "gorm.io/gorm/schema" ) +const indexSQL = ` +SELECT + i.name AS index_name, + i.is_unique, + i.is_primary_key, + col.name AS column_name +FROM + sys.indexes i + LEFT JOIN sys.index_columns ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id + LEFT JOIN sys.all_columns col ON col.column_id = ic.column_id AND col.object_id = ic.object_id +WHERE + i.name IS NOT NULL + AND i.is_unique_constraint = 0 + AND i.object_id = OBJECT_ID(?) +` + type Migrator struct { migrator.Migrator } @@ -348,14 +364,50 @@ func (m Migrator) RenameIndex(value interface{}, oldName, newName string) error }) } +type Index struct { + TableName string + ColumnName string + IndexName string + IsUnique sql.NullBool + IsPrimaryKey sql.NullBool +} + +func (m Migrator) GetIndexes(value interface{}) ([]gorm.Index, error) { + indexes := make([]gorm.Index, 0) + err := m.RunWithValue(value, func(stmt *gorm.Statement) error { + result := make([]*Index, 0) + if err := m.DB.Raw(indexSQL, stmt.Table).Scan(&result).Error; err != nil { + return err + } + indexMap := make(map[string]*migrator.Index) + for _, r := range result { + idx, ok := indexMap[r.IndexName] + if !ok { + idx = &migrator.Index{ + TableName: stmt.Table, + NameValue: r.IndexName, + ColumnList: nil, + PrimaryKeyValue: r.IsPrimaryKey, + UniqueValue: r.IsUnique, + } + } + idx.ColumnList = append(idx.ColumnList, r.ColumnName) + indexMap[r.IndexName] = idx + } + for _, idx := range indexMap { + indexes = append(indexes, idx) + } + return nil + }) + return indexes, err +} + func (m Migrator) HasConstraint(value interface{}, name string) bool { var count int64 m.RunWithValue(value, func(stmt *gorm.Statement) error { - constraint, chk, table := m.GuessConstraintAndTable(stmt, name) + constraint, table := m.GuessConstraintInterfaceAndTable(stmt, name) if constraint != nil { - name = constraint.Name - } else if chk != nil { - name = chk.Name + name = constraint.GetName() } tableCatalog, schema, tableName := splitFullQualifiedName(table)