From 10169437fbb9e84f8836dacc32d8b66b45d46176 Mon Sep 17 00:00:00 2001 From: henryjcee Date: Thu, 10 Oct 2024 15:18:50 +0100 Subject: [PATCH] Example showing the issue we're facing with null.String and embedded structs --- db.go | 1 + go.mod | 50 ++++++++++++++++++++++++++++++-------------------- main_test.go | 32 +++++++++++++++++++++++++++++++- models.go | 31 +++++++++++++++++-------------- 4 files changed, 79 insertions(+), 35 deletions(-) diff --git a/db.go b/db.go index ccab03ed..251ebc0b 100644 --- a/db.go +++ b/db.go @@ -11,6 +11,7 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/driver/sqlserver" + "gorm.io/gorm" "gorm.io/gorm/logger" ) diff --git a/go.mod b/go.mod index 159394d4..4b194260 100644 --- a/go.mod +++ b/go.mod @@ -1,35 +1,45 @@ module gorm.io/playground -go 1.20 +go 1.22.0 + +toolchain go1.23.2 require ( - 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/driver/mysql v1.5.7 + gorm.io/driver/postgres v1.5.9 + gorm.io/driver/sqlite v1.5.6 + gorm.io/driver/sqlserver v1.5.3 + gorm.io/gen v0.3.26 + gorm.io/gen/examples v0.0.0-00010101000000-000000000000 + gorm.io/gorm v1.25.12 ) require ( - github.com/go-sql-driver/mysql v1.7.1 // indirect + filippo.io/edwards25519 v1.1.0 // indirect + github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgx/v5 v5.4.3 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/pgx/v5 v5.7.1 // indirect + github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/mattn/go-sqlite3 v1.14.17 // indirect - github.com/microsoft/go-mssqldb v1.5.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.15.0 // indirect - gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c // indirect - gorm.io/hints v1.1.0 // indirect - gorm.io/plugin/dbresolver v1.5.0 // indirect + github.com/mattn/go-sqlite3 v1.14.24 // indirect + github.com/microsoft/go-mssqldb v1.7.2 // indirect + golang.org/x/crypto v0.28.0 // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/tools v0.26.0 // indirect + gopkg.in/guregu/null.v3 v3.5.0 // indirect + gorm.io/datatypes v1.2.2 // indirect + gorm.io/hints v1.1.2 // indirect + gorm.io/plugin/dbresolver v1.5.3 // indirect ) replace gorm.io/gorm => ./gorm + +replace gorm.io/gen/examples => ../gen/examples diff --git a/main_test.go b/main_test.go index 60a388f7..95d00828 100644 --- a/main_test.go +++ b/main_test.go @@ -2,6 +2,8 @@ package main import ( "testing" + + "gopkg.in/guregu/null.v3" ) // GORM_REPO: https://github.com/go-gorm/gorm.git @@ -9,7 +11,8 @@ import ( // TEST_DRIVERS: sqlite, mysql, postgres, sqlserver func TestGORM(t *testing.T) { - user := User{Name: "jinzhu"} + + user := User{Name: "jinzhu", OptionalID: null.StringFrom("this_is_an_optional_id")} DB.Create(&user) @@ -17,4 +20,31 @@ func TestGORM(t *testing.T) { if err := DB.First(&result, user.ID).Error; err != nil { t.Errorf("Failed, got error: %v", err) } + + // Update the user's name and optionalID (to be NULL) + toUpdate := user + toUpdate.OptionalID = null.String{} + toUpdate.Name = "Steve" + + err := DB.Save(&toUpdate).Error + if err != nil { + t.Errorf("Failed, got error: %v", err) + } + + // Refetch the updated user into &user + if err := DB.Model(user). + First(&user). + Error; err != nil { + t.Errorf("Failed, got error: %v", err) + } + + // Name is updated + if user.Name != "Steve" { + t.Errorf("Updated name was not fetched") + } + + // OptionalID isn't updated (should be invalid) + if user.OptionalID.Valid { + t.Errorf("Updated optional ID was not fetched") + } } diff --git a/models.go b/models.go index 692a6842..fe415a55 100644 --- a/models.go +++ b/models.go @@ -4,6 +4,8 @@ import ( "database/sql" "time" + "gopkg.in/guregu/null.v3" + "gorm.io/gorm" ) @@ -13,20 +15,21 @@ import ( // 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 + 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 + OptionalID null.String } type Account struct {