scan.go 16 KB

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