|
@@ -1,120 +0,0 @@
|
|
|
-// Copyright 2012 Gary Burd
|
|
|
|
|
-//
|
|
|
|
|
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
|
|
|
|
-// not use this file except in compliance with the License. You may obtain
|
|
|
|
|
-// a copy of the License at
|
|
|
|
|
-//
|
|
|
|
|
-// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
-//
|
|
|
|
|
-// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
|
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
|
-// License for the specific language governing permissions and limitations
|
|
|
|
|
-// under the License.
|
|
|
|
|
-
|
|
|
|
|
-package redisx
|
|
|
|
|
-
|
|
|
|
|
-import (
|
|
|
|
|
- "errors"
|
|
|
|
|
- "reflect"
|
|
|
|
|
- "strconv"
|
|
|
|
|
-)
|
|
|
|
|
-
|
|
|
|
|
-// ScanStruct is deprecated. Use redis.ScanStruct instead.
|
|
|
|
|
-//
|
|
|
|
|
-// ScanStruct scans a reply containing alternating names and values to a
|
|
|
|
|
-// struct. The HGETALL and CONFIG GET commands return replies in this format.
|
|
|
|
|
-//
|
|
|
|
|
-// ScanStruct uses the struct field name to match values in the response. Use
|
|
|
|
|
-// 'redis' field tag to override the name:
|
|
|
|
|
-//
|
|
|
|
|
-// Field int `redis:"myName"`
|
|
|
|
|
-//
|
|
|
|
|
-// Fields with the tag redis:"-" are ignored.
|
|
|
|
|
-func ScanStruct(reply interface{}, dst interface{}) error {
|
|
|
|
|
- v := reflect.ValueOf(dst)
|
|
|
|
|
- if v.Kind() != reflect.Ptr || v.IsNil() {
|
|
|
|
|
- return errors.New("redigo: ScanStruct value must be non-nil pointer")
|
|
|
|
|
- }
|
|
|
|
|
- v = v.Elem()
|
|
|
|
|
- ss := structSpecForType(v.Type())
|
|
|
|
|
-
|
|
|
|
|
- p, ok := reply.([]interface{})
|
|
|
|
|
- if !ok {
|
|
|
|
|
- return errors.New("redigo: ScanStruct expectes multibulk reply")
|
|
|
|
|
- }
|
|
|
|
|
- if len(p)%2 != 0 {
|
|
|
|
|
- return errors.New("redigo: ScanStruct expects even number of values in reply")
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- for i := 0; i < len(p); i += 2 {
|
|
|
|
|
- name, ok := p[i].([]byte)
|
|
|
|
|
- if !ok {
|
|
|
|
|
- return errors.New("redigo: ScanStruct key not a bulk value")
|
|
|
|
|
- }
|
|
|
|
|
- value, ok := p[i+1].([]byte)
|
|
|
|
|
- if !ok {
|
|
|
|
|
- return errors.New("redigo: ScanStruct value not a bulk value")
|
|
|
|
|
- }
|
|
|
|
|
- fs := ss.fieldSpec(name)
|
|
|
|
|
- if fs == nil {
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
- fv := v.FieldByIndex(fs.index)
|
|
|
|
|
- switch fv.Type().Kind() {
|
|
|
|
|
- case reflect.String:
|
|
|
|
|
- fv.SetString(string(value))
|
|
|
|
|
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
|
|
|
- x, err := strconv.ParseInt(string(value), 10, fv.Type().Bits())
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- return err
|
|
|
|
|
- }
|
|
|
|
|
- fv.SetInt(x)
|
|
|
|
|
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
|
|
|
- x, err := strconv.ParseUint(string(value), 10, fv.Type().Bits())
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- return err
|
|
|
|
|
- }
|
|
|
|
|
- fv.SetUint(x)
|
|
|
|
|
- case reflect.Float32, reflect.Float64:
|
|
|
|
|
- x, err := strconv.ParseFloat(string(value), fv.Type().Bits())
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- return err
|
|
|
|
|
- }
|
|
|
|
|
- fv.SetFloat(x)
|
|
|
|
|
- case reflect.Bool:
|
|
|
|
|
- x := len(value) != 0 && (len(value) != 1 || value[0] != '0')
|
|
|
|
|
- fv.SetBool(x)
|
|
|
|
|
- case reflect.Slice:
|
|
|
|
|
- if fv.Type().Elem().Kind() != reflect.Uint8 {
|
|
|
|
|
- // TODO: check field types in structSpec
|
|
|
|
|
- panic("redigo: unsuported type for field " + string(name))
|
|
|
|
|
- }
|
|
|
|
|
- fv.SetBytes(value)
|
|
|
|
|
- default:
|
|
|
|
|
- // TODO: check field types in structSpec
|
|
|
|
|
- panic("redigo: unsuported type for field " + string(name))
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return nil
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// AppendStruct is deprecated. Use redis.Args{}.AddFlat() instead.
|
|
|
|
|
-func AppendStruct(args []interface{}, src interface{}) []interface{} {
|
|
|
|
|
- v := reflect.ValueOf(src)
|
|
|
|
|
- if v.Kind() == reflect.Ptr {
|
|
|
|
|
- if v.IsNil() {
|
|
|
|
|
- panic("redigo: FormatStruct argument must not be nil")
|
|
|
|
|
- }
|
|
|
|
|
- v = v.Elem()
|
|
|
|
|
- }
|
|
|
|
|
- if v.Kind() != reflect.Struct {
|
|
|
|
|
- panic("redigo: FormatStruct argument must be a struct or pointer to a struct")
|
|
|
|
|
- }
|
|
|
|
|
- ss := structSpecForType(v.Type())
|
|
|
|
|
- for _, fs := range ss.l {
|
|
|
|
|
- fv := v.FieldByIndex(fs.index)
|
|
|
|
|
- args = append(args, fs.name, fv.Interface())
|
|
|
|
|
- }
|
|
|
|
|
- return args
|
|
|
|
|
-}
|
|
|