diff --git a/db.go b/db.go index ccab03ed..edf835ed 100644 --- a/db.go +++ b/db.go @@ -55,7 +55,9 @@ func OpenTestConnection() (db *gorm.DB, err error) { if dbDSN == "" { dbDSN = "user=gorm password=gorm host=localhost dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai" } - db, err = gorm.Open(postgres.Open(dbDSN), &gorm.Config{}) + db, err = gorm.Open(postgres.Open(dbDSN), &gorm.Config{ + SkipDefaultTransaction: true, + }) case "sqlserver": // CREATE LOGIN gorm WITH PASSWORD = 'LoremIpsum86'; // CREATE DATABASE gorm; @@ -83,7 +85,7 @@ func OpenTestConnection() (db *gorm.DB, err error) { func RunMigrations() { var err error - allModels := []interface{}{&User{}, &Account{}, &Pet{}, &Company{}, &Toy{}, &Language{}} + allModels := []interface{}{&User{}} rand.Seed(time.Now().UnixNano()) rand.Shuffle(len(allModels), func(i, j int) { allModels[i], allModels[j] = allModels[j], allModels[i] }) diff --git a/gen.go b/gen.go index 3127d5d6..a82f9442 100644 --- a/gen.go +++ b/gen.go @@ -14,7 +14,6 @@ func generate() { }) g.UseDB(dal.DB) - g.ApplyBasic(Company{}, Language{}) // Associations g.ApplyBasic(g.GenerateModel("user"), g.GenerateModelAs("account", "AccountInfo")) g.Execute() diff --git a/go.mod b/go.mod index 159394d4..64698d9e 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,13 @@ module gorm.io/playground go 1.20 require ( + github.com/qmuntal/stateless v1.7.0 gorm.io/driver/mysql v1.5.2 gorm.io/driver/postgres v1.5.2 gorm.io/driver/sqlite v1.5.3 gorm.io/driver/sqlserver v1.5.1 gorm.io/gen v0.3.25 - gorm.io/gorm v1.25.4 + gorm.io/gorm v1.25.10 ) require ( @@ -32,4 +33,4 @@ require ( gorm.io/plugin/dbresolver v1.5.0 // indirect ) -replace gorm.io/gorm => ./gorm +// replace gorm.io/gorm => ./gorm diff --git a/main_test.go b/main_test.go index 60a388f7..fb9d6309 100644 --- a/main_test.go +++ b/main_test.go @@ -9,12 +9,20 @@ import ( // TEST_DRIVERS: sqlite, mysql, postgres, sqlserver func TestGORM(t *testing.T) { - user := User{Name: "jinzhu"} + user := User{Name: "jinzhu", State: NewCustomType("active")} DB.Create(&user) - var result User - if err := DB.First(&result, user.ID).Error; err != nil { + var result []User + if err := DB.Find(&result).Error; err != nil { t.Errorf("Failed, got error: %v", err) } + + if len(result) == 0 { + t.Errorf("Failed, got empty result") + } + + if result[0].State.Machine == nil { + t.Errorf("Failed, expected: active") + } } diff --git a/models.go b/models.go index 692a6842..27e6d0e0 100644 --- a/models.go +++ b/models.go @@ -1,60 +1,41 @@ package main import ( - "database/sql" - "time" - + "database/sql/driver" "gorm.io/gorm" + "log" ) -// User has one `Account` (has one), many `Pets` (has many) and `Toys` (has many - polymorphic) -// He works in a Company (belongs to), he has a Manager (belongs to - single-table), and also managed a Team (has many - single-table) -// He speaks many languages (many to many) and has many friends (many to many - single-table) -// His pet also has one Toy (has one - polymorphic) type User struct { gorm.Model - Name string - Age uint - Birthday *time.Time - Account Account - Pets []*Pet - Toys []Toy `gorm:"polymorphic:Owner"` - CompanyID *int - Company Company - ManagerID *uint - Manager *User - Team []User `gorm:"foreignkey:ManagerID"` - Languages []Language `gorm:"many2many:UserSpeak"` - Friends []*User `gorm:"many2many:user_friends"` - Active bool + Name string + State CustomType } -type Account struct { - gorm.Model - UserID sql.NullInt64 - Number string +type CustomType struct { + Machine *Machine } -type Pet struct { - gorm.Model - UserID *uint - Name string - Toy Toy `gorm:"polymorphic:Owner;"` -} +type Machine string -type Toy struct { - gorm.Model - Name string - OwnerID string - OwnerType string +func NewCustomType(state Machine) CustomType { + return CustomType{&state} } -type Company struct { - ID int - Name string +// Implement scanner and value interfaces as described in tests https://gorm.io/docs/data_types.html#Scanner-x2F-Valuer +// https://github.com/go-gorm/gorm/blob/master/tests/scanner_valuer_test.go + +func (sm *CustomType) Scan(value interface{}) error { + log.Printf("Scanning state %v", value) + switch vt := value.(type) { + case string: + state := vt + *sm = NewCustomType(Machine(state)) + } + return nil } -type Language struct { - Code string `gorm:"primarykey"` - Name string +func (sm CustomType) Value() (driver.Value, error) { + log.Printf("Value of state %v", sm) + return &sm.Machine, nil }