diff --git a/go.mod b/go.mod index c01d599..3da90e8 100644 --- a/go.mod +++ b/go.mod @@ -5,5 +5,5 @@ go 1.14 require ( github.com/jackc/pgx/v4 v4.16.1 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect - gorm.io/gorm v1.23.4 + gorm.io/gorm v1.23.6 ) diff --git a/go.sum b/go.sum index 230f3f7..f43455a 100644 --- a/go.sum +++ b/go.sum @@ -186,4 +186,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/gorm v1.23.4 h1:1BKWM67O6CflSLcwGQR7ccfmC4ebOxQrTfOQGRE9wjg= gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.23.6 h1:KFLdNgri4ExFFGTRGGFWON2P1ZN28+9SJRN8voOoYe0= +gorm.io/gorm v1.23.6/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/migrator.go b/migrator.go index ca91802..210c2cb 100644 --- a/migrator.go +++ b/migrator.go @@ -13,6 +13,27 @@ import ( "gorm.io/gorm/schema" ) +const indexSql = ` +select + t.relname as table_name, + i.relname as index_name, + a.attname as column_name, + ix.indisunique as non_unique, + ix.indisprimary as primary +from + pg_class t, + pg_class i, + pg_index ix, + pg_attribute a +where + t.oid = ix.indrelid + and i.oid = ix.indexrelid + and a.attrelid = t.oid + and a.attnum = ANY(ix.indkey) + and t.relkind = 'r' + and t.relname = ? +` + type Migrator struct { migrator.Migrator } @@ -586,3 +607,53 @@ func (m Migrator) getColumnSequenceName(tx *gorm.DB, stmt *gorm.Statement, field ) return } + +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) + scanErr := m.DB.Raw(indexSql, stmt.Table).Scan(&result).Error + if scanErr != nil { + return scanErr + } + indexMap := groupByIndexName(result) + for _, idx := range indexMap { + tempIdx := &migrator.Index{ + TableName: idx[0].TableName, + NameValue: idx[0].IndexName, + PrimaryKeyValue: sql.NullBool{ + Bool: idx[0].Primary, + Valid: true, + }, + UniqueValue: sql.NullBool{ + Bool: idx[0].NonUnique, + Valid: true, + }, + } + for _, x := range idx { + tempIdx.ColumnList = append(tempIdx.ColumnList, x.ColumnName) + } + indexes = append(indexes, tempIdx) + } + return nil + }) + return indexes, err +} + +// Index table index info +type Index struct { + TableName string `gorm:"column:table_name"` + ColumnName string `gorm:"column:column_name"` + IndexName string `gorm:"column:index_name"` + NonUnique bool `gorm:"column:non_unique"` + Primary bool `gorm:"column:primary"` +} + +func groupByIndexName(indexList []*Index) map[string][]*Index { + columnIndexMap := make(map[string][]*Index, len(indexList)) + for _, idx := range indexList { + columnIndexMap[idx.IndexName] = append(columnIndexMap[idx.IndexName], idx) + } + return columnIndexMap +}