forked from mirror/gorm
fix:serializer contain field panic (#5461)
This commit is contained in:
parent
a70af2a4c0
commit
3e6ab99043
|
@ -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,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue