feat: support gob serialize
This commit is contained in:
		
							parent
							
								
									b1201fce4e
								
							
						
					
					
						commit
						6c7b46a231
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user