From 6e03b97e266f30db994d8bc24bca2afd74a106b9 Mon Sep 17 00:00:00 2001 From: "hjwblog.com" Date: Wed, 27 Jul 2022 13:59:47 +0800 Subject: [PATCH] fix: empty serilizer err #5524 (#5525) * fix: empty serilizer err #5524 * feat: fix UnixSecondSerializer return nil * feat: split type case Co-authored-by: huanjiawei --- schema/field.go | 5 +---- schema/serializer.go | 10 ++++++++-- tests/go.mod | 1 - tests/serializer_test.go | 29 +++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/schema/field.go b/schema/field.go index 47f3994f..1589d984 100644 --- a/schema/field.go +++ b/schema/field.go @@ -468,9 +468,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 { @@ -483,7 +480,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..00a4f85f 100644 --- a/schema/serializer.go +++ b/schema/serializer.go @@ -119,9 +119,15 @@ func (UnixSecondSerializer) Scan(ctx context.Context, field *Field, dst reflect. // Value implements serializer interface func (UnixSecondSerializer) Value(ctx context.Context, field *Field, dst reflect.Value, fieldValue interface{}) (result interface{}, err error) { + rv := reflect.ValueOf(fieldValue) 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) + case int64, int, uint, uint64, int32, uint32, int16, uint16: + result = time.Unix(reflect.Indirect(rv).Int(), 0) + case *int64, *int, *uint, *uint64, *int32, *uint32, *int16, *uint16: + if rv.IsZero() { + return nil, 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..946536bf 100644 --- a/tests/serializer_test.go +++ b/tests/serializer_test.go @@ -123,6 +123,35 @@ func TestSerializer(t *testing.T) { } } +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) + } + + data := SerializerStruct{} + + 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 TestSerializerAssignFirstOrCreate(t *testing.T) { schema.RegisterSerializer("custom", NewCustomSerializer("hello")) DB.Migrator().DropTable(&SerializerStruct{})