serializer.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package schema
  2. import (
  3. "bytes"
  4. "context"
  5. "database/sql"
  6. "database/sql/driver"
  7. "encoding/gob"
  8. "encoding/json"
  9. "fmt"
  10. "reflect"
  11. "strings"
  12. "sync"
  13. "time"
  14. )
  15. var serializerMap = sync.Map{}
  16. // RegisterSerializer register serializer
  17. func RegisterSerializer(name string, serializer SerializerInterface) {
  18. serializerMap.Store(strings.ToLower(name), serializer)
  19. }
  20. // GetSerializer get serializer
  21. func GetSerializer(name string) (serializer SerializerInterface, ok bool) {
  22. v, ok := serializerMap.Load(strings.ToLower(name))
  23. if ok {
  24. serializer, ok = v.(SerializerInterface)
  25. }
  26. return serializer, ok
  27. }
  28. func init() {
  29. RegisterSerializer("json", JSONSerializer{})
  30. RegisterSerializer("unixtime", UnixSecondSerializer{})
  31. RegisterSerializer("gob", GobSerializer{})
  32. }
  33. // Serializer field value serializer
  34. type serializer struct {
  35. Field *Field
  36. Serializer SerializerInterface
  37. SerializeValuer SerializerValuerInterface
  38. Destination reflect.Value
  39. Context context.Context
  40. value interface{}
  41. fieldValue interface{}
  42. }
  43. // Scan implements sql.Scanner interface
  44. func (s *serializer) Scan(value interface{}) error {
  45. s.value = value
  46. return nil
  47. }
  48. // Value implements driver.Valuer interface
  49. func (s serializer) Value() (driver.Value, error) {
  50. return s.SerializeValuer.Value(s.Context, s.Field, s.Destination, s.fieldValue)
  51. }
  52. // SerializerInterface serializer interface
  53. type SerializerInterface interface {
  54. Scan(ctx context.Context, field *Field, dst reflect.Value, dbValue interface{}) error
  55. SerializerValuerInterface
  56. }
  57. // SerializerValuerInterface serializer valuer interface
  58. type SerializerValuerInterface interface {
  59. Value(ctx context.Context, field *Field, dst reflect.Value, fieldValue interface{}) (interface{}, error)
  60. }
  61. // JSONSerializer json serializer
  62. type JSONSerializer struct{}
  63. // Scan implements serializer interface
  64. func (JSONSerializer) Scan(ctx context.Context, field *Field, dst reflect.Value, dbValue interface{}) (err error) {
  65. fieldValue := reflect.New(field.FieldType)
  66. if dbValue != nil {
  67. var bytes []byte
  68. switch v := dbValue.(type) {
  69. case []byte:
  70. bytes = v
  71. case string:
  72. bytes = []byte(v)
  73. default:
  74. bytes, err = json.Marshal(v)
  75. if err != nil {
  76. return err
  77. }
  78. }
  79. if len(bytes) > 0 {
  80. err = json.Unmarshal(bytes, fieldValue.Interface())
  81. }
  82. }
  83. field.ReflectValueOf(ctx, dst).Set(fieldValue.Elem())
  84. return
  85. }
  86. // Value implements serializer interface
  87. func (JSONSerializer) Value(ctx context.Context, field *Field, dst reflect.Value, fieldValue interface{}) (interface{}, error) {
  88. result, err := json.Marshal(fieldValue)
  89. if string(result) == "null" {
  90. if field.TagSettings["NOT NULL"] != "" {
  91. return "", nil
  92. }
  93. return nil, err
  94. }
  95. return string(result), err
  96. }
  97. // UnixSecondSerializer json serializer
  98. type UnixSecondSerializer struct{}
  99. // Scan implements serializer interface
  100. func (UnixSecondSerializer) Scan(ctx context.Context, field *Field, dst reflect.Value, dbValue interface{}) (err error) {
  101. t := sql.NullTime{}
  102. if err = t.Scan(dbValue); err == nil && t.Valid {
  103. err = field.Set(ctx, dst, t.Time.Unix())
  104. }
  105. return
  106. }
  107. // Value implements serializer interface
  108. func (UnixSecondSerializer) Value(ctx context.Context, field *Field, dst reflect.Value, fieldValue interface{}) (result interface{}, err error) {
  109. rv := reflect.ValueOf(fieldValue)
  110. switch v := fieldValue.(type) {
  111. case int64, int, uint, uint64, int32, uint32, int16, uint16:
  112. result = time.Unix(reflect.Indirect(rv).Int(), 0).UTC()
  113. case *int64, *int, *uint, *uint64, *int32, *uint32, *int16, *uint16:
  114. if rv.IsZero() {
  115. return nil, nil
  116. }
  117. result = time.Unix(reflect.Indirect(rv).Int(), 0).UTC()
  118. default:
  119. err = fmt.Errorf("invalid field type %#v for UnixSecondSerializer, only int, uint supported", v)
  120. }
  121. return
  122. }
  123. // GobSerializer gob serializer
  124. type GobSerializer struct{}
  125. // Scan implements serializer interface
  126. func (GobSerializer) Scan(ctx context.Context, field *Field, dst reflect.Value, dbValue interface{}) (err error) {
  127. fieldValue := reflect.New(field.FieldType)
  128. if dbValue != nil {
  129. var bytesValue []byte
  130. switch v := dbValue.(type) {
  131. case []byte:
  132. bytesValue = v
  133. default:
  134. return fmt.Errorf("failed to unmarshal gob value: %#v", dbValue)
  135. }
  136. if len(bytesValue) > 0 {
  137. decoder := gob.NewDecoder(bytes.NewBuffer(bytesValue))
  138. err = decoder.Decode(fieldValue.Interface())
  139. }
  140. }
  141. field.ReflectValueOf(ctx, dst).Set(fieldValue.Elem())
  142. return
  143. }
  144. // Value implements serializer interface
  145. func (GobSerializer) Value(ctx context.Context, field *Field, dst reflect.Value, fieldValue interface{}) (interface{}, error) {
  146. buf := new(bytes.Buffer)
  147. err := gob.NewEncoder(buf).Encode(fieldValue)
  148. return buf.Bytes(), err
  149. }