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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 jing1
						jing1