This commit is contained in:
Vladimir Mihailenco 2021-01-29 12:04:39 +02:00
parent 6f96bebac7
commit 8926f2992a
2 changed files with 13 additions and 23 deletions

View File

@ -34,7 +34,7 @@ var (
reflect.Interface: decodeUnsupported, reflect.Interface: decodeUnsupported,
reflect.Map: decodeUnsupported, reflect.Map: decodeUnsupported,
reflect.Ptr: decodeUnsupported, reflect.Ptr: decodeUnsupported,
reflect.Slice: decodeStringSlice, reflect.Slice: decodeSlice,
reflect.String: decodeString, reflect.String: decodeString,
reflect.Struct: decodeUnsupported, reflect.Struct: decodeUnsupported,
reflect.UnsafePointer: decodeUnsupported, reflect.UnsafePointer: decodeUnsupported,
@ -69,12 +69,7 @@ func Scan(vals []interface{}, dest interface{}) error {
// iterating through the fields of a struct type every time values are // iterating through the fields of a struct type every time values are
// scanned into it. // scanned into it.
typ := v.Type() typ := v.Type()
fMap, ok := structSpecs.get(typ) fMap := structSpecs.get(typ)
if !ok {
fMap = makeStructSpecs(v, "redis")
structSpecs.set(typ, fMap)
}
// Iterate through the (key, value) sequence. // Iterate through the (key, value) sequence.
for i := 0; i < len(vals); i += 2 { for i := 0; i < len(vals); i += 2 {
@ -143,7 +138,7 @@ func decodeString(f reflect.Value, s string) error {
return nil return nil
} }
func decodeStringSlice(f reflect.Value, s string) error { func decodeSlice(f reflect.Value, s string) error {
// []byte slice ([]uint8). // []byte slice ([]uint8).
if f.Type().Elem().Kind() == reflect.Uint8 { if f.Type().Elem().Kind() == reflect.Uint8 {
f.SetBytes([]byte(s)) f.SetBytes([]byte(s))
@ -151,6 +146,6 @@ func decodeStringSlice(f reflect.Value, s string) error {
return nil return nil
} }
func decodeUnsupported(f reflect.Value, s string) error { func decodeUnsupported(v reflect.Value, s string) error {
return fmt.Errorf("redis.Scan(unsupported type %v)", f) return fmt.Errorf("redis.Scan(unsupported %s)", v.Type())
} }

View File

@ -24,22 +24,17 @@ type structMap struct {
} }
func newStructMap() *structMap { func newStructMap() *structMap {
return &structMap{ return new(structMap)
m: sync.Map{},
}
} }
func (s *structMap) get(t reflect.Type) (*structFields, bool) { func (s *structMap) get(t reflect.Type) *structFields {
m, ok := s.m.Load(t) if v, ok := s.m.Load(t); ok {
if !ok { return m.(*structFields), ok
return nil, ok
} }
return m.(*structFields), true fMap := getStructFields(v, "redis")
} s.m.Store(t, fMap)
return fmap, true
func (s *structMap) set(t reflect.Type, sf *structFields) {
s.m.Store(t, sf)
} }
func newStructFields() *structFields { func newStructFields() *structFields {
@ -57,7 +52,7 @@ func (s *structFields) get(tag string) (*structField, bool) {
return f, ok return f, ok
} }
func makeStructSpecs(ob reflect.Value, fieldTag string) *structFields { func getStructFields(ob reflect.Value, fieldTag string) *structFields {
var ( var (
num = ob.NumField() num = ob.NumField()
out = newStructFields() out = newStructFields()