OSDN Git Service

feat: init cross_tx keepers (#146)
[bytom/vapor.git] / vendor / github.com / jinzhu / gorm / join_table_test.go
1 package gorm_test
2
3 import (
4         "fmt"
5         "strconv"
6         "testing"
7         "time"
8
9         "github.com/jinzhu/gorm"
10 )
11
12 type Person struct {
13         Id        int
14         Name      string
15         Addresses []*Address `gorm:"many2many:person_addresses;"`
16 }
17
18 type PersonAddress struct {
19         gorm.JoinTableHandler
20         PersonID  int
21         AddressID int
22         DeletedAt *time.Time
23         CreatedAt time.Time
24 }
25
26 func (*PersonAddress) Add(handler gorm.JoinTableHandlerInterface, db *gorm.DB, foreignValue interface{}, associationValue interface{}) error {
27         foreignPrimaryKey, _ := strconv.Atoi(fmt.Sprint(db.NewScope(foreignValue).PrimaryKeyValue()))
28         associationPrimaryKey, _ := strconv.Atoi(fmt.Sprint(db.NewScope(associationValue).PrimaryKeyValue()))
29         if result := db.Unscoped().Model(&PersonAddress{}).Where(map[string]interface{}{
30                 "person_id":  foreignPrimaryKey,
31                 "address_id": associationPrimaryKey,
32         }).Update(map[string]interface{}{
33                 "person_id":  foreignPrimaryKey,
34                 "address_id": associationPrimaryKey,
35                 "deleted_at": gorm.Expr("NULL"),
36         }).RowsAffected; result == 0 {
37                 return db.Create(&PersonAddress{
38                         PersonID:  foreignPrimaryKey,
39                         AddressID: associationPrimaryKey,
40                 }).Error
41         }
42
43         return nil
44 }
45
46 func (*PersonAddress) Delete(handler gorm.JoinTableHandlerInterface, db *gorm.DB, sources ...interface{}) error {
47         return db.Delete(&PersonAddress{}).Error
48 }
49
50 func (pa *PersonAddress) JoinWith(handler gorm.JoinTableHandlerInterface, db *gorm.DB, source interface{}) *gorm.DB {
51         table := pa.Table(db)
52         return db.Joins("INNER JOIN person_addresses ON person_addresses.address_id = addresses.id").Where(fmt.Sprintf("%v.deleted_at IS NULL OR %v.deleted_at <= '0001-01-02'", table, table))
53 }
54
55 func TestJoinTable(t *testing.T) {
56         DB.Exec("drop table person_addresses;")
57         DB.AutoMigrate(&Person{})
58         DB.SetJoinTableHandler(&Person{}, "Addresses", &PersonAddress{})
59
60         address1 := &Address{Address1: "address 1"}
61         address2 := &Address{Address1: "address 2"}
62         person := &Person{Name: "person", Addresses: []*Address{address1, address2}}
63         DB.Save(person)
64
65         DB.Model(person).Association("Addresses").Delete(address1)
66
67         if DB.Find(&[]PersonAddress{}, "person_id = ?", person.Id).RowsAffected != 1 {
68                 t.Errorf("Should found one address")
69         }
70
71         if DB.Model(person).Association("Addresses").Count() != 1 {
72                 t.Errorf("Should found one address")
73         }
74
75         if DB.Unscoped().Find(&[]PersonAddress{}, "person_id = ?", person.Id).RowsAffected != 2 {
76                 t.Errorf("Found two addresses with Unscoped")
77         }
78
79         if DB.Model(person).Association("Addresses").Clear(); DB.Model(person).Association("Addresses").Count() != 0 {
80                 t.Errorf("Should deleted all addresses")
81         }
82 }
83
84 func TestEmbeddedMany2ManyRelationship(t *testing.T) {
85         type EmbeddedPerson struct {
86                 ID        int
87                 Name      string
88                 Addresses []*Address `gorm:"many2many:person_addresses;"`
89         }
90
91         type NewPerson struct {
92                 EmbeddedPerson
93                 ExternalID uint
94         }
95         DB.Exec("drop table person_addresses;")
96         DB.AutoMigrate(&NewPerson{})
97
98         address1 := &Address{Address1: "address 1"}
99         address2 := &Address{Address1: "address 2"}
100         person := &NewPerson{ExternalID: 100, EmbeddedPerson: EmbeddedPerson{Name: "person", Addresses: []*Address{address1, address2}}}
101         if err := DB.Save(person).Error; err != nil {
102                 t.Errorf("no error should return when save embedded many2many relationship, but got %v", err)
103         }
104
105         if err := DB.Model(person).Association("Addresses").Delete(address1).Error; err != nil {
106                 t.Errorf("no error should return when delete embedded many2many relationship, but got %v", err)
107         }
108
109         association := DB.Model(person).Association("Addresses")
110         if count := association.Count(); count != 1 || association.Error != nil {
111                 t.Errorf("Should found one address, but got %v, error is %v", count, association.Error)
112         }
113
114         if association.Clear(); association.Count() != 0 {
115                 t.Errorf("Should deleted all addresses")
116         }
117 }