http urls monitor.

command.go 36KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875
  1. package redis
  2. import (
  3. "fmt"
  4. "net"
  5. "strconv"
  6. "strings"
  7. "time"
  8. "github.com/go-redis/redis/internal"
  9. "github.com/go-redis/redis/internal/proto"
  10. )
  11. type Cmder interface {
  12. Name() string
  13. Args() []interface{}
  14. stringArg(int) string
  15. readReply(rd *proto.Reader) error
  16. setErr(error)
  17. readTimeout() *time.Duration
  18. Err() error
  19. }
  20. func setCmdsErr(cmds []Cmder, e error) {
  21. for _, cmd := range cmds {
  22. if cmd.Err() == nil {
  23. cmd.setErr(e)
  24. }
  25. }
  26. }
  27. func cmdsFirstErr(cmds []Cmder) error {
  28. for _, cmd := range cmds {
  29. if err := cmd.Err(); err != nil {
  30. return err
  31. }
  32. }
  33. return nil
  34. }
  35. func writeCmd(wr *proto.Writer, cmds ...Cmder) error {
  36. for _, cmd := range cmds {
  37. err := wr.WriteArgs(cmd.Args())
  38. if err != nil {
  39. return err
  40. }
  41. }
  42. return nil
  43. }
  44. func cmdString(cmd Cmder, val interface{}) string {
  45. var ss []string
  46. for _, arg := range cmd.Args() {
  47. ss = append(ss, fmt.Sprint(arg))
  48. }
  49. s := strings.Join(ss, " ")
  50. if err := cmd.Err(); err != nil {
  51. return s + ": " + err.Error()
  52. }
  53. if val != nil {
  54. switch vv := val.(type) {
  55. case []byte:
  56. return s + ": " + string(vv)
  57. default:
  58. return s + ": " + fmt.Sprint(val)
  59. }
  60. }
  61. return s
  62. }
  63. func cmdFirstKeyPos(cmd Cmder, info *CommandInfo) int {
  64. switch cmd.Name() {
  65. case "eval", "evalsha":
  66. if cmd.stringArg(2) != "0" {
  67. return 3
  68. }
  69. return 0
  70. case "publish":
  71. return 1
  72. }
  73. if info == nil {
  74. return 0
  75. }
  76. return int(info.FirstKeyPos)
  77. }
  78. //------------------------------------------------------------------------------
  79. type baseCmd struct {
  80. _args []interface{}
  81. err error
  82. _readTimeout *time.Duration
  83. }
  84. var _ Cmder = (*Cmd)(nil)
  85. func (cmd *baseCmd) Err() error {
  86. return cmd.err
  87. }
  88. func (cmd *baseCmd) Args() []interface{} {
  89. return cmd._args
  90. }
  91. func (cmd *baseCmd) stringArg(pos int) string {
  92. if pos < 0 || pos >= len(cmd._args) {
  93. return ""
  94. }
  95. s, _ := cmd._args[pos].(string)
  96. return s
  97. }
  98. func (cmd *baseCmd) Name() string {
  99. if len(cmd._args) > 0 {
  100. // Cmd name must be lower cased.
  101. s := internal.ToLower(cmd.stringArg(0))
  102. cmd._args[0] = s
  103. return s
  104. }
  105. return ""
  106. }
  107. func (cmd *baseCmd) readTimeout() *time.Duration {
  108. return cmd._readTimeout
  109. }
  110. func (cmd *baseCmd) setReadTimeout(d time.Duration) {
  111. cmd._readTimeout = &d
  112. }
  113. func (cmd *baseCmd) setErr(e error) {
  114. cmd.err = e
  115. }
  116. //------------------------------------------------------------------------------
  117. type Cmd struct {
  118. baseCmd
  119. val interface{}
  120. }
  121. func NewCmd(args ...interface{}) *Cmd {
  122. return &Cmd{
  123. baseCmd: baseCmd{_args: args},
  124. }
  125. }
  126. func (cmd *Cmd) Val() interface{} {
  127. return cmd.val
  128. }
  129. func (cmd *Cmd) Result() (interface{}, error) {
  130. return cmd.val, cmd.err
  131. }
  132. func (cmd *Cmd) String() (string, error) {
  133. if cmd.err != nil {
  134. return "", cmd.err
  135. }
  136. switch val := cmd.val.(type) {
  137. case string:
  138. return val, nil
  139. default:
  140. err := fmt.Errorf("redis: unexpected type=%T for String", val)
  141. return "", err
  142. }
  143. }
  144. func (cmd *Cmd) Int() (int, error) {
  145. if cmd.err != nil {
  146. return 0, cmd.err
  147. }
  148. switch val := cmd.val.(type) {
  149. case int64:
  150. return int(val), nil
  151. case string:
  152. return strconv.Atoi(val)
  153. default:
  154. err := fmt.Errorf("redis: unexpected type=%T for Int", val)
  155. return 0, err
  156. }
  157. }
  158. func (cmd *Cmd) Int64() (int64, error) {
  159. if cmd.err != nil {
  160. return 0, cmd.err
  161. }
  162. switch val := cmd.val.(type) {
  163. case int64:
  164. return val, nil
  165. case string:
  166. return strconv.ParseInt(val, 10, 64)
  167. default:
  168. err := fmt.Errorf("redis: unexpected type=%T for Int64", val)
  169. return 0, err
  170. }
  171. }
  172. func (cmd *Cmd) Uint64() (uint64, error) {
  173. if cmd.err != nil {
  174. return 0, cmd.err
  175. }
  176. switch val := cmd.val.(type) {
  177. case int64:
  178. return uint64(val), nil
  179. case string:
  180. return strconv.ParseUint(val, 10, 64)
  181. default:
  182. err := fmt.Errorf("redis: unexpected type=%T for Uint64", val)
  183. return 0, err
  184. }
  185. }
  186. func (cmd *Cmd) Float64() (float64, error) {
  187. if cmd.err != nil {
  188. return 0, cmd.err
  189. }
  190. switch val := cmd.val.(type) {
  191. case int64:
  192. return float64(val), nil
  193. case string:
  194. return strconv.ParseFloat(val, 64)
  195. default:
  196. err := fmt.Errorf("redis: unexpected type=%T for Float64", val)
  197. return 0, err
  198. }
  199. }
  200. func (cmd *Cmd) Bool() (bool, error) {
  201. if cmd.err != nil {
  202. return false, cmd.err
  203. }
  204. switch val := cmd.val.(type) {
  205. case int64:
  206. return val != 0, nil
  207. case string:
  208. return strconv.ParseBool(val)
  209. default:
  210. err := fmt.Errorf("redis: unexpected type=%T for Bool", val)
  211. return false, err
  212. }
  213. }
  214. func (cmd *Cmd) readReply(rd *proto.Reader) error {
  215. cmd.val, cmd.err = rd.ReadReply(sliceParser)
  216. return cmd.err
  217. }
  218. // Implements proto.MultiBulkParse
  219. func sliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  220. vals := make([]interface{}, 0, n)
  221. for i := int64(0); i < n; i++ {
  222. v, err := rd.ReadReply(sliceParser)
  223. if err != nil {
  224. if err == Nil {
  225. vals = append(vals, nil)
  226. continue
  227. }
  228. if err, ok := err.(proto.RedisError); ok {
  229. vals = append(vals, err)
  230. continue
  231. }
  232. return nil, err
  233. }
  234. switch v := v.(type) {
  235. case string:
  236. vals = append(vals, v)
  237. default:
  238. vals = append(vals, v)
  239. }
  240. }
  241. return vals, nil
  242. }
  243. //------------------------------------------------------------------------------
  244. type SliceCmd struct {
  245. baseCmd
  246. val []interface{}
  247. }
  248. var _ Cmder = (*SliceCmd)(nil)
  249. func NewSliceCmd(args ...interface{}) *SliceCmd {
  250. return &SliceCmd{
  251. baseCmd: baseCmd{_args: args},
  252. }
  253. }
  254. func (cmd *SliceCmd) Val() []interface{} {
  255. return cmd.val
  256. }
  257. func (cmd *SliceCmd) Result() ([]interface{}, error) {
  258. return cmd.val, cmd.err
  259. }
  260. func (cmd *SliceCmd) String() string {
  261. return cmdString(cmd, cmd.val)
  262. }
  263. func (cmd *SliceCmd) readReply(rd *proto.Reader) error {
  264. var v interface{}
  265. v, cmd.err = rd.ReadArrayReply(sliceParser)
  266. if cmd.err != nil {
  267. return cmd.err
  268. }
  269. cmd.val = v.([]interface{})
  270. return nil
  271. }
  272. //------------------------------------------------------------------------------
  273. type StatusCmd struct {
  274. baseCmd
  275. val string
  276. }
  277. var _ Cmder = (*StatusCmd)(nil)
  278. func NewStatusCmd(args ...interface{}) *StatusCmd {
  279. return &StatusCmd{
  280. baseCmd: baseCmd{_args: args},
  281. }
  282. }
  283. func (cmd *StatusCmd) Val() string {
  284. return cmd.val
  285. }
  286. func (cmd *StatusCmd) Result() (string, error) {
  287. return cmd.val, cmd.err
  288. }
  289. func (cmd *StatusCmd) String() string {
  290. return cmdString(cmd, cmd.val)
  291. }
  292. func (cmd *StatusCmd) readReply(rd *proto.Reader) error {
  293. cmd.val, cmd.err = rd.ReadString()
  294. return cmd.err
  295. }
  296. //------------------------------------------------------------------------------
  297. type IntCmd struct {
  298. baseCmd
  299. val int64
  300. }
  301. var _ Cmder = (*IntCmd)(nil)
  302. func NewIntCmd(args ...interface{}) *IntCmd {
  303. return &IntCmd{
  304. baseCmd: baseCmd{_args: args},
  305. }
  306. }
  307. func (cmd *IntCmd) Val() int64 {
  308. return cmd.val
  309. }
  310. func (cmd *IntCmd) Result() (int64, error) {
  311. return cmd.val, cmd.err
  312. }
  313. func (cmd *IntCmd) String() string {
  314. return cmdString(cmd, cmd.val)
  315. }
  316. func (cmd *IntCmd) readReply(rd *proto.Reader) error {
  317. cmd.val, cmd.err = rd.ReadIntReply()
  318. return cmd.err
  319. }
  320. //------------------------------------------------------------------------------
  321. type DurationCmd struct {
  322. baseCmd
  323. val time.Duration
  324. precision time.Duration
  325. }
  326. var _ Cmder = (*DurationCmd)(nil)
  327. func NewDurationCmd(precision time.Duration, args ...interface{}) *DurationCmd {
  328. return &DurationCmd{
  329. baseCmd: baseCmd{_args: args},
  330. precision: precision,
  331. }
  332. }
  333. func (cmd *DurationCmd) Val() time.Duration {
  334. return cmd.val
  335. }
  336. func (cmd *DurationCmd) Result() (time.Duration, error) {
  337. return cmd.val, cmd.err
  338. }
  339. func (cmd *DurationCmd) String() string {
  340. return cmdString(cmd, cmd.val)
  341. }
  342. func (cmd *DurationCmd) readReply(rd *proto.Reader) error {
  343. var n int64
  344. n, cmd.err = rd.ReadIntReply()
  345. if cmd.err != nil {
  346. return cmd.err
  347. }
  348. cmd.val = time.Duration(n) * cmd.precision
  349. return nil
  350. }
  351. //------------------------------------------------------------------------------
  352. type TimeCmd struct {
  353. baseCmd
  354. val time.Time
  355. }
  356. var _ Cmder = (*TimeCmd)(nil)
  357. func NewTimeCmd(args ...interface{}) *TimeCmd {
  358. return &TimeCmd{
  359. baseCmd: baseCmd{_args: args},
  360. }
  361. }
  362. func (cmd *TimeCmd) Val() time.Time {
  363. return cmd.val
  364. }
  365. func (cmd *TimeCmd) Result() (time.Time, error) {
  366. return cmd.val, cmd.err
  367. }
  368. func (cmd *TimeCmd) String() string {
  369. return cmdString(cmd, cmd.val)
  370. }
  371. func (cmd *TimeCmd) readReply(rd *proto.Reader) error {
  372. var v interface{}
  373. v, cmd.err = rd.ReadArrayReply(timeParser)
  374. if cmd.err != nil {
  375. return cmd.err
  376. }
  377. cmd.val = v.(time.Time)
  378. return nil
  379. }
  380. // Implements proto.MultiBulkParse
  381. func timeParser(rd *proto.Reader, n int64) (interface{}, error) {
  382. if n != 2 {
  383. return nil, fmt.Errorf("got %d elements, expected 2", n)
  384. }
  385. sec, err := rd.ReadInt()
  386. if err != nil {
  387. return nil, err
  388. }
  389. microsec, err := rd.ReadInt()
  390. if err != nil {
  391. return nil, err
  392. }
  393. return time.Unix(sec, microsec*1000), nil
  394. }
  395. //------------------------------------------------------------------------------
  396. type BoolCmd struct {
  397. baseCmd
  398. val bool
  399. }
  400. var _ Cmder = (*BoolCmd)(nil)
  401. func NewBoolCmd(args ...interface{}) *BoolCmd {
  402. return &BoolCmd{
  403. baseCmd: baseCmd{_args: args},
  404. }
  405. }
  406. func (cmd *BoolCmd) Val() bool {
  407. return cmd.val
  408. }
  409. func (cmd *BoolCmd) Result() (bool, error) {
  410. return cmd.val, cmd.err
  411. }
  412. func (cmd *BoolCmd) String() string {
  413. return cmdString(cmd, cmd.val)
  414. }
  415. func (cmd *BoolCmd) readReply(rd *proto.Reader) error {
  416. var v interface{}
  417. v, cmd.err = rd.ReadReply(nil)
  418. // `SET key value NX` returns nil when key already exists. But
  419. // `SETNX key value` returns bool (0/1). So convert nil to bool.
  420. // TODO: is this okay?
  421. if cmd.err == Nil {
  422. cmd.val = false
  423. cmd.err = nil
  424. return nil
  425. }
  426. if cmd.err != nil {
  427. return cmd.err
  428. }
  429. switch v := v.(type) {
  430. case int64:
  431. cmd.val = v == 1
  432. return nil
  433. case string:
  434. cmd.val = v == "OK"
  435. return nil
  436. default:
  437. cmd.err = fmt.Errorf("got %T, wanted int64 or string", v)
  438. return cmd.err
  439. }
  440. }
  441. //------------------------------------------------------------------------------
  442. type StringCmd struct {
  443. baseCmd
  444. val string
  445. }
  446. var _ Cmder = (*StringCmd)(nil)
  447. func NewStringCmd(args ...interface{}) *StringCmd {
  448. return &StringCmd{
  449. baseCmd: baseCmd{_args: args},
  450. }
  451. }
  452. func (cmd *StringCmd) Val() string {
  453. return cmd.val
  454. }
  455. func (cmd *StringCmd) Result() (string, error) {
  456. return cmd.Val(), cmd.err
  457. }
  458. func (cmd *StringCmd) Bytes() ([]byte, error) {
  459. return []byte(cmd.val), cmd.err
  460. }
  461. func (cmd *StringCmd) Int() (int, error) {
  462. if cmd.err != nil {
  463. return 0, cmd.err
  464. }
  465. return strconv.Atoi(cmd.Val())
  466. }
  467. func (cmd *StringCmd) Int64() (int64, error) {
  468. if cmd.err != nil {
  469. return 0, cmd.err
  470. }
  471. return strconv.ParseInt(cmd.Val(), 10, 64)
  472. }
  473. func (cmd *StringCmd) Uint64() (uint64, error) {
  474. if cmd.err != nil {
  475. return 0, cmd.err
  476. }
  477. return strconv.ParseUint(cmd.Val(), 10, 64)
  478. }
  479. func (cmd *StringCmd) Float64() (float64, error) {
  480. if cmd.err != nil {
  481. return 0, cmd.err
  482. }
  483. return strconv.ParseFloat(cmd.Val(), 64)
  484. }
  485. func (cmd *StringCmd) Scan(val interface{}) error {
  486. if cmd.err != nil {
  487. return cmd.err
  488. }
  489. return proto.Scan([]byte(cmd.val), val)
  490. }
  491. func (cmd *StringCmd) String() string {
  492. return cmdString(cmd, cmd.val)
  493. }
  494. func (cmd *StringCmd) readReply(rd *proto.Reader) error {
  495. cmd.val, cmd.err = rd.ReadString()
  496. return cmd.err
  497. }
  498. //------------------------------------------------------------------------------
  499. type FloatCmd struct {
  500. baseCmd
  501. val float64
  502. }
  503. var _ Cmder = (*FloatCmd)(nil)
  504. func NewFloatCmd(args ...interface{}) *FloatCmd {
  505. return &FloatCmd{
  506. baseCmd: baseCmd{_args: args},
  507. }
  508. }
  509. func (cmd *FloatCmd) Val() float64 {
  510. return cmd.val
  511. }
  512. func (cmd *FloatCmd) Result() (float64, error) {
  513. return cmd.Val(), cmd.Err()
  514. }
  515. func (cmd *FloatCmd) String() string {
  516. return cmdString(cmd, cmd.val)
  517. }
  518. func (cmd *FloatCmd) readReply(rd *proto.Reader) error {
  519. cmd.val, cmd.err = rd.ReadFloatReply()
  520. return cmd.err
  521. }
  522. //------------------------------------------------------------------------------
  523. type StringSliceCmd struct {
  524. baseCmd
  525. val []string
  526. }
  527. var _ Cmder = (*StringSliceCmd)(nil)
  528. func NewStringSliceCmd(args ...interface{}) *StringSliceCmd {
  529. return &StringSliceCmd{
  530. baseCmd: baseCmd{_args: args},
  531. }
  532. }
  533. func (cmd *StringSliceCmd) Val() []string {
  534. return cmd.val
  535. }
  536. func (cmd *StringSliceCmd) Result() ([]string, error) {
  537. return cmd.Val(), cmd.Err()
  538. }
  539. func (cmd *StringSliceCmd) String() string {
  540. return cmdString(cmd, cmd.val)
  541. }
  542. func (cmd *StringSliceCmd) ScanSlice(container interface{}) error {
  543. return proto.ScanSlice(cmd.Val(), container)
  544. }
  545. func (cmd *StringSliceCmd) readReply(rd *proto.Reader) error {
  546. var v interface{}
  547. v, cmd.err = rd.ReadArrayReply(stringSliceParser)
  548. if cmd.err != nil {
  549. return cmd.err
  550. }
  551. cmd.val = v.([]string)
  552. return nil
  553. }
  554. // Implements proto.MultiBulkParse
  555. func stringSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  556. ss := make([]string, 0, n)
  557. for i := int64(0); i < n; i++ {
  558. s, err := rd.ReadString()
  559. if err == Nil {
  560. ss = append(ss, "")
  561. } else if err != nil {
  562. return nil, err
  563. } else {
  564. ss = append(ss, s)
  565. }
  566. }
  567. return ss, nil
  568. }
  569. //------------------------------------------------------------------------------
  570. type BoolSliceCmd struct {
  571. baseCmd
  572. val []bool
  573. }
  574. var _ Cmder = (*BoolSliceCmd)(nil)
  575. func NewBoolSliceCmd(args ...interface{}) *BoolSliceCmd {
  576. return &BoolSliceCmd{
  577. baseCmd: baseCmd{_args: args},
  578. }
  579. }
  580. func (cmd *BoolSliceCmd) Val() []bool {
  581. return cmd.val
  582. }
  583. func (cmd *BoolSliceCmd) Result() ([]bool, error) {
  584. return cmd.val, cmd.err
  585. }
  586. func (cmd *BoolSliceCmd) String() string {
  587. return cmdString(cmd, cmd.val)
  588. }
  589. func (cmd *BoolSliceCmd) readReply(rd *proto.Reader) error {
  590. var v interface{}
  591. v, cmd.err = rd.ReadArrayReply(boolSliceParser)
  592. if cmd.err != nil {
  593. return cmd.err
  594. }
  595. cmd.val = v.([]bool)
  596. return nil
  597. }
  598. // Implements proto.MultiBulkParse
  599. func boolSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  600. bools := make([]bool, 0, n)
  601. for i := int64(0); i < n; i++ {
  602. n, err := rd.ReadIntReply()
  603. if err != nil {
  604. return nil, err
  605. }
  606. bools = append(bools, n == 1)
  607. }
  608. return bools, nil
  609. }
  610. //------------------------------------------------------------------------------
  611. type StringStringMapCmd struct {
  612. baseCmd
  613. val map[string]string
  614. }
  615. var _ Cmder = (*StringStringMapCmd)(nil)
  616. func NewStringStringMapCmd(args ...interface{}) *StringStringMapCmd {
  617. return &StringStringMapCmd{
  618. baseCmd: baseCmd{_args: args},
  619. }
  620. }
  621. func (cmd *StringStringMapCmd) Val() map[string]string {
  622. return cmd.val
  623. }
  624. func (cmd *StringStringMapCmd) Result() (map[string]string, error) {
  625. return cmd.val, cmd.err
  626. }
  627. func (cmd *StringStringMapCmd) String() string {
  628. return cmdString(cmd, cmd.val)
  629. }
  630. func (cmd *StringStringMapCmd) readReply(rd *proto.Reader) error {
  631. var v interface{}
  632. v, cmd.err = rd.ReadArrayReply(stringStringMapParser)
  633. if cmd.err != nil {
  634. return cmd.err
  635. }
  636. cmd.val = v.(map[string]string)
  637. return nil
  638. }
  639. // Implements proto.MultiBulkParse
  640. func stringStringMapParser(rd *proto.Reader, n int64) (interface{}, error) {
  641. m := make(map[string]string, n/2)
  642. for i := int64(0); i < n; i += 2 {
  643. key, err := rd.ReadString()
  644. if err != nil {
  645. return nil, err
  646. }
  647. value, err := rd.ReadString()
  648. if err != nil {
  649. return nil, err
  650. }
  651. m[key] = value
  652. }
  653. return m, nil
  654. }
  655. //------------------------------------------------------------------------------
  656. type StringIntMapCmd struct {
  657. baseCmd
  658. val map[string]int64
  659. }
  660. var _ Cmder = (*StringIntMapCmd)(nil)
  661. func NewStringIntMapCmd(args ...interface{}) *StringIntMapCmd {
  662. return &StringIntMapCmd{
  663. baseCmd: baseCmd{_args: args},
  664. }
  665. }
  666. func (cmd *StringIntMapCmd) Val() map[string]int64 {
  667. return cmd.val
  668. }
  669. func (cmd *StringIntMapCmd) Result() (map[string]int64, error) {
  670. return cmd.val, cmd.err
  671. }
  672. func (cmd *StringIntMapCmd) String() string {
  673. return cmdString(cmd, cmd.val)
  674. }
  675. func (cmd *StringIntMapCmd) readReply(rd *proto.Reader) error {
  676. var v interface{}
  677. v, cmd.err = rd.ReadArrayReply(stringIntMapParser)
  678. if cmd.err != nil {
  679. return cmd.err
  680. }
  681. cmd.val = v.(map[string]int64)
  682. return nil
  683. }
  684. // Implements proto.MultiBulkParse
  685. func stringIntMapParser(rd *proto.Reader, n int64) (interface{}, error) {
  686. m := make(map[string]int64, n/2)
  687. for i := int64(0); i < n; i += 2 {
  688. key, err := rd.ReadString()
  689. if err != nil {
  690. return nil, err
  691. }
  692. n, err := rd.ReadIntReply()
  693. if err != nil {
  694. return nil, err
  695. }
  696. m[key] = n
  697. }
  698. return m, nil
  699. }
  700. //------------------------------------------------------------------------------
  701. type StringStructMapCmd struct {
  702. baseCmd
  703. val map[string]struct{}
  704. }
  705. var _ Cmder = (*StringStructMapCmd)(nil)
  706. func NewStringStructMapCmd(args ...interface{}) *StringStructMapCmd {
  707. return &StringStructMapCmd{
  708. baseCmd: baseCmd{_args: args},
  709. }
  710. }
  711. func (cmd *StringStructMapCmd) Val() map[string]struct{} {
  712. return cmd.val
  713. }
  714. func (cmd *StringStructMapCmd) Result() (map[string]struct{}, error) {
  715. return cmd.val, cmd.err
  716. }
  717. func (cmd *StringStructMapCmd) String() string {
  718. return cmdString(cmd, cmd.val)
  719. }
  720. func (cmd *StringStructMapCmd) readReply(rd *proto.Reader) error {
  721. var v interface{}
  722. v, cmd.err = rd.ReadArrayReply(stringStructMapParser)
  723. if cmd.err != nil {
  724. return cmd.err
  725. }
  726. cmd.val = v.(map[string]struct{})
  727. return nil
  728. }
  729. // Implements proto.MultiBulkParse
  730. func stringStructMapParser(rd *proto.Reader, n int64) (interface{}, error) {
  731. m := make(map[string]struct{}, n)
  732. for i := int64(0); i < n; i++ {
  733. key, err := rd.ReadString()
  734. if err != nil {
  735. return nil, err
  736. }
  737. m[key] = struct{}{}
  738. }
  739. return m, nil
  740. }
  741. //------------------------------------------------------------------------------
  742. type XMessage struct {
  743. ID string
  744. Values map[string]interface{}
  745. }
  746. type XMessageSliceCmd struct {
  747. baseCmd
  748. val []XMessage
  749. }
  750. var _ Cmder = (*XMessageSliceCmd)(nil)
  751. func NewXMessageSliceCmd(args ...interface{}) *XMessageSliceCmd {
  752. return &XMessageSliceCmd{
  753. baseCmd: baseCmd{_args: args},
  754. }
  755. }
  756. func (cmd *XMessageSliceCmd) Val() []XMessage {
  757. return cmd.val
  758. }
  759. func (cmd *XMessageSliceCmd) Result() ([]XMessage, error) {
  760. return cmd.val, cmd.err
  761. }
  762. func (cmd *XMessageSliceCmd) String() string {
  763. return cmdString(cmd, cmd.val)
  764. }
  765. func (cmd *XMessageSliceCmd) readReply(rd *proto.Reader) error {
  766. var v interface{}
  767. v, cmd.err = rd.ReadArrayReply(xMessageSliceParser)
  768. if cmd.err != nil {
  769. return cmd.err
  770. }
  771. cmd.val = v.([]XMessage)
  772. return nil
  773. }
  774. // Implements proto.MultiBulkParse
  775. func xMessageSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  776. msgs := make([]XMessage, 0, n)
  777. for i := int64(0); i < n; i++ {
  778. _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
  779. id, err := rd.ReadString()
  780. if err != nil {
  781. return nil, err
  782. }
  783. v, err := rd.ReadArrayReply(stringInterfaceMapParser)
  784. if err != nil {
  785. return nil, err
  786. }
  787. msgs = append(msgs, XMessage{
  788. ID: id,
  789. Values: v.(map[string]interface{}),
  790. })
  791. return nil, nil
  792. })
  793. if err != nil {
  794. return nil, err
  795. }
  796. }
  797. return msgs, nil
  798. }
  799. // Implements proto.MultiBulkParse
  800. func stringInterfaceMapParser(rd *proto.Reader, n int64) (interface{}, error) {
  801. m := make(map[string]interface{}, n/2)
  802. for i := int64(0); i < n; i += 2 {
  803. key, err := rd.ReadString()
  804. if err != nil {
  805. return nil, err
  806. }
  807. value, err := rd.ReadString()
  808. if err != nil {
  809. return nil, err
  810. }
  811. m[key] = value
  812. }
  813. return m, nil
  814. }
  815. //------------------------------------------------------------------------------
  816. type XStream struct {
  817. Stream string
  818. Messages []XMessage
  819. }
  820. type XStreamSliceCmd struct {
  821. baseCmd
  822. val []XStream
  823. }
  824. var _ Cmder = (*XStreamSliceCmd)(nil)
  825. func NewXStreamSliceCmd(args ...interface{}) *XStreamSliceCmd {
  826. return &XStreamSliceCmd{
  827. baseCmd: baseCmd{_args: args},
  828. }
  829. }
  830. func (cmd *XStreamSliceCmd) Val() []XStream {
  831. return cmd.val
  832. }
  833. func (cmd *XStreamSliceCmd) Result() ([]XStream, error) {
  834. return cmd.val, cmd.err
  835. }
  836. func (cmd *XStreamSliceCmd) String() string {
  837. return cmdString(cmd, cmd.val)
  838. }
  839. func (cmd *XStreamSliceCmd) readReply(rd *proto.Reader) error {
  840. var v interface{}
  841. v, cmd.err = rd.ReadArrayReply(xStreamSliceParser)
  842. if cmd.err != nil {
  843. return cmd.err
  844. }
  845. cmd.val = v.([]XStream)
  846. return nil
  847. }
  848. // Implements proto.MultiBulkParse
  849. func xStreamSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  850. ret := make([]XStream, 0, n)
  851. for i := int64(0); i < n; i++ {
  852. _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
  853. if n != 2 {
  854. return nil, fmt.Errorf("got %d, wanted 2", n)
  855. }
  856. stream, err := rd.ReadString()
  857. if err != nil {
  858. return nil, err
  859. }
  860. v, err := rd.ReadArrayReply(xMessageSliceParser)
  861. if err != nil {
  862. return nil, err
  863. }
  864. ret = append(ret, XStream{
  865. Stream: stream,
  866. Messages: v.([]XMessage),
  867. })
  868. return nil, nil
  869. })
  870. if err != nil {
  871. return nil, err
  872. }
  873. }
  874. return ret, nil
  875. }
  876. //------------------------------------------------------------------------------
  877. type XPending struct {
  878. Count int64
  879. Lower string
  880. Higher string
  881. Consumers map[string]int64
  882. }
  883. type XPendingCmd struct {
  884. baseCmd
  885. val *XPending
  886. }
  887. var _ Cmder = (*XPendingCmd)(nil)
  888. func NewXPendingCmd(args ...interface{}) *XPendingCmd {
  889. return &XPendingCmd{
  890. baseCmd: baseCmd{_args: args},
  891. }
  892. }
  893. func (cmd *XPendingCmd) Val() *XPending {
  894. return cmd.val
  895. }
  896. func (cmd *XPendingCmd) Result() (*XPending, error) {
  897. return cmd.val, cmd.err
  898. }
  899. func (cmd *XPendingCmd) String() string {
  900. return cmdString(cmd, cmd.val)
  901. }
  902. func (cmd *XPendingCmd) readReply(rd *proto.Reader) error {
  903. var info interface{}
  904. info, cmd.err = rd.ReadArrayReply(xPendingParser)
  905. if cmd.err != nil {
  906. return cmd.err
  907. }
  908. cmd.val = info.(*XPending)
  909. return nil
  910. }
  911. func xPendingParser(rd *proto.Reader, n int64) (interface{}, error) {
  912. if n != 4 {
  913. return nil, fmt.Errorf("got %d, wanted 4", n)
  914. }
  915. count, err := rd.ReadIntReply()
  916. if err != nil {
  917. return nil, err
  918. }
  919. lower, err := rd.ReadString()
  920. if err != nil && err != Nil {
  921. return nil, err
  922. }
  923. higher, err := rd.ReadString()
  924. if err != nil && err != Nil {
  925. return nil, err
  926. }
  927. pending := &XPending{
  928. Count: count,
  929. Lower: lower,
  930. Higher: higher,
  931. }
  932. _, err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
  933. for i := int64(0); i < n; i++ {
  934. _, err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
  935. if n != 2 {
  936. return nil, fmt.Errorf("got %d, wanted 2", n)
  937. }
  938. consumerName, err := rd.ReadString()
  939. if err != nil {
  940. return nil, err
  941. }
  942. consumerPending, err := rd.ReadInt()
  943. if err != nil {
  944. return nil, err
  945. }
  946. if pending.Consumers == nil {
  947. pending.Consumers = make(map[string]int64)
  948. }
  949. pending.Consumers[consumerName] = consumerPending
  950. return nil, nil
  951. })
  952. if err != nil {
  953. return nil, err
  954. }
  955. }
  956. return nil, nil
  957. })
  958. if err != nil && err != Nil {
  959. return nil, err
  960. }
  961. return pending, nil
  962. }
  963. //------------------------------------------------------------------------------
  964. type XPendingExt struct {
  965. Id string
  966. Consumer string
  967. Idle time.Duration
  968. RetryCount int64
  969. }
  970. type XPendingExtCmd struct {
  971. baseCmd
  972. val []XPendingExt
  973. }
  974. var _ Cmder = (*XPendingExtCmd)(nil)
  975. func NewXPendingExtCmd(args ...interface{}) *XPendingExtCmd {
  976. return &XPendingExtCmd{
  977. baseCmd: baseCmd{_args: args},
  978. }
  979. }
  980. func (cmd *XPendingExtCmd) Val() []XPendingExt {
  981. return cmd.val
  982. }
  983. func (cmd *XPendingExtCmd) Result() ([]XPendingExt, error) {
  984. return cmd.val, cmd.err
  985. }
  986. func (cmd *XPendingExtCmd) String() string {
  987. return cmdString(cmd, cmd.val)
  988. }
  989. func (cmd *XPendingExtCmd) readReply(rd *proto.Reader) error {
  990. var info interface{}
  991. info, cmd.err = rd.ReadArrayReply(xPendingExtSliceParser)
  992. if cmd.err != nil {
  993. return cmd.err
  994. }
  995. cmd.val = info.([]XPendingExt)
  996. return nil
  997. }
  998. func xPendingExtSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  999. ret := make([]XPendingExt, 0, n)
  1000. for i := int64(0); i < n; i++ {
  1001. _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
  1002. if n != 4 {
  1003. return nil, fmt.Errorf("got %d, wanted 4", n)
  1004. }
  1005. id, err := rd.ReadString()
  1006. if err != nil {
  1007. return nil, err
  1008. }
  1009. consumer, err := rd.ReadString()
  1010. if err != nil && err != Nil {
  1011. return nil, err
  1012. }
  1013. idle, err := rd.ReadIntReply()
  1014. if err != nil && err != Nil {
  1015. return nil, err
  1016. }
  1017. retryCount, err := rd.ReadIntReply()
  1018. if err != nil && err != Nil {
  1019. return nil, err
  1020. }
  1021. ret = append(ret, XPendingExt{
  1022. Id: id,
  1023. Consumer: consumer,
  1024. Idle: time.Duration(idle) * time.Millisecond,
  1025. RetryCount: retryCount,
  1026. })
  1027. return nil, nil
  1028. })
  1029. if err != nil {
  1030. return nil, err
  1031. }
  1032. }
  1033. return ret, nil
  1034. }
  1035. //------------------------------------------------------------------------------
  1036. //------------------------------------------------------------------------------
  1037. type ZSliceCmd struct {
  1038. baseCmd
  1039. val []Z
  1040. }
  1041. var _ Cmder = (*ZSliceCmd)(nil)
  1042. func NewZSliceCmd(args ...interface{}) *ZSliceCmd {
  1043. return &ZSliceCmd{
  1044. baseCmd: baseCmd{_args: args},
  1045. }
  1046. }
  1047. func (cmd *ZSliceCmd) Val() []Z {
  1048. return cmd.val
  1049. }
  1050. func (cmd *ZSliceCmd) Result() ([]Z, error) {
  1051. return cmd.val, cmd.err
  1052. }
  1053. func (cmd *ZSliceCmd) String() string {
  1054. return cmdString(cmd, cmd.val)
  1055. }
  1056. func (cmd *ZSliceCmd) readReply(rd *proto.Reader) error {
  1057. var v interface{}
  1058. v, cmd.err = rd.ReadArrayReply(zSliceParser)
  1059. if cmd.err != nil {
  1060. return cmd.err
  1061. }
  1062. cmd.val = v.([]Z)
  1063. return nil
  1064. }
  1065. // Implements proto.MultiBulkParse
  1066. func zSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  1067. zz := make([]Z, n/2)
  1068. for i := int64(0); i < n; i += 2 {
  1069. var err error
  1070. z := &zz[i/2]
  1071. z.Member, err = rd.ReadString()
  1072. if err != nil {
  1073. return nil, err
  1074. }
  1075. z.Score, err = rd.ReadFloatReply()
  1076. if err != nil {
  1077. return nil, err
  1078. }
  1079. }
  1080. return zz, nil
  1081. }
  1082. //------------------------------------------------------------------------------
  1083. type ScanCmd struct {
  1084. baseCmd
  1085. page []string
  1086. cursor uint64
  1087. process func(cmd Cmder) error
  1088. }
  1089. var _ Cmder = (*ScanCmd)(nil)
  1090. func NewScanCmd(process func(cmd Cmder) error, args ...interface{}) *ScanCmd {
  1091. return &ScanCmd{
  1092. baseCmd: baseCmd{_args: args},
  1093. process: process,
  1094. }
  1095. }
  1096. func (cmd *ScanCmd) Val() (keys []string, cursor uint64) {
  1097. return cmd.page, cmd.cursor
  1098. }
  1099. func (cmd *ScanCmd) Result() (keys []string, cursor uint64, err error) {
  1100. return cmd.page, cmd.cursor, cmd.err
  1101. }
  1102. func (cmd *ScanCmd) String() string {
  1103. return cmdString(cmd, cmd.page)
  1104. }
  1105. func (cmd *ScanCmd) readReply(rd *proto.Reader) error {
  1106. cmd.page, cmd.cursor, cmd.err = rd.ReadScanReply()
  1107. return cmd.err
  1108. }
  1109. // Iterator creates a new ScanIterator.
  1110. func (cmd *ScanCmd) Iterator() *ScanIterator {
  1111. return &ScanIterator{
  1112. cmd: cmd,
  1113. }
  1114. }
  1115. //------------------------------------------------------------------------------
  1116. type ClusterNode struct {
  1117. Id string
  1118. Addr string
  1119. }
  1120. type ClusterSlot struct {
  1121. Start int
  1122. End int
  1123. Nodes []ClusterNode
  1124. }
  1125. type ClusterSlotsCmd struct {
  1126. baseCmd
  1127. val []ClusterSlot
  1128. }
  1129. var _ Cmder = (*ClusterSlotsCmd)(nil)
  1130. func NewClusterSlotsCmd(args ...interface{}) *ClusterSlotsCmd {
  1131. return &ClusterSlotsCmd{
  1132. baseCmd: baseCmd{_args: args},
  1133. }
  1134. }
  1135. func (cmd *ClusterSlotsCmd) Val() []ClusterSlot {
  1136. return cmd.val
  1137. }
  1138. func (cmd *ClusterSlotsCmd) Result() ([]ClusterSlot, error) {
  1139. return cmd.Val(), cmd.Err()
  1140. }
  1141. func (cmd *ClusterSlotsCmd) String() string {
  1142. return cmdString(cmd, cmd.val)
  1143. }
  1144. func (cmd *ClusterSlotsCmd) readReply(rd *proto.Reader) error {
  1145. var v interface{}
  1146. v, cmd.err = rd.ReadArrayReply(clusterSlotsParser)
  1147. if cmd.err != nil {
  1148. return cmd.err
  1149. }
  1150. cmd.val = v.([]ClusterSlot)
  1151. return nil
  1152. }
  1153. // Implements proto.MultiBulkParse
  1154. func clusterSlotsParser(rd *proto.Reader, n int64) (interface{}, error) {
  1155. slots := make([]ClusterSlot, n)
  1156. for i := 0; i < len(slots); i++ {
  1157. n, err := rd.ReadArrayLen()
  1158. if err != nil {
  1159. return nil, err
  1160. }
  1161. if n < 2 {
  1162. err := fmt.Errorf("redis: got %d elements in cluster info, expected at least 2", n)
  1163. return nil, err
  1164. }
  1165. start, err := rd.ReadIntReply()
  1166. if err != nil {
  1167. return nil, err
  1168. }
  1169. end, err := rd.ReadIntReply()
  1170. if err != nil {
  1171. return nil, err
  1172. }
  1173. nodes := make([]ClusterNode, n-2)
  1174. for j := 0; j < len(nodes); j++ {
  1175. n, err := rd.ReadArrayLen()
  1176. if err != nil {
  1177. return nil, err
  1178. }
  1179. if n != 2 && n != 3 {
  1180. err := fmt.Errorf("got %d elements in cluster info address, expected 2 or 3", n)
  1181. return nil, err
  1182. }
  1183. ip, err := rd.ReadString()
  1184. if err != nil {
  1185. return nil, err
  1186. }
  1187. port, err := rd.ReadString()
  1188. if err != nil {
  1189. return nil, err
  1190. }
  1191. nodes[j].Addr = net.JoinHostPort(ip, port)
  1192. if n == 3 {
  1193. id, err := rd.ReadString()
  1194. if err != nil {
  1195. return nil, err
  1196. }
  1197. nodes[j].Id = id
  1198. }
  1199. }
  1200. slots[i] = ClusterSlot{
  1201. Start: int(start),
  1202. End: int(end),
  1203. Nodes: nodes,
  1204. }
  1205. }
  1206. return slots, nil
  1207. }
  1208. //------------------------------------------------------------------------------
  1209. // GeoLocation is used with GeoAdd to add geospatial location.
  1210. type GeoLocation struct {
  1211. Name string
  1212. Longitude, Latitude, Dist float64
  1213. GeoHash int64
  1214. }
  1215. // GeoRadiusQuery is used with GeoRadius to query geospatial index.
  1216. type GeoRadiusQuery struct {
  1217. Radius float64
  1218. // Can be m, km, ft, or mi. Default is km.
  1219. Unit string
  1220. WithCoord bool
  1221. WithDist bool
  1222. WithGeoHash bool
  1223. Count int
  1224. // Can be ASC or DESC. Default is no sort order.
  1225. Sort string
  1226. Store string
  1227. StoreDist string
  1228. }
  1229. type GeoLocationCmd struct {
  1230. baseCmd
  1231. q *GeoRadiusQuery
  1232. locations []GeoLocation
  1233. }
  1234. var _ Cmder = (*GeoLocationCmd)(nil)
  1235. func NewGeoLocationCmd(q *GeoRadiusQuery, args ...interface{}) *GeoLocationCmd {
  1236. args = append(args, q.Radius)
  1237. if q.Unit != "" {
  1238. args = append(args, q.Unit)
  1239. } else {
  1240. args = append(args, "km")
  1241. }
  1242. if q.WithCoord {
  1243. args = append(args, "withcoord")
  1244. }
  1245. if q.WithDist {
  1246. args = append(args, "withdist")
  1247. }
  1248. if q.WithGeoHash {
  1249. args = append(args, "withhash")
  1250. }
  1251. if q.Count > 0 {
  1252. args = append(args, "count", q.Count)
  1253. }
  1254. if q.Sort != "" {
  1255. args = append(args, q.Sort)
  1256. }
  1257. if q.Store != "" {
  1258. args = append(args, "store")
  1259. args = append(args, q.Store)
  1260. }
  1261. if q.StoreDist != "" {
  1262. args = append(args, "storedist")
  1263. args = append(args, q.StoreDist)
  1264. }
  1265. return &GeoLocationCmd{
  1266. baseCmd: baseCmd{_args: args},
  1267. q: q,
  1268. }
  1269. }
  1270. func (cmd *GeoLocationCmd) Val() []GeoLocation {
  1271. return cmd.locations
  1272. }
  1273. func (cmd *GeoLocationCmd) Result() ([]GeoLocation, error) {
  1274. return cmd.locations, cmd.err
  1275. }
  1276. func (cmd *GeoLocationCmd) String() string {
  1277. return cmdString(cmd, cmd.locations)
  1278. }
  1279. func (cmd *GeoLocationCmd) readReply(rd *proto.Reader) error {
  1280. var v interface{}
  1281. v, cmd.err = rd.ReadArrayReply(newGeoLocationSliceParser(cmd.q))
  1282. if cmd.err != nil {
  1283. return cmd.err
  1284. }
  1285. cmd.locations = v.([]GeoLocation)
  1286. return nil
  1287. }
  1288. func newGeoLocationParser(q *GeoRadiusQuery) proto.MultiBulkParse {
  1289. return func(rd *proto.Reader, n int64) (interface{}, error) {
  1290. var loc GeoLocation
  1291. var err error
  1292. loc.Name, err = rd.ReadString()
  1293. if err != nil {
  1294. return nil, err
  1295. }
  1296. if q.WithDist {
  1297. loc.Dist, err = rd.ReadFloatReply()
  1298. if err != nil {
  1299. return nil, err
  1300. }
  1301. }
  1302. if q.WithGeoHash {
  1303. loc.GeoHash, err = rd.ReadIntReply()
  1304. if err != nil {
  1305. return nil, err
  1306. }
  1307. }
  1308. if q.WithCoord {
  1309. n, err := rd.ReadArrayLen()
  1310. if err != nil {
  1311. return nil, err
  1312. }
  1313. if n != 2 {
  1314. return nil, fmt.Errorf("got %d coordinates, expected 2", n)
  1315. }
  1316. loc.Longitude, err = rd.ReadFloatReply()
  1317. if err != nil {
  1318. return nil, err
  1319. }
  1320. loc.Latitude, err = rd.ReadFloatReply()
  1321. if err != nil {
  1322. return nil, err
  1323. }
  1324. }
  1325. return &loc, nil
  1326. }
  1327. }
  1328. func newGeoLocationSliceParser(q *GeoRadiusQuery) proto.MultiBulkParse {
  1329. return func(rd *proto.Reader, n int64) (interface{}, error) {
  1330. locs := make([]GeoLocation, 0, n)
  1331. for i := int64(0); i < n; i++ {
  1332. v, err := rd.ReadReply(newGeoLocationParser(q))
  1333. if err != nil {
  1334. return nil, err
  1335. }
  1336. switch vv := v.(type) {
  1337. case string:
  1338. locs = append(locs, GeoLocation{
  1339. Name: vv,
  1340. })
  1341. case *GeoLocation:
  1342. locs = append(locs, *vv)
  1343. default:
  1344. return nil, fmt.Errorf("got %T, expected string or *GeoLocation", v)
  1345. }
  1346. }
  1347. return locs, nil
  1348. }
  1349. }
  1350. //------------------------------------------------------------------------------
  1351. type GeoPos struct {
  1352. Longitude, Latitude float64
  1353. }
  1354. type GeoPosCmd struct {
  1355. baseCmd
  1356. positions []*GeoPos
  1357. }
  1358. var _ Cmder = (*GeoPosCmd)(nil)
  1359. func NewGeoPosCmd(args ...interface{}) *GeoPosCmd {
  1360. return &GeoPosCmd{
  1361. baseCmd: baseCmd{_args: args},
  1362. }
  1363. }
  1364. func (cmd *GeoPosCmd) Val() []*GeoPos {
  1365. return cmd.positions
  1366. }
  1367. func (cmd *GeoPosCmd) Result() ([]*GeoPos, error) {
  1368. return cmd.Val(), cmd.Err()
  1369. }
  1370. func (cmd *GeoPosCmd) String() string {
  1371. return cmdString(cmd, cmd.positions)
  1372. }
  1373. func (cmd *GeoPosCmd) readReply(rd *proto.Reader) error {
  1374. var v interface{}
  1375. v, cmd.err = rd.ReadArrayReply(geoPosSliceParser)
  1376. if cmd.err != nil {
  1377. return cmd.err
  1378. }
  1379. cmd.positions = v.([]*GeoPos)
  1380. return nil
  1381. }
  1382. func geoPosSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  1383. positions := make([]*GeoPos, 0, n)
  1384. for i := int64(0); i < n; i++ {
  1385. v, err := rd.ReadReply(geoPosParser)
  1386. if err != nil {
  1387. if err == Nil {
  1388. positions = append(positions, nil)
  1389. continue
  1390. }
  1391. return nil, err
  1392. }
  1393. switch v := v.(type) {
  1394. case *GeoPos:
  1395. positions = append(positions, v)
  1396. default:
  1397. return nil, fmt.Errorf("got %T, expected *GeoPos", v)
  1398. }
  1399. }
  1400. return positions, nil
  1401. }
  1402. func geoPosParser(rd *proto.Reader, n int64) (interface{}, error) {
  1403. var pos GeoPos
  1404. var err error
  1405. pos.Longitude, err = rd.ReadFloatReply()
  1406. if err != nil {
  1407. return nil, err
  1408. }
  1409. pos.Latitude, err = rd.ReadFloatReply()
  1410. if err != nil {
  1411. return nil, err
  1412. }
  1413. return &pos, nil
  1414. }
  1415. //------------------------------------------------------------------------------
  1416. type CommandInfo struct {
  1417. Name string
  1418. Arity int8
  1419. Flags []string
  1420. FirstKeyPos int8
  1421. LastKeyPos int8
  1422. StepCount int8
  1423. ReadOnly bool
  1424. }
  1425. type CommandsInfoCmd struct {
  1426. baseCmd
  1427. val map[string]*CommandInfo
  1428. }
  1429. var _ Cmder = (*CommandsInfoCmd)(nil)
  1430. func NewCommandsInfoCmd(args ...interface{}) *CommandsInfoCmd {
  1431. return &CommandsInfoCmd{
  1432. baseCmd: baseCmd{_args: args},
  1433. }
  1434. }
  1435. func (cmd *CommandsInfoCmd) Val() map[string]*CommandInfo {
  1436. return cmd.val
  1437. }
  1438. func (cmd *CommandsInfoCmd) Result() (map[string]*CommandInfo, error) {
  1439. return cmd.Val(), cmd.Err()
  1440. }
  1441. func (cmd *CommandsInfoCmd) String() string {
  1442. return cmdString(cmd, cmd.val)
  1443. }
  1444. func (cmd *CommandsInfoCmd) readReply(rd *proto.Reader) error {
  1445. var v interface{}
  1446. v, cmd.err = rd.ReadArrayReply(commandInfoSliceParser)
  1447. if cmd.err != nil {
  1448. return cmd.err
  1449. }
  1450. cmd.val = v.(map[string]*CommandInfo)
  1451. return nil
  1452. }
  1453. // Implements proto.MultiBulkParse
  1454. func commandInfoSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
  1455. m := make(map[string]*CommandInfo, n)
  1456. for i := int64(0); i < n; i++ {
  1457. v, err := rd.ReadReply(commandInfoParser)
  1458. if err != nil {
  1459. return nil, err
  1460. }
  1461. vv := v.(*CommandInfo)
  1462. m[vv.Name] = vv
  1463. }
  1464. return m, nil
  1465. }
  1466. func commandInfoParser(rd *proto.Reader, n int64) (interface{}, error) {
  1467. var cmd CommandInfo
  1468. var err error
  1469. if n != 6 {
  1470. return nil, fmt.Errorf("redis: got %d elements in COMMAND reply, wanted 6", n)
  1471. }
  1472. cmd.Name, err = rd.ReadString()
  1473. if err != nil {
  1474. return nil, err
  1475. }
  1476. arity, err := rd.ReadIntReply()
  1477. if err != nil {
  1478. return nil, err
  1479. }
  1480. cmd.Arity = int8(arity)
  1481. flags, err := rd.ReadReply(stringSliceParser)
  1482. if err != nil {
  1483. return nil, err
  1484. }
  1485. cmd.Flags = flags.([]string)
  1486. firstKeyPos, err := rd.ReadIntReply()
  1487. if err != nil {
  1488. return nil, err
  1489. }
  1490. cmd.FirstKeyPos = int8(firstKeyPos)
  1491. lastKeyPos, err := rd.ReadIntReply()
  1492. if err != nil {
  1493. return nil, err
  1494. }
  1495. cmd.LastKeyPos = int8(lastKeyPos)
  1496. stepCount, err := rd.ReadIntReply()
  1497. if err != nil {
  1498. return nil, err
  1499. }
  1500. cmd.StepCount = int8(stepCount)
  1501. for _, flag := range cmd.Flags {
  1502. if flag == "readonly" {
  1503. cmd.ReadOnly = true
  1504. break
  1505. }
  1506. }
  1507. return &cmd, nil
  1508. }
  1509. //------------------------------------------------------------------------------
  1510. type cmdsInfoCache struct {
  1511. fn func() (map[string]*CommandInfo, error)
  1512. once internal.Once
  1513. cmds map[string]*CommandInfo
  1514. }
  1515. func newCmdsInfoCache(fn func() (map[string]*CommandInfo, error)) *cmdsInfoCache {
  1516. return &cmdsInfoCache{
  1517. fn: fn,
  1518. }
  1519. }
  1520. func (c *cmdsInfoCache) Get() (map[string]*CommandInfo, error) {
  1521. err := c.once.Do(func() error {
  1522. cmds, err := c.fn()
  1523. if err != nil {
  1524. return err
  1525. }
  1526. c.cmds = cmds
  1527. return nil
  1528. })
  1529. return c.cmds, err
  1530. }