fix:serializer contain field panic (#5461)

This commit is contained in:
wws 2022-06-25 16:32:47 +08:00 committed by GitHub
parent a70af2a4c0
commit 3e6ab99043
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 8 deletions

View File

@ -950,7 +950,7 @@ func (field *Field) setupNewValuePool() {
New: func() interface{} {
return &serializer{
Field: field,
Serializer: reflect.New(reflect.Indirect(reflect.ValueOf(field.Serializer)).Type()).Interface().(SerializerInterface),
Serializer: field.Serializer,
}
},
}

View File

@ -16,13 +16,14 @@ import (
type SerializerStruct struct {
gorm.Model
Name []byte `gorm:"json"`
Roles Roles `gorm:"serializer:json"`
Contracts map[string]interface{} `gorm:"serializer:json"`
JobInfo Job `gorm:"type:bytes;serializer:gob"`
CreatedTime int64 `gorm:"serializer:unixtime;type:time"` // store time in db, use int as field type
UpdatedTime *int64 `gorm:"serializer:unixtime;type:time"` // store time in db, use int as field type
EncryptedString EncryptedString
Name []byte `gorm:"json"`
Roles Roles `gorm:"serializer:json"`
Contracts map[string]interface{} `gorm:"serializer:json"`
JobInfo Job `gorm:"type:bytes;serializer:gob"`
CreatedTime int64 `gorm:"serializer:unixtime;type:time"` // store time in db, use int as field type
UpdatedTime *int64 `gorm:"serializer:unixtime;type:time"` // store time in db, use int as field type
CustomSerializerString string `gorm:"serializer:custom"`
EncryptedString EncryptedString
}
type Roles []string
@ -52,7 +53,32 @@ func (es EncryptedString) Value(ctx context.Context, field *schema.Field, dst re
return "hello" + string(es), nil
}
type CustomSerializer struct {
prefix []byte
}
func NewCustomSerializer(prefix string) *CustomSerializer {
return &CustomSerializer{prefix: []byte(prefix)}
}
func (c *CustomSerializer) Scan(ctx context.Context, field *schema.Field, dst reflect.Value, dbValue interface{}) (err error) {
switch value := dbValue.(type) {
case []byte:
err = field.Set(ctx, dst, bytes.TrimPrefix(value, c.prefix))
case string:
err = field.Set(ctx, dst, strings.TrimPrefix(value, string(c.prefix)))
default:
err = fmt.Errorf("unsupported data %#v", dbValue)
}
return err
}
func (c *CustomSerializer) Value(ctx context.Context, field *schema.Field, dst reflect.Value, fieldValue interface{}) (interface{}, error) {
return fmt.Sprintf("%s%s", c.prefix, fieldValue), nil
}
func TestSerializer(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)
@ -74,6 +100,7 @@ func TestSerializer(t *testing.T) {
Location: "Kenmawr",
IsIntern: false,
},
CustomSerializerString: "world",
}
if err := DB.Create(&data).Error; err != nil {
@ -90,6 +117,7 @@ func TestSerializer(t *testing.T) {
}
func TestSerializerAssignFirstOrCreate(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)
@ -109,6 +137,7 @@ func TestSerializerAssignFirstOrCreate(t *testing.T) {
Location: "Shadyside",
IsIntern: false,
},
CustomSerializerString: "world",
}
// first time insert record