scan.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. // Copyright 2012 Gary Burd
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"): you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. // License for the specific language governing permissions and limitations
  13. // under the License.
  14. package redis
  15. import (
  16. "errors"
  17. "fmt"
  18. "reflect"
  19. "strconv"
  20. "strings"
  21. "sync"
  22. )
  23. func ensureLen(d reflect.Value, n int) {
  24. if n > d.Cap() {
  25. d.Set(reflect.MakeSlice(d.Type(), n, n))
  26. } else {
  27. d.SetLen(n)
  28. }
  29. }
  30. func cannotConvert(d reflect.Value, s interface{}) error {
  31. var sname string
  32. switch s.(type) {
  33. case string:
  34. sname = "Redis simple string"
  35. case Error:
  36. sname = "Redis error"
  37. case int64:
  38. sname = "Redis integer"
  39. case []byte:
  40. sname = "Redis bulk string"
  41. case []interface{}:
  42. sname = "Redis array"
  43. default:
  44. sname = reflect.TypeOf(s).String()
  45. }
  46. return fmt.Errorf("cannot convert from %s to %s", sname, d.Type())
  47. }
  48. func convertAssignError(d reflect.Value, s Error) (err error) {
  49. if d.Kind() == reflect.String {
  50. d.SetString(string(s))
  51. } else if d.Kind() == reflect.Slice && d.Type().Elem().Kind() == reflect.Uint8 {
  52. d.SetBytes([]byte(s))
  53. } else {
  54. err = cannotConvert(d, s)
  55. }
  56. return
  57. }
  58. func convertAssignString(d reflect.Value, s string) (err error) {
  59. switch d.Type().Kind() {
  60. case reflect.Float32, reflect.Float64:
  61. var x float64
  62. x, err = strconv.ParseFloat(s, d.Type().Bits())
  63. d.SetFloat(x)
  64. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  65. var x int64
  66. x, err = strconv.ParseInt(s, 10, d.Type().Bits())
  67. d.SetInt(x)
  68. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  69. var x uint64
  70. x, err = strconv.ParseUint(s, 10, d.Type().Bits())
  71. d.SetUint(x)
  72. case reflect.Bool:
  73. var x bool
  74. x, err = strconv.ParseBool(s)
  75. d.SetBool(x)
  76. case reflect.String:
  77. d.SetString(s)
  78. case reflect.Slice:
  79. if d.Type().Elem().Kind() == reflect.Uint8 {
  80. d.SetBytes([]byte(s))
  81. } else {
  82. err = cannotConvert(d, s)
  83. }
  84. default:
  85. err = cannotConvert(d, s)
  86. }
  87. return
  88. }
  89. func convertAssignBulkString(d reflect.Value, s []byte) (err error) {
  90. switch d.Type().Kind() {
  91. case reflect.Slice:
  92. // Handle []byte destination here to avoid unnecessary
  93. // []byte -> string -> []byte converion.
  94. if d.Type().Elem().Kind() == reflect.Uint8 {
  95. d.SetBytes(s)
  96. } else {
  97. err = cannotConvert(d, s)
  98. }
  99. default:
  100. err = convertAssignString(d, string(s))
  101. }
  102. return err
  103. }
  104. func convertAssignInt(d reflect.Value, s int64) (err error) {
  105. switch d.Type().Kind() {
  106. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  107. d.SetInt(s)
  108. if d.Int() != s {
  109. err = strconv.ErrRange
  110. d.SetInt(0)
  111. }
  112. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  113. if s < 0 {
  114. err = strconv.ErrRange
  115. } else {
  116. x := uint64(s)
  117. d.SetUint(x)
  118. if d.Uint() != x {
  119. err = strconv.ErrRange
  120. d.SetUint(0)
  121. }
  122. }
  123. case reflect.Bool:
  124. d.SetBool(s != 0)
  125. default:
  126. err = cannotConvert(d, s)
  127. }
  128. return
  129. }
  130. func convertAssignValue(d reflect.Value, s interface{}) (err error) {
  131. if d.Kind() != reflect.Ptr {
  132. if d.CanAddr() {
  133. d2 := d.Addr()
  134. if d2.CanInterface() {
  135. if scanner, ok := d2.Interface().(Scanner); ok {
  136. return scanner.RedisScan(s)
  137. }
  138. }
  139. }
  140. } else if d.CanInterface() {
  141. // Already a reflect.Ptr
  142. if d.IsNil() {
  143. d.Set(reflect.New(d.Type().Elem()))
  144. }
  145. if scanner, ok := d.Interface().(Scanner); ok {
  146. return scanner.RedisScan(s)
  147. }
  148. }
  149. switch s := s.(type) {
  150. case []byte:
  151. err = convertAssignBulkString(d, s)
  152. case int64:
  153. err = convertAssignInt(d, s)
  154. case string:
  155. err = convertAssignString(d, s)
  156. case Error:
  157. err = convertAssignError(d, s)
  158. default:
  159. err = cannotConvert(d, s)
  160. }
  161. return err
  162. }
  163. func convertAssignArray(d reflect.Value, s []interface{}) error {
  164. if d.Type().Kind() != reflect.Slice {
  165. return cannotConvert(d, s)
  166. }
  167. ensureLen(d, len(s))
  168. for i := 0; i < len(s); i++ {
  169. if err := convertAssignValue(d.Index(i), s[i]); err != nil {
  170. return err
  171. }
  172. }
  173. return nil
  174. }
  175. func convertAssign(d interface{}, s interface{}) (err error) {
  176. if scanner, ok := d.(Scanner); ok {
  177. return scanner.RedisScan(s)
  178. }
  179. // Handle the most common destination types using type switches and
  180. // fall back to reflection for all other types.
  181. switch s := s.(type) {
  182. case nil:
  183. // ignore
  184. case []byte:
  185. switch d := d.(type) {
  186. case *string:
  187. *d = string(s)
  188. case *int:
  189. *d, err = strconv.Atoi(string(s))
  190. case *bool:
  191. *d, err = strconv.ParseBool(string(s))
  192. case *[]byte:
  193. *d = s
  194. case *interface{}:
  195. *d = s
  196. case nil:
  197. // skip value
  198. default:
  199. if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
  200. err = cannotConvert(d, s)
  201. } else {
  202. err = convertAssignBulkString(d.Elem(), s)
  203. }
  204. }
  205. case int64:
  206. switch d := d.(type) {
  207. case *int:
  208. x := int(s)
  209. if int64(x) != s {
  210. err = strconv.ErrRange
  211. x = 0
  212. }
  213. *d = x
  214. case *bool:
  215. *d = s != 0
  216. case *interface{}:
  217. *d = s
  218. case nil:
  219. // skip value
  220. default:
  221. if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
  222. err = cannotConvert(d, s)
  223. } else {
  224. err = convertAssignInt(d.Elem(), s)
  225. }
  226. }
  227. case string:
  228. switch d := d.(type) {
  229. case *string:
  230. *d = s
  231. case *interface{}:
  232. *d = s
  233. case nil:
  234. // skip value
  235. default:
  236. err = cannotConvert(reflect.ValueOf(d), s)
  237. }
  238. case []interface{}:
  239. switch d := d.(type) {
  240. case *[]interface{}:
  241. *d = s
  242. case *interface{}:
  243. *d = s
  244. case nil:
  245. // skip value
  246. default:
  247. if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
  248. err = cannotConvert(d, s)
  249. } else {
  250. err = convertAssignArray(d.Elem(), s)
  251. }
  252. }
  253. case Error:
  254. err = s
  255. default:
  256. err = cannotConvert(reflect.ValueOf(d), s)
  257. }
  258. return
  259. }
  260. // Scan copies from src to the values pointed at by dest.
  261. //
  262. // Scan uses RedisScan if available otherwise:
  263. //
  264. // The values pointed at by dest must be an integer, float, boolean, string,
  265. // []byte, interface{} or slices of these types. Scan uses the standard strconv
  266. // package to convert bulk strings to numeric and boolean types.
  267. //
  268. // If a dest value is nil, then the corresponding src value is skipped.
  269. //
  270. // If a src element is nil, then the corresponding dest value is not modified.
  271. //
  272. // To enable easy use of Scan in a loop, Scan returns the slice of src
  273. // following the copied values.
  274. func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error) {
  275. if len(src) < len(dest) {
  276. return nil, errors.New("redigo.Scan: array short")
  277. }
  278. var err error
  279. for i, d := range dest {
  280. err = convertAssign(d, src[i])
  281. if err != nil {
  282. err = fmt.Errorf("redigo.Scan: cannot assign to dest %d: %v", i, err)
  283. break
  284. }
  285. }
  286. return src[len(dest):], err
  287. }
  288. type fieldSpec struct {
  289. name string
  290. index []int
  291. omitEmpty bool
  292. }
  293. type structSpec struct {
  294. m map[string]*fieldSpec
  295. l []*fieldSpec
  296. }
  297. func (ss *structSpec) fieldSpec(name []byte) *fieldSpec {
  298. return ss.m[string(name)]
  299. }
  300. func compileStructSpec(t reflect.Type, depth map[string]int, index []int, ss *structSpec) {
  301. for i := 0; i < t.NumField(); i++ {
  302. f := t.Field(i)
  303. switch {
  304. case f.PkgPath != "" && !f.Anonymous:
  305. // Ignore unexported fields.
  306. case f.Anonymous:
  307. // TODO: Handle pointers. Requires change to decoder and
  308. // protection against infinite recursion.
  309. if f.Type.Kind() == reflect.Struct {
  310. compileStructSpec(f.Type, depth, append(index, i), ss)
  311. }
  312. default:
  313. fs := &fieldSpec{name: f.Name}
  314. tag := f.Tag.Get("redis")
  315. p := strings.Split(tag, ",")
  316. if len(p) > 0 {
  317. if p[0] == "-" {
  318. continue
  319. }
  320. if len(p[0]) > 0 {
  321. fs.name = p[0]
  322. }
  323. for _, s := range p[1:] {
  324. switch s {
  325. case "omitempty":
  326. fs.omitEmpty = true
  327. default:
  328. panic(fmt.Errorf("redigo: unknown field tag %s for type %s", s, t.Name()))
  329. }
  330. }
  331. }
  332. d, found := depth[fs.name]
  333. if !found {
  334. d = 1 << 30
  335. }
  336. switch {
  337. case len(index) == d:
  338. // At same depth, remove from result.
  339. delete(ss.m, fs.name)
  340. j := 0
  341. for i := 0; i < len(ss.l); i++ {
  342. if fs.name != ss.l[i].name {
  343. ss.l[j] = ss.l[i]
  344. j += 1
  345. }
  346. }
  347. ss.l = ss.l[:j]
  348. case len(index) < d:
  349. fs.index = make([]int, len(index)+1)
  350. copy(fs.index, index)
  351. fs.index[len(index)] = i
  352. depth[fs.name] = len(index)
  353. ss.m[fs.name] = fs
  354. ss.l = append(ss.l, fs)
  355. }
  356. }
  357. }
  358. }
  359. var (
  360. structSpecMutex sync.RWMutex
  361. structSpecCache = make(map[reflect.Type]*structSpec)
  362. defaultFieldSpec = &fieldSpec{}
  363. )
  364. func structSpecForType(t reflect.Type) *structSpec {
  365. structSpecMutex.RLock()
  366. ss, found := structSpecCache[t]
  367. structSpecMutex.RUnlock()
  368. if found {
  369. return ss
  370. }
  371. structSpecMutex.Lock()
  372. defer structSpecMutex.Unlock()
  373. ss, found = structSpecCache[t]
  374. if found {
  375. return ss
  376. }
  377. ss = &structSpec{m: make(map[string]*fieldSpec)}
  378. compileStructSpec(t, make(map[string]int), nil, ss)
  379. structSpecCache[t] = ss
  380. return ss
  381. }
  382. var errScanStructValue = errors.New("redigo.ScanStruct: value must be non-nil pointer to a struct")
  383. // ScanStruct scans alternating names and values from src to a struct. The
  384. // HGETALL and CONFIG GET commands return replies in this format.
  385. //
  386. // ScanStruct uses exported field names to match values in the response. Use
  387. // 'redis' field tag to override the name:
  388. //
  389. // Field int `redis:"myName"`
  390. //
  391. // Fields with the tag redis:"-" are ignored.
  392. //
  393. // Each field uses RedisScan if available otherwise:
  394. // Integer, float, boolean, string and []byte fields are supported. Scan uses the
  395. // standard strconv package to convert bulk string values to numeric and
  396. // boolean types.
  397. //
  398. // If a src element is nil, then the corresponding field is not modified.
  399. func ScanStruct(src []interface{}, dest interface{}) error {
  400. d := reflect.ValueOf(dest)
  401. if d.Kind() != reflect.Ptr || d.IsNil() {
  402. return errScanStructValue
  403. }
  404. d = d.Elem()
  405. if d.Kind() != reflect.Struct {
  406. return errScanStructValue
  407. }
  408. ss := structSpecForType(d.Type())
  409. if len(src)%2 != 0 {
  410. return errors.New("redigo.ScanStruct: number of values not a multiple of 2")
  411. }
  412. for i := 0; i < len(src); i += 2 {
  413. s := src[i+1]
  414. if s == nil {
  415. continue
  416. }
  417. name, ok := src[i].([]byte)
  418. if !ok {
  419. return fmt.Errorf("redigo.ScanStruct: key %d not a bulk string value", i)
  420. }
  421. fs := ss.fieldSpec(name)
  422. if fs == nil {
  423. continue
  424. }
  425. if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
  426. return fmt.Errorf("redigo.ScanStruct: cannot assign field %s: %v", fs.name, err)
  427. }
  428. }
  429. return nil
  430. }
  431. var (
  432. errScanSliceValue = errors.New("redigo.ScanSlice: dest must be non-nil pointer to a struct")
  433. )
  434. // ScanSlice scans src to the slice pointed to by dest. The elements the dest
  435. // slice must be integer, float, boolean, string, struct or pointer to struct
  436. // values.
  437. //
  438. // Struct fields must be integer, float, boolean or string values. All struct
  439. // fields are used unless a subset is specified using fieldNames.
  440. func ScanSlice(src []interface{}, dest interface{}, fieldNames ...string) error {
  441. d := reflect.ValueOf(dest)
  442. if d.Kind() != reflect.Ptr || d.IsNil() {
  443. return errScanSliceValue
  444. }
  445. d = d.Elem()
  446. if d.Kind() != reflect.Slice {
  447. return errScanSliceValue
  448. }
  449. isPtr := false
  450. t := d.Type().Elem()
  451. if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct {
  452. isPtr = true
  453. t = t.Elem()
  454. }
  455. if t.Kind() != reflect.Struct {
  456. ensureLen(d, len(src))
  457. for i, s := range src {
  458. if s == nil {
  459. continue
  460. }
  461. if err := convertAssignValue(d.Index(i), s); err != nil {
  462. return fmt.Errorf("redigo.ScanSlice: cannot assign element %d: %v", i, err)
  463. }
  464. }
  465. return nil
  466. }
  467. ss := structSpecForType(t)
  468. fss := ss.l
  469. if len(fieldNames) > 0 {
  470. fss = make([]*fieldSpec, len(fieldNames))
  471. for i, name := range fieldNames {
  472. fss[i] = ss.m[name]
  473. if fss[i] == nil {
  474. return fmt.Errorf("redigo.ScanSlice: ScanSlice bad field name %s", name)
  475. }
  476. }
  477. }
  478. if len(fss) == 0 {
  479. return errors.New("redigo.ScanSlice: no struct fields")
  480. }
  481. n := len(src) / len(fss)
  482. if n*len(fss) != len(src) {
  483. return errors.New("redigo.ScanSlice: length not a multiple of struct field count")
  484. }
  485. ensureLen(d, n)
  486. for i := 0; i < n; i++ {
  487. d := d.Index(i)
  488. if isPtr {
  489. if d.IsNil() {
  490. d.Set(reflect.New(t))
  491. }
  492. d = d.Elem()
  493. }
  494. for j, fs := range fss {
  495. s := src[i*len(fss)+j]
  496. if s == nil {
  497. continue
  498. }
  499. if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
  500. return fmt.Errorf("redigo.ScanSlice: cannot assign element %d to field %s: %v", i*len(fss)+j, fs.name, err)
  501. }
  502. }
  503. }
  504. return nil
  505. }
  506. // Args is a helper for constructing command arguments from structured values.
  507. type Args []interface{}
  508. // Add returns the result of appending value to args.
  509. func (args Args) Add(value ...interface{}) Args {
  510. return append(args, value...)
  511. }
  512. // AddFlat returns the result of appending the flattened value of v to args.
  513. //
  514. // Maps are flattened by appending the alternating keys and map values to args.
  515. //
  516. // Slices are flattened by appending the slice elements to args.
  517. //
  518. // Structs are flattened by appending the alternating names and values of
  519. // exported fields to args. If v is a nil struct pointer, then nothing is
  520. // appended. The 'redis' field tag overrides struct field names. See ScanStruct
  521. // for more information on the use of the 'redis' field tag.
  522. //
  523. // Other types are appended to args as is.
  524. func (args Args) AddFlat(v interface{}) Args {
  525. rv := reflect.ValueOf(v)
  526. switch rv.Kind() {
  527. case reflect.Struct:
  528. args = flattenStruct(args, rv)
  529. case reflect.Slice:
  530. for i := 0; i < rv.Len(); i++ {
  531. args = append(args, rv.Index(i).Interface())
  532. }
  533. case reflect.Map:
  534. for _, k := range rv.MapKeys() {
  535. args = append(args, k.Interface(), rv.MapIndex(k).Interface())
  536. }
  537. case reflect.Ptr:
  538. if rv.Type().Elem().Kind() == reflect.Struct {
  539. if !rv.IsNil() {
  540. args = flattenStruct(args, rv.Elem())
  541. }
  542. } else {
  543. args = append(args, v)
  544. }
  545. default:
  546. args = append(args, v)
  547. }
  548. return args
  549. }
  550. func flattenStruct(args Args, v reflect.Value) Args {
  551. ss := structSpecForType(v.Type())
  552. for _, fs := range ss.l {
  553. fv := v.FieldByIndex(fs.index)
  554. if fs.omitEmpty {
  555. var empty = false
  556. switch fv.Kind() {
  557. case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
  558. empty = fv.Len() == 0
  559. case reflect.Bool:
  560. empty = !fv.Bool()
  561. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  562. empty = fv.Int() == 0
  563. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  564. empty = fv.Uint() == 0
  565. case reflect.Float32, reflect.Float64:
  566. empty = fv.Float() == 0
  567. case reflect.Interface, reflect.Ptr:
  568. empty = fv.IsNil()
  569. }
  570. if empty {
  571. continue
  572. }
  573. }
  574. args = append(args, fs.name, fv.Interface())
  575. }
  576. return args
  577. }