From 985dcdc8a7999c15af7626006dff356e61456682 Mon Sep 17 00:00:00 2001 From: huanjiawei Date: Tue, 19 Jul 2022 23:41:30 +0800 Subject: [PATCH] fix: empty serilizer err #5524 --- schema/field.go | 5 +---- schema/serializer.go | 6 +++++- tests/go.mod | 1 - tests/serializer_test.go | 42 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/schema/field.go b/schema/field.go index d4dfbd6f..a415f8d7 100644 --- a/schema/field.go +++ b/schema/field.go @@ -472,9 +472,6 @@ func (field *Field) setupValuerAndSetter() { oldValuerOf := field.ValueOf field.ValueOf = func(ctx context.Context, v reflect.Value) (interface{}, bool) { value, zero := oldValuerOf(ctx, v) - if zero { - return value, zero - } s, ok := value.(SerializerValuerInterface) if !ok { @@ -487,7 +484,7 @@ func (field *Field) setupValuerAndSetter() { Destination: v, Context: ctx, fieldValue: value, - }, false + }, zero } } diff --git a/schema/serializer.go b/schema/serializer.go index 21be3c35..2c9db986 100644 --- a/schema/serializer.go +++ b/schema/serializer.go @@ -121,7 +121,11 @@ func (UnixSecondSerializer) Scan(ctx context.Context, field *Field, dst reflect. func (UnixSecondSerializer) Value(ctx context.Context, field *Field, dst reflect.Value, fieldValue interface{}) (result interface{}, err error) { switch v := fieldValue.(type) { case int64, int, uint, uint64, int32, uint32, int16, uint16, *int64, *int, *uint, *uint64, *int32, *uint32, *int16, *uint16: - result = time.Unix(reflect.Indirect(reflect.ValueOf(v)).Int(), 0) + rv := reflect.ValueOf(v) + if rv.IsZero() { + return time.Unix(0, 0), nil + } + result = time.Unix(reflect.Indirect(rv).Int(), 0) default: err = fmt.Errorf("invalid field type %#v for UnixSecondSerializer, only int, uint supported", v) } diff --git a/tests/go.mod b/tests/go.mod index 7a788a43..eb8f336d 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -3,7 +3,6 @@ module gorm.io/gorm/tests go 1.14 require ( - github.com/denisenkom/go-mssqldb v0.12.2 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/google/uuid v1.3.0 github.com/jinzhu/now v1.1.5 diff --git a/tests/serializer_test.go b/tests/serializer_test.go index 95d25699..230cf195 100644 --- a/tests/serializer_test.go +++ b/tests/serializer_test.go @@ -103,6 +103,48 @@ func TestSerializer(t *testing.T) { CustomSerializerString: "world", } + data.JobInfo = Job{} + if err := DB.Create(&data).Error; err != nil { + t.Fatalf("failed to create data, got error %v", err) + } + + var result SerializerStruct + if err := DB.First(&result, data.ID).Error; err != nil { + t.Fatalf("failed to query data, got error %v", err) + } + + AssertEqual(t, result, data) + + if err := DB.Model(&result).Update("roles", "").Error; err != nil { + t.Fatalf("failed to update data's roles, got error %v", err) + } + + if err := DB.First(&result, data.ID).Error; err != nil { + t.Fatalf("failed to query data, got error %v", err) + } +} + +func TestSerializerZeroValue(t *testing.T) { + schema.RegisterSerializer("custom", NewCustomSerializer("hello")) + DB.Migrator().DropTable(&SerializerStruct{}) + if err := DB.Migrator().AutoMigrate(&SerializerStruct{}); err != nil { + t.Fatalf("no error should happen when migrate scanner, valuer struct, got error %v", err) + } + + createdAt := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC) + updatedAt := createdAt.Unix() + + data := SerializerStruct{ + Name: []byte("jinzhu"), + Roles: []string{"r1", "r2"}, + Contracts: map[string]interface{}{"name": "jinzhu", "age": 10}, + EncryptedString: EncryptedString("pass"), + CreatedTime: createdAt.Unix(), + UpdatedTime: &updatedAt, + JobInfo: Job{}, + CustomSerializerString: "world", + } + if err := DB.Create(&data).Error; err != nil { t.Fatalf("failed to create data, got error %v", err) }