mirror of https://github.com/go-gorm/gorm.git
feat: support gob serialize (#5108)
This commit is contained in:
parent
45ef1da7e4
commit
3741f258d0
|
@ -1,11 +1,12 @@
|
||||||
package schema
|
package schema
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
|
"encoding/gob"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -32,6 +33,7 @@ func GetSerializer(name string) (serializer SerializerInterface, ok bool) {
|
||||||
func init() {
|
func init() {
|
||||||
RegisterSerializer("json", JSONSerializer{})
|
RegisterSerializer("json", JSONSerializer{})
|
||||||
RegisterSerializer("unixtime", UnixSecondSerializer{})
|
RegisterSerializer("unixtime", UnixSecondSerializer{})
|
||||||
|
RegisterSerializer("gob", GobSerializer{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serializer field value serializer
|
// Serializer field value serializer
|
||||||
|
@ -83,7 +85,7 @@ func (JSONSerializer) Scan(ctx context.Context, field *Field, dst reflect.Value,
|
||||||
case string:
|
case string:
|
||||||
bytes = []byte(v)
|
bytes = []byte(v)
|
||||||
default:
|
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())
|
err = json.Unmarshal(bytes, fieldValue.Interface())
|
||||||
|
@ -123,3 +125,33 @@ func (UnixSecondSerializer) Value(ctx context.Context, field *Field, dst reflect
|
||||||
}
|
}
|
||||||
return
|
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"`
|
Name []byte `gorm:"json"`
|
||||||
Roles Roles `gorm:"serializer:json"`
|
Roles Roles `gorm:"serializer:json"`
|
||||||
Contracts map[string]interface{} `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
|
CreatedTime int64 `gorm:"serializer:unixtime;type:time"` // store time in db, use int as field type
|
||||||
EncryptedString EncryptedString
|
EncryptedString EncryptedString
|
||||||
}
|
}
|
||||||
|
|
||||||
type Roles []string
|
type Roles []string
|
||||||
|
|
||||||
|
type Job struct {
|
||||||
|
Title string
|
||||||
|
Number int
|
||||||
|
Location string
|
||||||
|
IsIntern bool
|
||||||
|
}
|
||||||
|
|
||||||
type EncryptedString string
|
type EncryptedString string
|
||||||
|
|
||||||
func (es *EncryptedString) Scan(ctx context.Context, field *schema.Field, dst reflect.Value, dbValue interface{}) (err error) {
|
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},
|
Contracts: map[string]interface{}{"name": "jinzhu", "age": 10},
|
||||||
EncryptedString: EncryptedString("pass"),
|
EncryptedString: EncryptedString("pass"),
|
||||||
CreatedTime: createdAt.Unix(),
|
CreatedTime: createdAt.Unix(),
|
||||||
|
JobInfo: Job{
|
||||||
|
Title: "programmer",
|
||||||
|
Number: 9920,
|
||||||
|
Location: "Kenmawr",
|
||||||
|
IsIntern: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := DB.Create(&data).Error; err != nil {
|
if err := DB.Create(&data).Error; err != nil {
|
||||||
|
|
Loading…
Reference in New Issue