From 373bcf7aca01ef76c8ba5c3bc1ff191b020afc7b Mon Sep 17 00:00:00 2001 From: Cr <631807682@qq.com> Date: Mon, 9 May 2022 10:07:18 +0800 Subject: [PATCH 1/3] fix: many2many auto migrate (#5322) * fix: many2many auto migrate * fix: uuid ossp --- schema/relationship.go | 6 ++++-- schema/utils.go | 9 +++++++++ tests/migrate_test.go | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/schema/relationship.go b/schema/relationship.go index b5100897..0aa33e51 100644 --- a/schema/relationship.go +++ b/schema/relationship.go @@ -235,7 +235,8 @@ func (schema *Schema) buildMany2ManyRelation(relation *Relationship, field *Fiel Name: joinFieldName, PkgPath: ownField.StructField.PkgPath, Type: ownField.StructField.Type, - Tag: removeSettingFromTag(ownField.StructField.Tag, "column", "autoincrement", "index", "unique", "uniqueindex"), + Tag: removeSettingFromTag(appendSettingFromTag(ownField.StructField.Tag, "primaryKey"), + "column", "autoincrement", "index", "unique", "uniqueindex"), }) } @@ -258,7 +259,8 @@ func (schema *Schema) buildMany2ManyRelation(relation *Relationship, field *Fiel Name: joinFieldName, PkgPath: relField.StructField.PkgPath, Type: relField.StructField.Type, - Tag: removeSettingFromTag(relField.StructField.Tag, "column", "autoincrement", "index", "unique", "uniqueindex"), + Tag: removeSettingFromTag(appendSettingFromTag(relField.StructField.Tag, "primaryKey"), + "column", "autoincrement", "index", "unique", "uniqueindex"), }) } diff --git a/schema/utils.go b/schema/utils.go index 2720c530..acf1a739 100644 --- a/schema/utils.go +++ b/schema/utils.go @@ -2,6 +2,7 @@ package schema import ( "context" + "fmt" "reflect" "regexp" "strings" @@ -59,6 +60,14 @@ func removeSettingFromTag(tag reflect.StructTag, names ...string) reflect.Struct return tag } +func appendSettingFromTag(tag reflect.StructTag, value string) reflect.StructTag { + t := tag.Get("gorm") + if strings.Contains(t, value) { + return tag + } + return reflect.StructTag(fmt.Sprintf(`gorm:"%s;%s"`, value, t)) +} + // GetRelationsValues get relations's values from a reflect value func GetRelationsValues(ctx context.Context, reflectValue reflect.Value, rels []*Relationship) (reflectResults reflect.Value) { for _, rel := range rels { diff --git a/tests/migrate_test.go b/tests/migrate_test.go index 28ee28cb..f862eda0 100644 --- a/tests/migrate_test.go +++ b/tests/migrate_test.go @@ -657,3 +657,39 @@ func TestMigrateWithSpecialName(t *testing.T) { AssertEqual(t, true, DB.Migrator().HasTable("coupon_product_1")) AssertEqual(t, true, DB.Migrator().HasTable("coupon_product_2")) } + +// https://github.com/go-gorm/gorm/issues/5320 +func TestPrimarykeyID(t *testing.T) { + if DB.Dialector.Name() != "postgres" { + return + } + + type MissPKLanguage struct { + ID string `gorm:"type:uuid;default:uuid_generate_v4()"` + Name string + } + + type MissPKUser struct { + ID string `gorm:"type:uuid;default:uuid_generate_v4()"` + MissPKLanguages []MissPKLanguage `gorm:"many2many:miss_pk_user_languages;"` + } + + var err error + err = DB.Migrator().DropTable(&MissPKUser{}, &MissPKLanguage{}) + if err != nil { + t.Fatalf("DropTable err:%v", err) + } + + DB.Exec(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp";`) + + err = DB.AutoMigrate(&MissPKUser{}, &MissPKLanguage{}) + if err != nil { + t.Fatalf("AutoMigrate err:%v", err) + } + + // patch + err = DB.AutoMigrate(&MissPKUser{}, &MissPKLanguage{}) + if err != nil { + t.Fatalf("AutoMigrate err:%v", err) + } +} From f5e77aab2fd3886f8743d6c9da87d5171f31a521 Mon Sep 17 00:00:00 2001 From: black-06 Date: Tue, 17 May 2022 10:59:53 +0800 Subject: [PATCH 2/3] fix: quote index when creating table (#5331) --- migrator/migrator.go | 2 +- tests/migrate_test.go | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/migrator/migrator.go b/migrator/migrator.go index d4989410..757ab949 100644 --- a/migrator/migrator.go +++ b/migrator/migrator.go @@ -223,7 +223,7 @@ func (m Migrator) CreateTable(values ...interface{}) error { } createTableSQL += "," - values = append(values, clause.Expr{SQL: idx.Name}, tx.Migrator().(BuildIndexOptionsInterface).BuildIndexOptions(idx.Fields, stmt)) + values = append(values, clause.Column{Name: idx.Name}, tx.Migrator().(BuildIndexOptionsInterface).BuildIndexOptions(idx.Fields, stmt)) } } diff --git a/tests/migrate_test.go b/tests/migrate_test.go index f862eda0..12eb8ed0 100644 --- a/tests/migrate_test.go +++ b/tests/migrate_test.go @@ -262,6 +262,25 @@ func TestMigrateTable(t *testing.T) { } } +func TestMigrateWithQuotedIndex(t *testing.T) { + if DB.Dialector.Name() != "mysql" { + t.Skip() + } + + type QuotedIndexStruct struct { + gorm.Model + Name string `gorm:"size:255;index:AS"` // AS is one of MySQL reserved words + } + + if err := DB.Migrator().DropTable(&QuotedIndexStruct{}); err != nil { + t.Fatalf("Failed to drop table, got error %v", err) + } + + if err := DB.AutoMigrate(&QuotedIndexStruct{}); err != nil { + t.Fatalf("Failed to auto migrate, but got error %v", err) + } +} + func TestMigrateIndexes(t *testing.T) { type IndexStruct struct { gorm.Model From 7496c3a56eb4a26679a0a47db092e51379a98ff5 Mon Sep 17 00:00:00 2001 From: Cr <631807682@qq.com> Date: Tue, 17 May 2022 14:13:41 +0800 Subject: [PATCH 3/3] fix: trx in hooks clone stmt (#5338) * fix: trx in hooks * chore: format by gofumpt --- finisher_api.go | 3 +-- tests/transaction_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/finisher_api.go b/finisher_api.go index 663d532b..da4ef8f7 100644 --- a/finisher_api.go +++ b/finisher_api.go @@ -589,8 +589,7 @@ func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err er } }() } - - err = fc(db.Session(&Session{})) + err = fc(db.Session(&Session{NewDB: db.clone == 1})) } else { tx := db.Begin(opts...) if tx.Error != nil { diff --git a/tests/transaction_test.go b/tests/transaction_test.go index 4e4b6149..0ac04a04 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -367,3 +367,33 @@ func TestTransactionOnClosedConn(t *testing.T) { t.Errorf("should returns error when commit with closed conn, got error %v", err) } } + +func TestTransactionWithHooks(t *testing.T) { + user := GetUser("tTestTransactionWithHooks", Config{Account: true}) + DB.Create(&user) + + var err error + err = DB.Transaction(func(tx *gorm.DB) error { + return tx.Model(&User{}).Limit(1).Transaction(func(tx2 *gorm.DB) error { + return tx2.Scan(&User{}).Error + }) + }) + + if err != nil { + t.Error(err) + } + + // method with hooks + err = DB.Transaction(func(tx1 *gorm.DB) error { + // callMethod do + tx2 := tx1.Find(&User{}).Session(&gorm.Session{NewDB: true}) + // trx in hooks + return tx2.Transaction(func(tx3 *gorm.DB) error { + return tx3.Where("user_id", user.ID).Delete(&Account{}).Error + }) + }) + + if err != nil { + t.Error(err) + } +}