123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- package gorm_test
- import (
- "testing"
- "time"
- "github.com/jinzhu/gorm"
- )
- type CustomizeColumn struct {
- ID int64 `gorm:"column:mapped_id; primary_key:yes"`
- Name string `gorm:"column:mapped_name"`
- Date *time.Time `gorm:"column:mapped_time"`
- }
- // Make sure an ignored field does not interfere with another field's custom
- // column name that matches the ignored field.
- type CustomColumnAndIgnoredFieldClash struct {
- Body string `sql:"-"`
- RawBody string `gorm:"column:body"`
- }
- func TestCustomizeColumn(t *testing.T) {
- col := "mapped_name"
- DB.DropTable(&CustomizeColumn{})
- DB.AutoMigrate(&CustomizeColumn{})
- scope := DB.NewScope(&CustomizeColumn{})
- if !scope.Dialect().HasColumn(scope.TableName(), col) {
- t.Errorf("CustomizeColumn should have column %s", col)
- }
- col = "mapped_id"
- if scope.PrimaryKey() != col {
- t.Errorf("CustomizeColumn should have primary key %s, but got %q", col, scope.PrimaryKey())
- }
- expected := "foo"
- now := time.Now()
- cc := CustomizeColumn{ID: 666, Name: expected, Date: &now}
- if count := DB.Create(&cc).RowsAffected; count != 1 {
- t.Error("There should be one record be affected when create record")
- }
- var cc1 CustomizeColumn
- DB.First(&cc1, 666)
- if cc1.Name != expected {
- t.Errorf("Failed to query CustomizeColumn")
- }
- cc.Name = "bar"
- DB.Save(&cc)
- var cc2 CustomizeColumn
- DB.First(&cc2, 666)
- if cc2.Name != "bar" {
- t.Errorf("Failed to query CustomizeColumn")
- }
- }
- func TestCustomColumnAndIgnoredFieldClash(t *testing.T) {
- DB.DropTable(&CustomColumnAndIgnoredFieldClash{})
- if err := DB.AutoMigrate(&CustomColumnAndIgnoredFieldClash{}).Error; err != nil {
- t.Errorf("Should not raise error: %s", err)
- }
- }
- type CustomizePerson struct {
- IdPerson string `gorm:"column:idPerson;primary_key:true"`
- Accounts []CustomizeAccount `gorm:"many2many:PersonAccount;associationforeignkey:idAccount;foreignkey:idPerson"`
- }
- type CustomizeAccount struct {
- IdAccount string `gorm:"column:idAccount;primary_key:true"`
- Name string
- }
- func TestManyToManyWithCustomizedColumn(t *testing.T) {
- DB.DropTable(&CustomizePerson{}, &CustomizeAccount{}, "PersonAccount")
- DB.AutoMigrate(&CustomizePerson{}, &CustomizeAccount{})
- account := CustomizeAccount{IdAccount: "account", Name: "id1"}
- person := CustomizePerson{
- IdPerson: "person",
- Accounts: []CustomizeAccount{account},
- }
- if err := DB.Create(&account).Error; err != nil {
- t.Errorf("no error should happen, but got %v", err)
- }
- if err := DB.Create(&person).Error; err != nil {
- t.Errorf("no error should happen, but got %v", err)
- }
- var person1 CustomizePerson
- scope := DB.NewScope(nil)
- if err := DB.Preload("Accounts").First(&person1, scope.Quote("idPerson")+" = ?", person.IdPerson).Error; err != nil {
- t.Errorf("no error should happen when preloading customized column many2many relations, but got %v", err)
- }
- if len(person1.Accounts) != 1 || person1.Accounts[0].IdAccount != "account" {
- t.Errorf("should preload correct accounts")
- }
- }
- type CustomizeUser struct {
- gorm.Model
- Email string `sql:"column:email_address"`
- }
- type CustomizeInvitation struct {
- gorm.Model
- Address string `sql:"column:invitation"`
- Person *CustomizeUser `gorm:"foreignkey:Email;associationforeignkey:invitation"`
- }
- func TestOneToOneWithCustomizedColumn(t *testing.T) {
- DB.DropTable(&CustomizeUser{}, &CustomizeInvitation{})
- DB.AutoMigrate(&CustomizeUser{}, &CustomizeInvitation{})
- user := CustomizeUser{
- Email: "hello@example.com",
- }
- invitation := CustomizeInvitation{
- Address: "hello@example.com",
- }
- DB.Create(&user)
- DB.Create(&invitation)
- var invitation2 CustomizeInvitation
- if err := DB.Preload("Person").Find(&invitation2, invitation.ID).Error; err != nil {
- t.Errorf("no error should happen, but got %v", err)
- }
- if invitation2.Person.Email != user.Email {
- t.Errorf("Should preload one to one relation with customize foreign keys")
- }
- }
- type PromotionDiscount struct {
- gorm.Model
- Name string
- Coupons []*PromotionCoupon `gorm:"ForeignKey:discount_id"`
- Rule *PromotionRule `gorm:"ForeignKey:discount_id"`
- Benefits []PromotionBenefit `gorm:"ForeignKey:promotion_id"`
- }
- type PromotionBenefit struct {
- gorm.Model
- Name string
- PromotionID uint
- Discount PromotionDiscount `gorm:"ForeignKey:promotion_id"`
- }
- type PromotionCoupon struct {
- gorm.Model
- Code string
- DiscountID uint
- Discount PromotionDiscount
- }
- type PromotionRule struct {
- gorm.Model
- Name string
- Begin *time.Time
- End *time.Time
- DiscountID uint
- Discount *PromotionDiscount
- }
- func TestOneToManyWithCustomizedColumn(t *testing.T) {
- DB.DropTable(&PromotionDiscount{}, &PromotionCoupon{})
- DB.AutoMigrate(&PromotionDiscount{}, &PromotionCoupon{})
- discount := PromotionDiscount{
- Name: "Happy New Year",
- Coupons: []*PromotionCoupon{
- {Code: "newyear1"},
- {Code: "newyear2"},
- },
- }
- if err := DB.Create(&discount).Error; err != nil {
- t.Errorf("no error should happen but got %v", err)
- }
- var discount1 PromotionDiscount
- if err := DB.Preload("Coupons").First(&discount1, "id = ?", discount.ID).Error; err != nil {
- t.Errorf("no error should happen but got %v", err)
- }
- if len(discount.Coupons) != 2 {
- t.Errorf("should find two coupons")
- }
- var coupon PromotionCoupon
- if err := DB.Preload("Discount").First(&coupon, "code = ?", "newyear1").Error; err != nil {
- t.Errorf("no error should happen but got %v", err)
- }
- if coupon.Discount.Name != "Happy New Year" {
- t.Errorf("should preload discount from coupon")
- }
- }
- func TestHasOneWithPartialCustomizedColumn(t *testing.T) {
- DB.DropTable(&PromotionDiscount{}, &PromotionRule{})
- DB.AutoMigrate(&PromotionDiscount{}, &PromotionRule{})
- var begin = time.Now()
- var end = time.Now().Add(24 * time.Hour)
- discount := PromotionDiscount{
- Name: "Happy New Year 2",
- Rule: &PromotionRule{
- Name: "time_limited",
- Begin: &begin,
- End: &end,
- },
- }
- if err := DB.Create(&discount).Error; err != nil {
- t.Errorf("no error should happen but got %v", err)
- }
- var discount1 PromotionDiscount
- if err := DB.Preload("Rule").First(&discount1, "id = ?", discount.ID).Error; err != nil {
- t.Errorf("no error should happen but got %v", err)
- }
- if discount.Rule.Begin.Format(time.RFC3339Nano) != begin.Format(time.RFC3339Nano) {
- t.Errorf("Should be able to preload Rule")
- }
- var rule PromotionRule
- if err := DB.Preload("Discount").First(&rule, "name = ?", "time_limited").Error; err != nil {
- t.Errorf("no error should happen but got %v", err)
- }
- if rule.Discount.Name != "Happy New Year 2" {
- t.Errorf("should preload discount from rule")
- }
- }
- func TestBelongsToWithPartialCustomizedColumn(t *testing.T) {
- DB.DropTable(&PromotionDiscount{}, &PromotionBenefit{})
- DB.AutoMigrate(&PromotionDiscount{}, &PromotionBenefit{})
- discount := PromotionDiscount{
- Name: "Happy New Year 3",
- Benefits: []PromotionBenefit{
- {Name: "free cod"},
- {Name: "free shipping"},
- },
- }
- if err := DB.Create(&discount).Error; err != nil {
- t.Errorf("no error should happen but got %v", err)
- }
- var discount1 PromotionDiscount
- if err := DB.Preload("Benefits").First(&discount1, "id = ?", discount.ID).Error; err != nil {
- t.Errorf("no error should happen but got %v", err)
- }
- if len(discount.Benefits) != 2 {
- t.Errorf("should find two benefits")
- }
- var benefit PromotionBenefit
- if err := DB.Preload("Discount").First(&benefit, "name = ?", "free cod").Error; err != nil {
- t.Errorf("no error should happen but got %v", err)
- }
- if benefit.Discount.Name != "Happy New Year 3" {
- t.Errorf("should preload discount from coupon")
- }
- }
- type SelfReferencingUser struct {
- gorm.Model
- Name string
- Friends []*SelfReferencingUser `gorm:"many2many:UserFriends;association_jointable_foreignkey:friend_id"`
- }
- func TestSelfReferencingMany2ManyColumn(t *testing.T) {
- DB.DropTable(&SelfReferencingUser{}, "UserFriends")
- DB.AutoMigrate(&SelfReferencingUser{})
- if !DB.HasTable("UserFriends") {
- t.Errorf("auto migrate error, table UserFriends should be created")
- }
- friend1 := SelfReferencingUser{Name: "friend1_m2m"}
- if err := DB.Create(&friend1).Error; err != nil {
- t.Errorf("no error should happen, but got %v", err)
- }
- friend2 := SelfReferencingUser{Name: "friend2_m2m"}
- if err := DB.Create(&friend2).Error; err != nil {
- t.Errorf("no error should happen, but got %v", err)
- }
- user := SelfReferencingUser{
- Name: "self_m2m",
- Friends: []*SelfReferencingUser{&friend1, &friend2},
- }
- if err := DB.Create(&user).Error; err != nil {
- t.Errorf("no error should happen, but got %v", err)
- }
- if DB.Model(&user).Association("Friends").Count() != 2 {
- t.Errorf("Should find created friends correctly")
- }
- var count int
- if err := DB.Table("UserFriends").Count(&count).Error; err != nil {
- t.Errorf("no error should happen, but got %v", err)
- }
- if count == 0 {
- t.Errorf("table UserFriends should have records")
- }
- var newUser = SelfReferencingUser{}
- if err := DB.Preload("Friends").First(&newUser, "id = ?", user.ID).Error; err != nil {
- t.Errorf("no error should happen, but got %v", err)
- }
- if len(newUser.Friends) != 2 {
- t.Errorf("Should preload created frineds for self reference m2m")
- }
- DB.Model(&newUser).Association("Friends").Append(&SelfReferencingUser{Name: "friend3_m2m"})
- if DB.Model(&user).Association("Friends").Count() != 3 {
- t.Errorf("Should find created friends correctly")
- }
- DB.Model(&newUser).Association("Friends").Replace(&SelfReferencingUser{Name: "friend4_m2m"})
- if DB.Model(&user).Association("Friends").Count() != 1 {
- t.Errorf("Should find created friends correctly")
- }
- friend := SelfReferencingUser{}
- DB.Model(&newUser).Association("Friends").Find(&friend)
- if friend.Name != "friend4_m2m" {
- t.Errorf("Should find created friends correctly")
- }
- DB.Model(&newUser).Association("Friends").Delete(friend)
- if DB.Model(&user).Association("Friends").Count() != 0 {
- t.Errorf("All friends should be deleted")
- }
- }
|