diff --git a/schema/field.go b/schema/field.go index d1a633ce..e03fe053 100644 --- a/schema/field.go +++ b/schema/field.go @@ -896,7 +896,9 @@ func (field *Field) setupValuerAndSetter() { if !reflectV.IsValid() { field.ReflectValueOf(ctx, value).Set(reflect.New(field.FieldType).Elem()) } else if reflectV.Kind() == reflect.Ptr && reflectV.IsNil() { - return + if field.FieldType.Elem().Kind() == reflect.Array && field.OwnerSchema == nil { + field.ReflectValueOf(ctx, value).Set(reflectV) + } } else if reflectV.Type().AssignableTo(field.FieldType) { field.ReflectValueOf(ctx, value).Set(reflectV) } else if reflectV.Kind() == reflect.Ptr { diff --git a/tests/connpool_test.go b/tests/connpool_test.go index 21a2bad0..3e878da6 100644 --- a/tests/connpool_test.go +++ b/tests/connpool_test.go @@ -101,12 +101,12 @@ func TestConnPoolWrapper(t *testing.T) { db: nativeDB, expect: []string{ "SELECT VERSION()", - "INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`) VALUES (?,?,?,?,?,?,?,?,?)", + "INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`,`user_uuid`) VALUES (?,?,?,?,?,?,?,?,?,?)", "SELECT * FROM `users` WHERE name = ? AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT ?", - "INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`) VALUES (?,?,?,?,?,?,?,?,?)", + "INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`,`user_uuid`) VALUES (?,?,?,?,?,?,?,?,?,?)", "SELECT * FROM `users` WHERE name = ? AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT ?", "SELECT * FROM `users` WHERE name = ? AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT ?", - "INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`) VALUES (?,?,?,?,?,?,?,?,?)", + "INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`,`user_uuid`) VALUES (?,?,?,?,?,?,?,?,?,?)", "SELECT * FROM `users` WHERE name = ? AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT ?", "SELECT * FROM `users` WHERE name = ? AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT ?", }, diff --git a/tests/embedded_struct_test.go b/tests/embedded_struct_test.go index 3351ed8e..2d7973f6 100644 --- a/tests/embedded_struct_test.go +++ b/tests/embedded_struct_test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "github.com/google/uuid" "gorm.io/gorm" . "gorm.io/gorm/utils/tests" ) @@ -114,6 +115,7 @@ func TestEmbeddedPointerTypeStruct(t *testing.T) { ContentPtr *Content Birthday time.Time BirthdayPtr *time.Time + AuthorUUID *uuid.UUID } type HNPost struct { diff --git a/tests/go.mod b/tests/go.mod index 30143433..1cfce16e 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -7,6 +7,7 @@ require ( github.com/jinzhu/now v1.1.5 github.com/lib/pq v1.10.9 github.com/stretchr/testify v1.9.0 + gorm.io/datatypes v1.2.2 gorm.io/driver/mysql v1.5.7 gorm.io/driver/postgres v1.5.10 gorm.io/driver/sqlite v1.5.6 diff --git a/tests/sql_builder_test.go b/tests/sql_builder_test.go index 0c204db4..0325bf82 100644 --- a/tests/sql_builder_test.go +++ b/tests/sql_builder_test.go @@ -158,7 +158,7 @@ func TestDryRun(t *testing.T) { dryRunDB := DB.Session(&gorm.Session{DryRun: true}) stmt := dryRunDB.Create(&user).Statement - if stmt.SQL.String() == "" || len(stmt.Vars) != 9 { + if stmt.SQL.String() == "" || len(stmt.Vars) != 10 { t.Errorf("Failed to generate sql, got %v", stmt.SQL.String()) } @@ -403,7 +403,7 @@ func TestToSQL(t *testing.T) { sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB { return tx.Model(&User{}).Create(user) }) - assertEqualSQL(t, `INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active") VALUES ('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'foo',20,NULL,NULL,NULL,false) RETURNING "id"`, sql) + assertEqualSQL(t, `INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active","user_uuid") VALUES ('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'foo',20,NULL,NULL,NULL,false,NULL) RETURNING "id"`, sql) // save user = &User{Name: "foo", Age: 20} @@ -412,7 +412,7 @@ func TestToSQL(t *testing.T) { sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB { return tx.Model(&User{}).Save(user) }) - assertEqualSQL(t, `INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active") VALUES ('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'foo',20,NULL,NULL,NULL,false) RETURNING "id"`, sql) + assertEqualSQL(t, `INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active","user_uuid") VALUES ('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'foo',20,NULL,NULL,NULL,false,NULL) RETURNING "id"`, sql) // updates user = &User{Name: "bar", Age: 22} diff --git a/tests/update_test.go b/tests/update_test.go index 9eb9dbfc..285e9602 100644 --- a/tests/update_test.go +++ b/tests/update_test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "gorm.io/datatypes" "gorm.io/gorm" "gorm.io/gorm/clause" "gorm.io/gorm/utils" @@ -183,6 +184,38 @@ func TestUpdates(t *testing.T) { user3.Age += 100 AssertObjEqual(t, user4, user3, "UpdatedAt", "Age") + + // Updates() with map and datatypes.UUID - Case 1 - Update with UUID value + uuidVal := datatypes.NewUUIDv4() + tx := DB.Model(&user4) + uuidErr := tx.Updates(map[string]interface{}{"user_uuid": uuidVal}).Error + if uuidErr != nil { + t.Errorf("No error should occur while updating with UUID value, but got %v", uuidErr) + } + // Expecting the model object (user4) to reflect the UUID value assignment. + AssertEqual(t, user4.UserUUID, uuidVal) + + // Updates() with map and datatypes.UUID - Case 2 - Update with UUID nil pointer + var nilUUIDPtr *datatypes.UUID = nil + uuidErr = tx.Updates(map[string]interface{}{"user_uuid": nilUUIDPtr}).Error + if uuidErr != nil { + t.Errorf("No error should occur while updating with nil UUID pointer, but got %v", uuidErr) + } + // Expecting the model object (user4) to reflect the UUID nil pointer assignment. + AssertEqual(t, user4.UserUUID, nilUUIDPtr) + + // Updates() with map and datatypes.UUID - Case 3 - Update with a non-nil UUID pointer + uuidVal2 := datatypes.NewUUIDv1() + if uuidErr != nil { + t.Errorf("No error should occur while generating UUID, but got %v", uuidErr) + } + var nonNilUUIDPtr *datatypes.UUID = &uuidVal2 + uuidErr = tx.Updates(map[string]interface{}{"user_uuid": nonNilUUIDPtr}).Error + if uuidErr != nil { + t.Errorf("No error should occur while updating with non-nil UUID pointer, but got %v", uuidErr) + } + // Expecting the model object (user4) to reflect the non-nil UUID pointer assignment. + AssertEqual(t, user4.UserUUID, nonNilUUIDPtr) } func TestUpdateColumn(t *testing.T) { diff --git a/utils/tests/models.go b/utils/tests/models.go index f9f4f50e..060467c2 100644 --- a/utils/tests/models.go +++ b/utils/tests/models.go @@ -4,6 +4,7 @@ import ( "database/sql" "time" + "gorm.io/datatypes" "gorm.io/gorm" ) @@ -30,6 +31,7 @@ type User struct { Languages []Language `gorm:"many2many:UserSpeak;"` Friends []*User `gorm:"many2many:user_friends;"` Active bool + UserUUID *datatypes.UUID } type Account struct {