forked from mirror/gorm
feat: support gob serialize (#5108)
This commit is contained in:
parent
45ef1da7e4
commit
3741f258d0
|
@ -1,11 +1,12 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"encoding/gob"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
@ -32,6 +33,7 @@ func GetSerializer(name string) (serializer SerializerInterface, ok bool) {
|
|||
func init() {
|
||||
RegisterSerializer("json", JSONSerializer{})
|
||||
RegisterSerializer("unixtime", UnixSecondSerializer{})
|
||||
RegisterSerializer("gob", GobSerializer{})
|
||||
}
|
||||
|
||||
// Serializer field value serializer
|
||||
|
@ -83,7 +85,7 @@ func (JSONSerializer) Scan(ctx context.Context, field *Field, dst reflect.Value,
|
|||
case string:
|
||||
bytes = []byte(v)
|
||||
default:
|
||||
return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", dbValue))
|
||||
return fmt.Errorf("failed to unmarshal JSONB value: %#v", dbValue)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(bytes, fieldValue.Interface())
|
||||
|
@ -123,3 +125,33 @@ func (UnixSecondSerializer) Value(ctx context.Context, field *Field, dst reflect
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GobSerializer gob serializer
|
||||
type GobSerializer struct {
|
||||
}
|
||||
|
||||
// Scan implements serializer interface
|
||||
func (GobSerializer) Scan(ctx context.Context, field *Field, dst reflect.Value, dbValue interface{}) (err error) {
|
||||
fieldValue := reflect.New(field.FieldType)
|
||||
|
||||
if dbValue != nil {
|
||||
var bytesValue []byte
|
||||
switch v := dbValue.(type) {
|
||||
case []byte:
|
||||
bytesValue = v
|
||||
default:
|
||||
return fmt.Errorf("failed to unmarshal gob value: %#v", dbValue)
|
||||
}
|
||||
decoder := gob.NewDecoder(bytes.NewBuffer(bytesValue))
|
||||
err = decoder.Decode(fieldValue.Interface())
|
||||
}
|
||||
field.ReflectValueOf(ctx, dst).Set(fieldValue.Elem())
|
||||
return
|
||||
}
|
||||
|
||||
// Value implements serializer interface
|
||||
func (GobSerializer) Value(ctx context.Context, field *Field, dst reflect.Value, fieldValue interface{}) (interface{}, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
err := gob.NewEncoder(buf).Encode(fieldValue)
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
|
|
|
@ -19,11 +19,20 @@ type SerializerStruct struct {
|
|||
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
|
||||
EncryptedString EncryptedString
|
||||
}
|
||||
|
||||
type Roles []string
|
||||
|
||||
type Job struct {
|
||||
Title string
|
||||
Number int
|
||||
Location string
|
||||
IsIntern bool
|
||||
}
|
||||
|
||||
type EncryptedString string
|
||||
|
||||
func (es *EncryptedString) Scan(ctx context.Context, field *schema.Field, dst reflect.Value, dbValue interface{}) (err error) {
|
||||
|
@ -56,6 +65,12 @@ func TestSerializer(t *testing.T) {
|
|||
Contracts: map[string]interface{}{"name": "jinzhu", "age": 10},
|
||||
EncryptedString: EncryptedString("pass"),
|
||||
CreatedTime: createdAt.Unix(),
|
||||
JobInfo: Job{
|
||||
Title: "programmer",
|
||||
Number: 9920,
|
||||
Location: "Kenmawr",
|
||||
IsIntern: false,
|
||||
},
|
||||
}
|
||||
|
||||
if err := DB.Create(&data).Error; err != nil {
|
||||
|
|
Loading…
Reference in New Issue