Test migrate with comment and check created constraints
This commit is contained in:
parent
fee1e4aafd
commit
d0764bead1
@ -2,6 +2,9 @@ package gorm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Migrator returns migrator
|
// Migrator returns migrator
|
||||||
@ -27,6 +30,7 @@ type Migrator interface {
|
|||||||
|
|
||||||
// Database
|
// Database
|
||||||
CurrentDatabase() string
|
CurrentDatabase() string
|
||||||
|
FullDataTypeOf(*schema.Field) clause.Expr
|
||||||
|
|
||||||
// Tables
|
// Tables
|
||||||
CreateTable(dst ...interface{}) error
|
CreateTable(dst ...interface{}) error
|
||||||
|
@ -18,9 +18,8 @@ type Migrator struct {
|
|||||||
|
|
||||||
// Config schema config
|
// Config schema config
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CreateIndexAfterCreateTable bool
|
CreateIndexAfterCreateTable bool
|
||||||
AllowDeferredConstraintsWhenAutoMigrate bool
|
DB *gorm.DB
|
||||||
DB *gorm.DB
|
|
||||||
gorm.Dialector
|
gorm.Dialector
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,13 +119,13 @@ func (m Migrator) AutoMigrate(values ...interface{}) error {
|
|||||||
if rel.JoinTable != nil {
|
if rel.JoinTable != nil {
|
||||||
joinValue := reflect.New(rel.JoinTable.ModelType).Interface()
|
joinValue := reflect.New(rel.JoinTable.ModelType).Interface()
|
||||||
if !tx.Migrator().HasTable(rel.JoinTable.Table) {
|
if !tx.Migrator().HasTable(rel.JoinTable.Table) {
|
||||||
defer func() {
|
defer func(table string, joinValue interface{}) {
|
||||||
errr = tx.Table(rel.JoinTable.Table).Migrator().CreateTable(joinValue)
|
errr = tx.Table(table).Migrator().CreateTable(joinValue)
|
||||||
}()
|
}(rel.JoinTable.Table, joinValue)
|
||||||
} else {
|
} else {
|
||||||
defer func() {
|
defer func(table string, joinValue interface{}) {
|
||||||
errr = tx.Table(rel.JoinTable.Table).Migrator().AutoMigrate(joinValue)
|
errr = tx.Table(table).Migrator().AutoMigrate(joinValue)
|
||||||
}()
|
}(rel.JoinTable.Table, joinValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,7 +153,7 @@ func (m Migrator) CreateTable(values ...interface{}) error {
|
|||||||
field := stmt.Schema.FieldsByDBName[dbName]
|
field := stmt.Schema.FieldsByDBName[dbName]
|
||||||
createTableSQL += fmt.Sprintf("? ?")
|
createTableSQL += fmt.Sprintf("? ?")
|
||||||
hasPrimaryKeyInDataType = hasPrimaryKeyInDataType || strings.Contains(strings.ToUpper(string(field.DataType)), "PRIMARY KEY")
|
hasPrimaryKeyInDataType = hasPrimaryKeyInDataType || strings.Contains(strings.ToUpper(string(field.DataType)), "PRIMARY KEY")
|
||||||
values = append(values, clause.Column{Name: dbName}, m.FullDataTypeOf(field))
|
values = append(values, clause.Column{Name: dbName}, m.DB.Migrator().FullDataTypeOf(field))
|
||||||
createTableSQL += ","
|
createTableSQL += ","
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,9 +169,9 @@ func (m Migrator) CreateTable(values ...interface{}) error {
|
|||||||
|
|
||||||
for _, idx := range stmt.Schema.ParseIndexes() {
|
for _, idx := range stmt.Schema.ParseIndexes() {
|
||||||
if m.CreateIndexAfterCreateTable {
|
if m.CreateIndexAfterCreateTable {
|
||||||
defer func() {
|
defer func(value interface{}, name string) {
|
||||||
errr = tx.Migrator().CreateIndex(value, idx.Name)
|
errr = tx.Migrator().CreateIndex(value, name)
|
||||||
}()
|
}(value, idx.Name)
|
||||||
} else {
|
} else {
|
||||||
createTableSQL += "INDEX ? ?,"
|
createTableSQL += "INDEX ? ?,"
|
||||||
values = append(values, clause.Expr{SQL: idx.Name}, tx.Migrator().(BuildIndexOptionsInterface).BuildIndexOptions(idx.Fields, stmt))
|
values = append(values, clause.Expr{SQL: idx.Name}, tx.Migrator().(BuildIndexOptionsInterface).BuildIndexOptions(idx.Fields, stmt))
|
||||||
@ -277,7 +276,7 @@ func (m Migrator) AddColumn(value interface{}, field string) error {
|
|||||||
if field := stmt.Schema.LookUpField(field); field != nil {
|
if field := stmt.Schema.LookUpField(field); field != nil {
|
||||||
return m.DB.Exec(
|
return m.DB.Exec(
|
||||||
"ALTER TABLE ? ADD ? ?",
|
"ALTER TABLE ? ADD ? ?",
|
||||||
clause.Table{Name: stmt.Table}, clause.Column{Name: field.DBName}, m.FullDataTypeOf(field),
|
clause.Table{Name: stmt.Table}, clause.Column{Name: field.DBName}, m.DB.Migrator().FullDataTypeOf(field),
|
||||||
).Error
|
).Error
|
||||||
}
|
}
|
||||||
return fmt.Errorf("failed to look up field with name: %s", field)
|
return fmt.Errorf("failed to look up field with name: %s", field)
|
||||||
@ -301,7 +300,7 @@ func (m Migrator) AlterColumn(value interface{}, field string) error {
|
|||||||
if field := stmt.Schema.LookUpField(field); field != nil {
|
if field := stmt.Schema.LookUpField(field); field != nil {
|
||||||
return m.DB.Exec(
|
return m.DB.Exec(
|
||||||
"ALTER TABLE ? ALTER COLUMN ? TYPE ?",
|
"ALTER TABLE ? ALTER COLUMN ? TYPE ?",
|
||||||
clause.Table{Name: stmt.Table}, clause.Column{Name: field.DBName}, m.FullDataTypeOf(field),
|
clause.Table{Name: stmt.Table}, clause.Column{Name: field.DBName}, m.DB.Migrator().FullDataTypeOf(field),
|
||||||
).Error
|
).Error
|
||||||
}
|
}
|
||||||
return fmt.Errorf("failed to look up field with name: %s", field)
|
return fmt.Errorf("failed to look up field with name: %s", field)
|
||||||
@ -436,7 +435,7 @@ func (m Migrator) HasConstraint(value interface{}, name string) bool {
|
|||||||
m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
m.RunWithValue(value, func(stmt *gorm.Statement) error {
|
||||||
currentDatabase := m.DB.Migrator().CurrentDatabase()
|
currentDatabase := m.DB.Migrator().CurrentDatabase()
|
||||||
return m.DB.Raw(
|
return m.DB.Raw(
|
||||||
"SELECT count(*) FROM INFORMATION_SCHEMA.referential_constraints WHERE constraint_schema = ? AND table_name = ? AND constraint_name = ?",
|
"SELECT count(*) FROM INFORMATION_SCHEMA.table_constraints WHERE constraint_schema = ? AND table_name = ? AND constraint_name = ?",
|
||||||
currentDatabase, stmt.Table, name,
|
currentDatabase, stmt.Table, name,
|
||||||
).Row().Scan(&count)
|
).Row().Scan(&count)
|
||||||
})
|
})
|
||||||
@ -481,11 +480,6 @@ func (m Migrator) CreateIndex(value interface{}, name string) error {
|
|||||||
}
|
}
|
||||||
createIndexSQL += "INDEX ? ON ??"
|
createIndexSQL += "INDEX ? ON ??"
|
||||||
|
|
||||||
if idx.Comment != "" {
|
|
||||||
values = append(values, idx.Comment)
|
|
||||||
createIndexSQL += " COMMENT ?"
|
|
||||||
}
|
|
||||||
|
|
||||||
if idx.Type != "" {
|
if idx.Type != "" {
|
||||||
createIndexSQL += " USING " + idx.Type
|
createIndexSQL += " USING " + idx.Type
|
||||||
}
|
}
|
||||||
|
@ -53,16 +53,18 @@ func (schema *Schema) ParseIndexes() map[string]Index {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (schema *Schema) LookIndex(name string) *Index {
|
func (schema *Schema) LookIndex(name string) *Index {
|
||||||
indexes := schema.ParseIndexes()
|
if schema != nil {
|
||||||
for _, index := range indexes {
|
indexes := schema.ParseIndexes()
|
||||||
if index.Name == name {
|
for _, index := range indexes {
|
||||||
return &index
|
if index.Name == name {
|
||||||
}
|
|
||||||
|
|
||||||
for _, field := range index.Fields {
|
|
||||||
if field.Name == name {
|
|
||||||
return &index
|
return &index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, field := range index.Fields {
|
||||||
|
if field.Name == name {
|
||||||
|
return &index
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ require (
|
|||||||
github.com/jinzhu/now v1.1.1
|
github.com/jinzhu/now v1.1.1
|
||||||
github.com/lib/pq v1.6.0
|
github.com/lib/pq v1.6.0
|
||||||
gorm.io/driver/mysql v0.2.3
|
gorm.io/driver/mysql v0.2.3
|
||||||
gorm.io/driver/postgres v0.2.2
|
gorm.io/driver/postgres v0.2.3
|
||||||
gorm.io/driver/sqlite v1.0.6
|
gorm.io/driver/sqlite v1.0.7
|
||||||
gorm.io/driver/sqlserver v0.2.2
|
gorm.io/driver/sqlserver v0.2.2
|
||||||
gorm.io/gorm v0.2.9
|
gorm.io/gorm v0.2.9
|
||||||
)
|
)
|
||||||
|
@ -15,6 +15,8 @@ func TestMigrate(t *testing.T) {
|
|||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
rand.Shuffle(len(allModels), func(i, j int) { allModels[i], allModels[j] = allModels[j], allModels[i] })
|
rand.Shuffle(len(allModels), func(i, j int) { allModels[i], allModels[j] = allModels[j], allModels[i] })
|
||||||
|
|
||||||
|
DB.Migrator().DropTable("user_speaks", "user_friends")
|
||||||
|
|
||||||
if err := DB.Migrator().DropTable(allModels...); err != nil {
|
if err := DB.Migrator().DropTable(allModels...); err != nil {
|
||||||
t.Fatalf("Failed to drop table, got error %v", err)
|
t.Fatalf("Failed to drop table, got error %v", err)
|
||||||
}
|
}
|
||||||
@ -28,6 +30,36 @@ func TestMigrate(t *testing.T) {
|
|||||||
t.Fatalf("Failed to create table for %#v---", m)
|
t.Fatalf("Failed to create table for %#v---", m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, indexes := range [][2]string{
|
||||||
|
{"user_speaks", "fk_user_speaks_user"},
|
||||||
|
{"user_speaks", "fk_user_speaks_language"},
|
||||||
|
{"user_friends", "fk_user_friends_user"},
|
||||||
|
{"user_friends", "fk_user_friends_friends"},
|
||||||
|
{"accounts", "fk_users_account"},
|
||||||
|
{"users", "fk_users_team"},
|
||||||
|
{"users", "fk_users_manager"},
|
||||||
|
{"users", "fk_users_company"},
|
||||||
|
} {
|
||||||
|
if !DB.Migrator().HasConstraint(indexes[0], indexes[1]) {
|
||||||
|
t.Fatalf("Failed to find index for many2many for %v %v", indexes[0], indexes[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMigrateWithComment(t *testing.T) {
|
||||||
|
type UserWithComment struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string `gorm:"size:111;index:,comment:这是一个index;comment:this is a 字段"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DB.Migrator().DropTable(&UserWithComment{}); err != nil {
|
||||||
|
t.Fatalf("Failed to drop table, got error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DB.AutoMigrate(&UserWithComment{}); err != nil {
|
||||||
|
t.Fatalf("Failed to auto migrate, but got error %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTable(t *testing.T) {
|
func TestTable(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user