|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- package db
-
- import (
- "context"
- "fmt"
- "reflect"
-
- "gorm.io/gorm/schema"
- )
-
- // 必须给结构体(而不是指针)实现此接口。FromString实现为静态方法
- type StringDBValuer interface {
- ToString() (string, error)
- FromString(str string) (any, error)
- }
-
- type StringSerializer struct {
- }
-
- func (StringSerializer) Scan(ctx context.Context, field *schema.Field, dst reflect.Value, dbValue interface{}) error {
- if dbValue == nil {
- fieldValue := reflect.New(field.FieldType)
- field.ReflectValueOf(ctx, dst).Set(fieldValue.Elem())
- return nil
- }
-
- str := ""
- switch v := dbValue.(type) {
- case []byte:
- str = string(v)
- case string:
- str = v
- default:
- return fmt.Errorf("expected []byte or string, got: %T", dbValue)
- }
-
- if field.FieldType.Kind() == reflect.Struct {
- val := reflect.Zero(field.FieldType)
-
- sv, ok := val.Interface().(StringDBValuer)
- if !ok {
- return fmt.Errorf("ref of field type %v is not StringDBValuer", field.FieldType)
- }
-
- v2, err := sv.FromString(str)
- if err != nil {
- return err
- }
-
- field.ReflectValueOf(ctx, dst).Set(reflect.ValueOf(v2))
- return nil
- }
-
- if field.FieldType.Kind() == reflect.Ptr {
- val := reflect.Zero(field.FieldType.Elem())
-
- sv, ok := val.Interface().(StringDBValuer)
- if !ok {
- return fmt.Errorf("field type %v is not StringDBValuer", field.FieldType)
- }
-
- v2, err := sv.FromString(str)
- if err != nil {
- return err
- }
-
- field.ReflectValueOf(ctx, dst).Set(reflect.ValueOf(v2))
- return nil
- }
-
- return fmt.Errorf("unsupported field type: %v", field.FieldType)
- }
-
- func (StringSerializer) Value(ctx context.Context, field *schema.Field, dst reflect.Value, fieldValue interface{}) (interface{}, error) {
- val := reflect.ValueOf(fieldValue)
- if val.Kind() == reflect.Struct {
- sv, ok := val.Interface().(StringDBValuer)
- if !ok {
- return nil, fmt.Errorf("ref of field type %v is not StringDBValuer", field.FieldType)
- }
-
- return sv.ToString()
- }
-
- if val.Kind() == reflect.Ptr {
- sv, ok := val.Elem().Interface().(StringDBValuer)
- if !ok {
- return nil, fmt.Errorf("field type %v is not StringDBValuer", field.FieldType)
- }
-
- return sv.ToString()
- }
-
- return nil, fmt.Errorf("unsupported field type: %v", field.FieldType)
- }
-
- func init() {
- schema.RegisterSerializer("string", StringSerializer{})
- }
|