本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2584 line
63KB

  1. package redis
  2. import (
  3. "errors"
  4. "io"
  5. "time"
  6. "github.com/go-redis/redis/internal"
  7. )
  8. func usePrecise(dur time.Duration) bool {
  9. return dur < time.Second || dur%time.Second != 0
  10. }
  11. func formatMs(dur time.Duration) int64 {
  12. if dur > 0 && dur < time.Millisecond {
  13. internal.Logf(
  14. "specified duration is %s, but minimal supported value is %s",
  15. dur, time.Millisecond,
  16. )
  17. }
  18. return int64(dur / time.Millisecond)
  19. }
  20. func formatSec(dur time.Duration) int64 {
  21. if dur > 0 && dur < time.Second {
  22. internal.Logf(
  23. "specified duration is %s, but minimal supported value is %s",
  24. dur, time.Second,
  25. )
  26. }
  27. return int64(dur / time.Second)
  28. }
  29. func appendArgs(dst, src []interface{}) []interface{} {
  30. if len(src) == 1 {
  31. if ss, ok := src[0].([]string); ok {
  32. for _, s := range ss {
  33. dst = append(dst, s)
  34. }
  35. return dst
  36. }
  37. }
  38. for _, v := range src {
  39. dst = append(dst, v)
  40. }
  41. return dst
  42. }
  43. type Cmdable interface {
  44. Pipeline() Pipeliner
  45. Pipelined(fn func(Pipeliner) error) ([]Cmder, error)
  46. TxPipelined(fn func(Pipeliner) error) ([]Cmder, error)
  47. TxPipeline() Pipeliner
  48. Command() *CommandsInfoCmd
  49. ClientGetName() *StringCmd
  50. Echo(message interface{}) *StringCmd
  51. Ping() *StatusCmd
  52. Quit() *StatusCmd
  53. Del(keys ...string) *IntCmd
  54. Unlink(keys ...string) *IntCmd
  55. Dump(key string) *StringCmd
  56. Exists(keys ...string) *IntCmd
  57. Expire(key string, expiration time.Duration) *BoolCmd
  58. ExpireAt(key string, tm time.Time) *BoolCmd
  59. Keys(pattern string) *StringSliceCmd
  60. Migrate(host, port, key string, db int64, timeout time.Duration) *StatusCmd
  61. Move(key string, db int64) *BoolCmd
  62. ObjectRefCount(key string) *IntCmd
  63. ObjectEncoding(key string) *StringCmd
  64. ObjectIdleTime(key string) *DurationCmd
  65. Persist(key string) *BoolCmd
  66. PExpire(key string, expiration time.Duration) *BoolCmd
  67. PExpireAt(key string, tm time.Time) *BoolCmd
  68. PTTL(key string) *DurationCmd
  69. RandomKey() *StringCmd
  70. Rename(key, newkey string) *StatusCmd
  71. RenameNX(key, newkey string) *BoolCmd
  72. Restore(key string, ttl time.Duration, value string) *StatusCmd
  73. RestoreReplace(key string, ttl time.Duration, value string) *StatusCmd
  74. Sort(key string, sort *Sort) *StringSliceCmd
  75. SortStore(key, store string, sort *Sort) *IntCmd
  76. SortInterfaces(key string, sort *Sort) *SliceCmd
  77. Touch(keys ...string) *IntCmd
  78. TTL(key string) *DurationCmd
  79. Type(key string) *StatusCmd
  80. Scan(cursor uint64, match string, count int64) *ScanCmd
  81. SScan(key string, cursor uint64, match string, count int64) *ScanCmd
  82. HScan(key string, cursor uint64, match string, count int64) *ScanCmd
  83. ZScan(key string, cursor uint64, match string, count int64) *ScanCmd
  84. Append(key, value string) *IntCmd
  85. BitCount(key string, bitCount *BitCount) *IntCmd
  86. BitOpAnd(destKey string, keys ...string) *IntCmd
  87. BitOpOr(destKey string, keys ...string) *IntCmd
  88. BitOpXor(destKey string, keys ...string) *IntCmd
  89. BitOpNot(destKey string, key string) *IntCmd
  90. BitPos(key string, bit int64, pos ...int64) *IntCmd
  91. Decr(key string) *IntCmd
  92. DecrBy(key string, decrement int64) *IntCmd
  93. Get(key string) *StringCmd
  94. GetBit(key string, offset int64) *IntCmd
  95. GetRange(key string, start, end int64) *StringCmd
  96. GetSet(key string, value interface{}) *StringCmd
  97. Incr(key string) *IntCmd
  98. IncrBy(key string, value int64) *IntCmd
  99. IncrByFloat(key string, value float64) *FloatCmd
  100. MGet(keys ...string) *SliceCmd
  101. MSet(pairs ...interface{}) *StatusCmd
  102. MSetNX(pairs ...interface{}) *BoolCmd
  103. Set(key string, value interface{}, expiration time.Duration) *StatusCmd
  104. SetBit(key string, offset int64, value int) *IntCmd
  105. SetNX(key string, value interface{}, expiration time.Duration) *BoolCmd
  106. SetXX(key string, value interface{}, expiration time.Duration) *BoolCmd
  107. SetRange(key string, offset int64, value string) *IntCmd
  108. StrLen(key string) *IntCmd
  109. HDel(key string, fields ...string) *IntCmd
  110. HExists(key, field string) *BoolCmd
  111. HGet(key, field string) *StringCmd
  112. HGetAll(key string) *StringStringMapCmd
  113. HIncrBy(key, field string, incr int64) *IntCmd
  114. HIncrByFloat(key, field string, incr float64) *FloatCmd
  115. HKeys(key string) *StringSliceCmd
  116. HLen(key string) *IntCmd
  117. HMGet(key string, fields ...string) *SliceCmd
  118. HMSet(key string, fields map[string]interface{}) *StatusCmd
  119. HSet(key, field string, value interface{}) *BoolCmd
  120. HSetNX(key, field string, value interface{}) *BoolCmd
  121. HVals(key string) *StringSliceCmd
  122. BLPop(timeout time.Duration, keys ...string) *StringSliceCmd
  123. BRPop(timeout time.Duration, keys ...string) *StringSliceCmd
  124. BRPopLPush(source, destination string, timeout time.Duration) *StringCmd
  125. LIndex(key string, index int64) *StringCmd
  126. LInsert(key, op string, pivot, value interface{}) *IntCmd
  127. LInsertBefore(key string, pivot, value interface{}) *IntCmd
  128. LInsertAfter(key string, pivot, value interface{}) *IntCmd
  129. LLen(key string) *IntCmd
  130. LPop(key string) *StringCmd
  131. LPush(key string, values ...interface{}) *IntCmd
  132. LPushX(key string, value interface{}) *IntCmd
  133. LRange(key string, start, stop int64) *StringSliceCmd
  134. LRem(key string, count int64, value interface{}) *IntCmd
  135. LSet(key string, index int64, value interface{}) *StatusCmd
  136. LTrim(key string, start, stop int64) *StatusCmd
  137. RPop(key string) *StringCmd
  138. RPopLPush(source, destination string) *StringCmd
  139. RPush(key string, values ...interface{}) *IntCmd
  140. RPushX(key string, value interface{}) *IntCmd
  141. SAdd(key string, members ...interface{}) *IntCmd
  142. SCard(key string) *IntCmd
  143. SDiff(keys ...string) *StringSliceCmd
  144. SDiffStore(destination string, keys ...string) *IntCmd
  145. SInter(keys ...string) *StringSliceCmd
  146. SInterStore(destination string, keys ...string) *IntCmd
  147. SIsMember(key string, member interface{}) *BoolCmd
  148. SMembers(key string) *StringSliceCmd
  149. SMembersMap(key string) *StringStructMapCmd
  150. SMove(source, destination string, member interface{}) *BoolCmd
  151. SPop(key string) *StringCmd
  152. SPopN(key string, count int64) *StringSliceCmd
  153. SRandMember(key string) *StringCmd
  154. SRandMemberN(key string, count int64) *StringSliceCmd
  155. SRem(key string, members ...interface{}) *IntCmd
  156. SUnion(keys ...string) *StringSliceCmd
  157. SUnionStore(destination string, keys ...string) *IntCmd
  158. XAdd(a *XAddArgs) *StringCmd
  159. XDel(stream string, ids ...string) *IntCmd
  160. XLen(stream string) *IntCmd
  161. XRange(stream, start, stop string) *XMessageSliceCmd
  162. XRangeN(stream, start, stop string, count int64) *XMessageSliceCmd
  163. XRevRange(stream string, start, stop string) *XMessageSliceCmd
  164. XRevRangeN(stream string, start, stop string, count int64) *XMessageSliceCmd
  165. XRead(a *XReadArgs) *XStreamSliceCmd
  166. XReadStreams(streams ...string) *XStreamSliceCmd
  167. XGroupCreate(stream, group, start string) *StatusCmd
  168. XGroupCreateMkStream(stream, group, start string) *StatusCmd
  169. XGroupSetID(stream, group, start string) *StatusCmd
  170. XGroupDestroy(stream, group string) *IntCmd
  171. XGroupDelConsumer(stream, group, consumer string) *IntCmd
  172. XReadGroup(a *XReadGroupArgs) *XStreamSliceCmd
  173. XAck(stream, group string, ids ...string) *IntCmd
  174. XPending(stream, group string) *XPendingCmd
  175. XPendingExt(a *XPendingExtArgs) *XPendingExtCmd
  176. XClaim(a *XClaimArgs) *XMessageSliceCmd
  177. XClaimJustID(a *XClaimArgs) *StringSliceCmd
  178. XTrim(key string, maxLen int64) *IntCmd
  179. XTrimApprox(key string, maxLen int64) *IntCmd
  180. BZPopMax(timeout time.Duration, keys ...string) *ZWithKeyCmd
  181. BZPopMin(timeout time.Duration, keys ...string) *ZWithKeyCmd
  182. ZAdd(key string, members ...Z) *IntCmd
  183. ZAddNX(key string, members ...Z) *IntCmd
  184. ZAddXX(key string, members ...Z) *IntCmd
  185. ZAddCh(key string, members ...Z) *IntCmd
  186. ZAddNXCh(key string, members ...Z) *IntCmd
  187. ZAddXXCh(key string, members ...Z) *IntCmd
  188. ZIncr(key string, member Z) *FloatCmd
  189. ZIncrNX(key string, member Z) *FloatCmd
  190. ZIncrXX(key string, member Z) *FloatCmd
  191. ZCard(key string) *IntCmd
  192. ZCount(key, min, max string) *IntCmd
  193. ZLexCount(key, min, max string) *IntCmd
  194. ZIncrBy(key string, increment float64, member string) *FloatCmd
  195. ZInterStore(destination string, store ZStore, keys ...string) *IntCmd
  196. ZPopMax(key string, count ...int64) *ZSliceCmd
  197. ZPopMin(key string, count ...int64) *ZSliceCmd
  198. ZRange(key string, start, stop int64) *StringSliceCmd
  199. ZRangeWithScores(key string, start, stop int64) *ZSliceCmd
  200. ZRangeByScore(key string, opt ZRangeBy) *StringSliceCmd
  201. ZRangeByLex(key string, opt ZRangeBy) *StringSliceCmd
  202. ZRangeByScoreWithScores(key string, opt ZRangeBy) *ZSliceCmd
  203. ZRank(key, member string) *IntCmd
  204. ZRem(key string, members ...interface{}) *IntCmd
  205. ZRemRangeByRank(key string, start, stop int64) *IntCmd
  206. ZRemRangeByScore(key, min, max string) *IntCmd
  207. ZRemRangeByLex(key, min, max string) *IntCmd
  208. ZRevRange(key string, start, stop int64) *StringSliceCmd
  209. ZRevRangeWithScores(key string, start, stop int64) *ZSliceCmd
  210. ZRevRangeByScore(key string, opt ZRangeBy) *StringSliceCmd
  211. ZRevRangeByLex(key string, opt ZRangeBy) *StringSliceCmd
  212. ZRevRangeByScoreWithScores(key string, opt ZRangeBy) *ZSliceCmd
  213. ZRevRank(key, member string) *IntCmd
  214. ZScore(key, member string) *FloatCmd
  215. ZUnionStore(dest string, store ZStore, keys ...string) *IntCmd
  216. PFAdd(key string, els ...interface{}) *IntCmd
  217. PFCount(keys ...string) *IntCmd
  218. PFMerge(dest string, keys ...string) *StatusCmd
  219. BgRewriteAOF() *StatusCmd
  220. BgSave() *StatusCmd
  221. ClientKill(ipPort string) *StatusCmd
  222. ClientKillByFilter(keys ...string) *IntCmd
  223. ClientList() *StringCmd
  224. ClientPause(dur time.Duration) *BoolCmd
  225. ClientID() *IntCmd
  226. ConfigGet(parameter string) *SliceCmd
  227. ConfigResetStat() *StatusCmd
  228. ConfigSet(parameter, value string) *StatusCmd
  229. ConfigRewrite() *StatusCmd
  230. DBSize() *IntCmd
  231. FlushAll() *StatusCmd
  232. FlushAllAsync() *StatusCmd
  233. FlushDB() *StatusCmd
  234. FlushDBAsync() *StatusCmd
  235. Info(section ...string) *StringCmd
  236. LastSave() *IntCmd
  237. Save() *StatusCmd
  238. Shutdown() *StatusCmd
  239. ShutdownSave() *StatusCmd
  240. ShutdownNoSave() *StatusCmd
  241. SlaveOf(host, port string) *StatusCmd
  242. Time() *TimeCmd
  243. Eval(script string, keys []string, args ...interface{}) *Cmd
  244. EvalSha(sha1 string, keys []string, args ...interface{}) *Cmd
  245. ScriptExists(hashes ...string) *BoolSliceCmd
  246. ScriptFlush() *StatusCmd
  247. ScriptKill() *StatusCmd
  248. ScriptLoad(script string) *StringCmd
  249. DebugObject(key string) *StringCmd
  250. Publish(channel string, message interface{}) *IntCmd
  251. PubSubChannels(pattern string) *StringSliceCmd
  252. PubSubNumSub(channels ...string) *StringIntMapCmd
  253. PubSubNumPat() *IntCmd
  254. ClusterSlots() *ClusterSlotsCmd
  255. ClusterNodes() *StringCmd
  256. ClusterMeet(host, port string) *StatusCmd
  257. ClusterForget(nodeID string) *StatusCmd
  258. ClusterReplicate(nodeID string) *StatusCmd
  259. ClusterResetSoft() *StatusCmd
  260. ClusterResetHard() *StatusCmd
  261. ClusterInfo() *StringCmd
  262. ClusterKeySlot(key string) *IntCmd
  263. ClusterGetKeysInSlot(slot int, count int) *StringSliceCmd
  264. ClusterCountFailureReports(nodeID string) *IntCmd
  265. ClusterCountKeysInSlot(slot int) *IntCmd
  266. ClusterDelSlots(slots ...int) *StatusCmd
  267. ClusterDelSlotsRange(min, max int) *StatusCmd
  268. ClusterSaveConfig() *StatusCmd
  269. ClusterSlaves(nodeID string) *StringSliceCmd
  270. ClusterFailover() *StatusCmd
  271. ClusterAddSlots(slots ...int) *StatusCmd
  272. ClusterAddSlotsRange(min, max int) *StatusCmd
  273. GeoAdd(key string, geoLocation ...*GeoLocation) *IntCmd
  274. GeoPos(key string, members ...string) *GeoPosCmd
  275. GeoRadius(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd
  276. GeoRadiusRO(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd
  277. GeoRadiusByMember(key, member string, query *GeoRadiusQuery) *GeoLocationCmd
  278. GeoRadiusByMemberRO(key, member string, query *GeoRadiusQuery) *GeoLocationCmd
  279. GeoDist(key string, member1, member2, unit string) *FloatCmd
  280. GeoHash(key string, members ...string) *StringSliceCmd
  281. ReadOnly() *StatusCmd
  282. ReadWrite() *StatusCmd
  283. MemoryUsage(key string, samples ...int) *IntCmd
  284. }
  285. type StatefulCmdable interface {
  286. Cmdable
  287. Auth(password string) *StatusCmd
  288. Select(index int) *StatusCmd
  289. SwapDB(index1, index2 int) *StatusCmd
  290. ClientSetName(name string) *BoolCmd
  291. }
  292. var _ Cmdable = (*Client)(nil)
  293. var _ Cmdable = (*Tx)(nil)
  294. var _ Cmdable = (*Ring)(nil)
  295. var _ Cmdable = (*ClusterClient)(nil)
  296. type cmdable struct {
  297. process func(cmd Cmder) error
  298. }
  299. func (c *cmdable) setProcessor(fn func(Cmder) error) {
  300. c.process = fn
  301. }
  302. type statefulCmdable struct {
  303. cmdable
  304. process func(cmd Cmder) error
  305. }
  306. func (c *statefulCmdable) setProcessor(fn func(Cmder) error) {
  307. c.process = fn
  308. c.cmdable.setProcessor(fn)
  309. }
  310. //------------------------------------------------------------------------------
  311. func (c *statefulCmdable) Auth(password string) *StatusCmd {
  312. cmd := NewStatusCmd("auth", password)
  313. c.process(cmd)
  314. return cmd
  315. }
  316. func (c *cmdable) Echo(message interface{}) *StringCmd {
  317. cmd := NewStringCmd("echo", message)
  318. c.process(cmd)
  319. return cmd
  320. }
  321. func (c *cmdable) Ping() *StatusCmd {
  322. cmd := NewStatusCmd("ping")
  323. c.process(cmd)
  324. return cmd
  325. }
  326. func (c *cmdable) Wait(numSlaves int, timeout time.Duration) *IntCmd {
  327. cmd := NewIntCmd("wait", numSlaves, int(timeout/time.Millisecond))
  328. c.process(cmd)
  329. return cmd
  330. }
  331. func (c *cmdable) Quit() *StatusCmd {
  332. panic("not implemented")
  333. }
  334. func (c *statefulCmdable) Select(index int) *StatusCmd {
  335. cmd := NewStatusCmd("select", index)
  336. c.process(cmd)
  337. return cmd
  338. }
  339. func (c *statefulCmdable) SwapDB(index1, index2 int) *StatusCmd {
  340. cmd := NewStatusCmd("swapdb", index1, index2)
  341. c.process(cmd)
  342. return cmd
  343. }
  344. //------------------------------------------------------------------------------
  345. func (c *cmdable) Command() *CommandsInfoCmd {
  346. cmd := NewCommandsInfoCmd("command")
  347. c.process(cmd)
  348. return cmd
  349. }
  350. func (c *cmdable) Del(keys ...string) *IntCmd {
  351. args := make([]interface{}, 1+len(keys))
  352. args[0] = "del"
  353. for i, key := range keys {
  354. args[1+i] = key
  355. }
  356. cmd := NewIntCmd(args...)
  357. c.process(cmd)
  358. return cmd
  359. }
  360. func (c *cmdable) Unlink(keys ...string) *IntCmd {
  361. args := make([]interface{}, 1+len(keys))
  362. args[0] = "unlink"
  363. for i, key := range keys {
  364. args[1+i] = key
  365. }
  366. cmd := NewIntCmd(args...)
  367. c.process(cmd)
  368. return cmd
  369. }
  370. func (c *cmdable) Dump(key string) *StringCmd {
  371. cmd := NewStringCmd("dump", key)
  372. c.process(cmd)
  373. return cmd
  374. }
  375. func (c *cmdable) Exists(keys ...string) *IntCmd {
  376. args := make([]interface{}, 1+len(keys))
  377. args[0] = "exists"
  378. for i, key := range keys {
  379. args[1+i] = key
  380. }
  381. cmd := NewIntCmd(args...)
  382. c.process(cmd)
  383. return cmd
  384. }
  385. func (c *cmdable) Expire(key string, expiration time.Duration) *BoolCmd {
  386. cmd := NewBoolCmd("expire", key, formatSec(expiration))
  387. c.process(cmd)
  388. return cmd
  389. }
  390. func (c *cmdable) ExpireAt(key string, tm time.Time) *BoolCmd {
  391. cmd := NewBoolCmd("expireat", key, tm.Unix())
  392. c.process(cmd)
  393. return cmd
  394. }
  395. func (c *cmdable) Keys(pattern string) *StringSliceCmd {
  396. cmd := NewStringSliceCmd("keys", pattern)
  397. c.process(cmd)
  398. return cmd
  399. }
  400. func (c *cmdable) Migrate(host, port, key string, db int64, timeout time.Duration) *StatusCmd {
  401. cmd := NewStatusCmd(
  402. "migrate",
  403. host,
  404. port,
  405. key,
  406. db,
  407. formatMs(timeout),
  408. )
  409. cmd.setReadTimeout(timeout)
  410. c.process(cmd)
  411. return cmd
  412. }
  413. func (c *cmdable) Move(key string, db int64) *BoolCmd {
  414. cmd := NewBoolCmd("move", key, db)
  415. c.process(cmd)
  416. return cmd
  417. }
  418. func (c *cmdable) ObjectRefCount(key string) *IntCmd {
  419. cmd := NewIntCmd("object", "refcount", key)
  420. c.process(cmd)
  421. return cmd
  422. }
  423. func (c *cmdable) ObjectEncoding(key string) *StringCmd {
  424. cmd := NewStringCmd("object", "encoding", key)
  425. c.process(cmd)
  426. return cmd
  427. }
  428. func (c *cmdable) ObjectIdleTime(key string) *DurationCmd {
  429. cmd := NewDurationCmd(time.Second, "object", "idletime", key)
  430. c.process(cmd)
  431. return cmd
  432. }
  433. func (c *cmdable) Persist(key string) *BoolCmd {
  434. cmd := NewBoolCmd("persist", key)
  435. c.process(cmd)
  436. return cmd
  437. }
  438. func (c *cmdable) PExpire(key string, expiration time.Duration) *BoolCmd {
  439. cmd := NewBoolCmd("pexpire", key, formatMs(expiration))
  440. c.process(cmd)
  441. return cmd
  442. }
  443. func (c *cmdable) PExpireAt(key string, tm time.Time) *BoolCmd {
  444. cmd := NewBoolCmd(
  445. "pexpireat",
  446. key,
  447. tm.UnixNano()/int64(time.Millisecond),
  448. )
  449. c.process(cmd)
  450. return cmd
  451. }
  452. func (c *cmdable) PTTL(key string) *DurationCmd {
  453. cmd := NewDurationCmd(time.Millisecond, "pttl", key)
  454. c.process(cmd)
  455. return cmd
  456. }
  457. func (c *cmdable) RandomKey() *StringCmd {
  458. cmd := NewStringCmd("randomkey")
  459. c.process(cmd)
  460. return cmd
  461. }
  462. func (c *cmdable) Rename(key, newkey string) *StatusCmd {
  463. cmd := NewStatusCmd("rename", key, newkey)
  464. c.process(cmd)
  465. return cmd
  466. }
  467. func (c *cmdable) RenameNX(key, newkey string) *BoolCmd {
  468. cmd := NewBoolCmd("renamenx", key, newkey)
  469. c.process(cmd)
  470. return cmd
  471. }
  472. func (c *cmdable) Restore(key string, ttl time.Duration, value string) *StatusCmd {
  473. cmd := NewStatusCmd(
  474. "restore",
  475. key,
  476. formatMs(ttl),
  477. value,
  478. )
  479. c.process(cmd)
  480. return cmd
  481. }
  482. func (c *cmdable) RestoreReplace(key string, ttl time.Duration, value string) *StatusCmd {
  483. cmd := NewStatusCmd(
  484. "restore",
  485. key,
  486. formatMs(ttl),
  487. value,
  488. "replace",
  489. )
  490. c.process(cmd)
  491. return cmd
  492. }
  493. type Sort struct {
  494. By string
  495. Offset, Count int64
  496. Get []string
  497. Order string
  498. Alpha bool
  499. }
  500. func (sort *Sort) args(key string) []interface{} {
  501. args := []interface{}{"sort", key}
  502. if sort.By != "" {
  503. args = append(args, "by", sort.By)
  504. }
  505. if sort.Offset != 0 || sort.Count != 0 {
  506. args = append(args, "limit", sort.Offset, sort.Count)
  507. }
  508. for _, get := range sort.Get {
  509. args = append(args, "get", get)
  510. }
  511. if sort.Order != "" {
  512. args = append(args, sort.Order)
  513. }
  514. if sort.Alpha {
  515. args = append(args, "alpha")
  516. }
  517. return args
  518. }
  519. func (c *cmdable) Sort(key string, sort *Sort) *StringSliceCmd {
  520. cmd := NewStringSliceCmd(sort.args(key)...)
  521. c.process(cmd)
  522. return cmd
  523. }
  524. func (c *cmdable) SortStore(key, store string, sort *Sort) *IntCmd {
  525. args := sort.args(key)
  526. if store != "" {
  527. args = append(args, "store", store)
  528. }
  529. cmd := NewIntCmd(args...)
  530. c.process(cmd)
  531. return cmd
  532. }
  533. func (c *cmdable) SortInterfaces(key string, sort *Sort) *SliceCmd {
  534. cmd := NewSliceCmd(sort.args(key)...)
  535. c.process(cmd)
  536. return cmd
  537. }
  538. func (c *cmdable) Touch(keys ...string) *IntCmd {
  539. args := make([]interface{}, len(keys)+1)
  540. args[0] = "touch"
  541. for i, key := range keys {
  542. args[i+1] = key
  543. }
  544. cmd := NewIntCmd(args...)
  545. c.process(cmd)
  546. return cmd
  547. }
  548. func (c *cmdable) TTL(key string) *DurationCmd {
  549. cmd := NewDurationCmd(time.Second, "ttl", key)
  550. c.process(cmd)
  551. return cmd
  552. }
  553. func (c *cmdable) Type(key string) *StatusCmd {
  554. cmd := NewStatusCmd("type", key)
  555. c.process(cmd)
  556. return cmd
  557. }
  558. func (c *cmdable) Scan(cursor uint64, match string, count int64) *ScanCmd {
  559. args := []interface{}{"scan", cursor}
  560. if match != "" {
  561. args = append(args, "match", match)
  562. }
  563. if count > 0 {
  564. args = append(args, "count", count)
  565. }
  566. cmd := NewScanCmd(c.process, args...)
  567. c.process(cmd)
  568. return cmd
  569. }
  570. func (c *cmdable) SScan(key string, cursor uint64, match string, count int64) *ScanCmd {
  571. args := []interface{}{"sscan", key, cursor}
  572. if match != "" {
  573. args = append(args, "match", match)
  574. }
  575. if count > 0 {
  576. args = append(args, "count", count)
  577. }
  578. cmd := NewScanCmd(c.process, args...)
  579. c.process(cmd)
  580. return cmd
  581. }
  582. func (c *cmdable) HScan(key string, cursor uint64, match string, count int64) *ScanCmd {
  583. args := []interface{}{"hscan", key, cursor}
  584. if match != "" {
  585. args = append(args, "match", match)
  586. }
  587. if count > 0 {
  588. args = append(args, "count", count)
  589. }
  590. cmd := NewScanCmd(c.process, args...)
  591. c.process(cmd)
  592. return cmd
  593. }
  594. func (c *cmdable) ZScan(key string, cursor uint64, match string, count int64) *ScanCmd {
  595. args := []interface{}{"zscan", key, cursor}
  596. if match != "" {
  597. args = append(args, "match", match)
  598. }
  599. if count > 0 {
  600. args = append(args, "count", count)
  601. }
  602. cmd := NewScanCmd(c.process, args...)
  603. c.process(cmd)
  604. return cmd
  605. }
  606. //------------------------------------------------------------------------------
  607. func (c *cmdable) Append(key, value string) *IntCmd {
  608. cmd := NewIntCmd("append", key, value)
  609. c.process(cmd)
  610. return cmd
  611. }
  612. type BitCount struct {
  613. Start, End int64
  614. }
  615. func (c *cmdable) BitCount(key string, bitCount *BitCount) *IntCmd {
  616. args := []interface{}{"bitcount", key}
  617. if bitCount != nil {
  618. args = append(
  619. args,
  620. bitCount.Start,
  621. bitCount.End,
  622. )
  623. }
  624. cmd := NewIntCmd(args...)
  625. c.process(cmd)
  626. return cmd
  627. }
  628. func (c *cmdable) bitOp(op, destKey string, keys ...string) *IntCmd {
  629. args := make([]interface{}, 3+len(keys))
  630. args[0] = "bitop"
  631. args[1] = op
  632. args[2] = destKey
  633. for i, key := range keys {
  634. args[3+i] = key
  635. }
  636. cmd := NewIntCmd(args...)
  637. c.process(cmd)
  638. return cmd
  639. }
  640. func (c *cmdable) BitOpAnd(destKey string, keys ...string) *IntCmd {
  641. return c.bitOp("and", destKey, keys...)
  642. }
  643. func (c *cmdable) BitOpOr(destKey string, keys ...string) *IntCmd {
  644. return c.bitOp("or", destKey, keys...)
  645. }
  646. func (c *cmdable) BitOpXor(destKey string, keys ...string) *IntCmd {
  647. return c.bitOp("xor", destKey, keys...)
  648. }
  649. func (c *cmdable) BitOpNot(destKey string, key string) *IntCmd {
  650. return c.bitOp("not", destKey, key)
  651. }
  652. func (c *cmdable) BitPos(key string, bit int64, pos ...int64) *IntCmd {
  653. args := make([]interface{}, 3+len(pos))
  654. args[0] = "bitpos"
  655. args[1] = key
  656. args[2] = bit
  657. switch len(pos) {
  658. case 0:
  659. case 1:
  660. args[3] = pos[0]
  661. case 2:
  662. args[3] = pos[0]
  663. args[4] = pos[1]
  664. default:
  665. panic("too many arguments")
  666. }
  667. cmd := NewIntCmd(args...)
  668. c.process(cmd)
  669. return cmd
  670. }
  671. func (c *cmdable) Decr(key string) *IntCmd {
  672. cmd := NewIntCmd("decr", key)
  673. c.process(cmd)
  674. return cmd
  675. }
  676. func (c *cmdable) DecrBy(key string, decrement int64) *IntCmd {
  677. cmd := NewIntCmd("decrby", key, decrement)
  678. c.process(cmd)
  679. return cmd
  680. }
  681. // Redis `GET key` command. It returns redis.Nil error when key does not exist.
  682. func (c *cmdable) Get(key string) *StringCmd {
  683. cmd := NewStringCmd("get", key)
  684. c.process(cmd)
  685. return cmd
  686. }
  687. func (c *cmdable) GetBit(key string, offset int64) *IntCmd {
  688. cmd := NewIntCmd("getbit", key, offset)
  689. c.process(cmd)
  690. return cmd
  691. }
  692. func (c *cmdable) GetRange(key string, start, end int64) *StringCmd {
  693. cmd := NewStringCmd("getrange", key, start, end)
  694. c.process(cmd)
  695. return cmd
  696. }
  697. func (c *cmdable) GetSet(key string, value interface{}) *StringCmd {
  698. cmd := NewStringCmd("getset", key, value)
  699. c.process(cmd)
  700. return cmd
  701. }
  702. func (c *cmdable) Incr(key string) *IntCmd {
  703. cmd := NewIntCmd("incr", key)
  704. c.process(cmd)
  705. return cmd
  706. }
  707. func (c *cmdable) IncrBy(key string, value int64) *IntCmd {
  708. cmd := NewIntCmd("incrby", key, value)
  709. c.process(cmd)
  710. return cmd
  711. }
  712. func (c *cmdable) IncrByFloat(key string, value float64) *FloatCmd {
  713. cmd := NewFloatCmd("incrbyfloat", key, value)
  714. c.process(cmd)
  715. return cmd
  716. }
  717. func (c *cmdable) MGet(keys ...string) *SliceCmd {
  718. args := make([]interface{}, 1+len(keys))
  719. args[0] = "mget"
  720. for i, key := range keys {
  721. args[1+i] = key
  722. }
  723. cmd := NewSliceCmd(args...)
  724. c.process(cmd)
  725. return cmd
  726. }
  727. func (c *cmdable) MSet(pairs ...interface{}) *StatusCmd {
  728. args := make([]interface{}, 1, 1+len(pairs))
  729. args[0] = "mset"
  730. args = appendArgs(args, pairs)
  731. cmd := NewStatusCmd(args...)
  732. c.process(cmd)
  733. return cmd
  734. }
  735. func (c *cmdable) MSetNX(pairs ...interface{}) *BoolCmd {
  736. args := make([]interface{}, 1, 1+len(pairs))
  737. args[0] = "msetnx"
  738. args = appendArgs(args, pairs)
  739. cmd := NewBoolCmd(args...)
  740. c.process(cmd)
  741. return cmd
  742. }
  743. // Redis `SET key value [expiration]` command.
  744. //
  745. // Use expiration for `SETEX`-like behavior.
  746. // Zero expiration means the key has no expiration time.
  747. func (c *cmdable) Set(key string, value interface{}, expiration time.Duration) *StatusCmd {
  748. args := make([]interface{}, 3, 4)
  749. args[0] = "set"
  750. args[1] = key
  751. args[2] = value
  752. if expiration > 0 {
  753. if usePrecise(expiration) {
  754. args = append(args, "px", formatMs(expiration))
  755. } else {
  756. args = append(args, "ex", formatSec(expiration))
  757. }
  758. }
  759. cmd := NewStatusCmd(args...)
  760. c.process(cmd)
  761. return cmd
  762. }
  763. func (c *cmdable) SetBit(key string, offset int64, value int) *IntCmd {
  764. cmd := NewIntCmd(
  765. "setbit",
  766. key,
  767. offset,
  768. value,
  769. )
  770. c.process(cmd)
  771. return cmd
  772. }
  773. // Redis `SET key value [expiration] NX` command.
  774. //
  775. // Zero expiration means the key has no expiration time.
  776. func (c *cmdable) SetNX(key string, value interface{}, expiration time.Duration) *BoolCmd {
  777. var cmd *BoolCmd
  778. if expiration == 0 {
  779. // Use old `SETNX` to support old Redis versions.
  780. cmd = NewBoolCmd("setnx", key, value)
  781. } else {
  782. if usePrecise(expiration) {
  783. cmd = NewBoolCmd("set", key, value, "px", formatMs(expiration), "nx")
  784. } else {
  785. cmd = NewBoolCmd("set", key, value, "ex", formatSec(expiration), "nx")
  786. }
  787. }
  788. c.process(cmd)
  789. return cmd
  790. }
  791. // Redis `SET key value [expiration] XX` command.
  792. //
  793. // Zero expiration means the key has no expiration time.
  794. func (c *cmdable) SetXX(key string, value interface{}, expiration time.Duration) *BoolCmd {
  795. var cmd *BoolCmd
  796. if expiration == 0 {
  797. cmd = NewBoolCmd("set", key, value, "xx")
  798. } else {
  799. if usePrecise(expiration) {
  800. cmd = NewBoolCmd("set", key, value, "px", formatMs(expiration), "xx")
  801. } else {
  802. cmd = NewBoolCmd("set", key, value, "ex", formatSec(expiration), "xx")
  803. }
  804. }
  805. c.process(cmd)
  806. return cmd
  807. }
  808. func (c *cmdable) SetRange(key string, offset int64, value string) *IntCmd {
  809. cmd := NewIntCmd("setrange", key, offset, value)
  810. c.process(cmd)
  811. return cmd
  812. }
  813. func (c *cmdable) StrLen(key string) *IntCmd {
  814. cmd := NewIntCmd("strlen", key)
  815. c.process(cmd)
  816. return cmd
  817. }
  818. //------------------------------------------------------------------------------
  819. func (c *cmdable) HDel(key string, fields ...string) *IntCmd {
  820. args := make([]interface{}, 2+len(fields))
  821. args[0] = "hdel"
  822. args[1] = key
  823. for i, field := range fields {
  824. args[2+i] = field
  825. }
  826. cmd := NewIntCmd(args...)
  827. c.process(cmd)
  828. return cmd
  829. }
  830. func (c *cmdable) HExists(key, field string) *BoolCmd {
  831. cmd := NewBoolCmd("hexists", key, field)
  832. c.process(cmd)
  833. return cmd
  834. }
  835. func (c *cmdable) HGet(key, field string) *StringCmd {
  836. cmd := NewStringCmd("hget", key, field)
  837. c.process(cmd)
  838. return cmd
  839. }
  840. func (c *cmdable) HGetAll(key string) *StringStringMapCmd {
  841. cmd := NewStringStringMapCmd("hgetall", key)
  842. c.process(cmd)
  843. return cmd
  844. }
  845. func (c *cmdable) HIncrBy(key, field string, incr int64) *IntCmd {
  846. cmd := NewIntCmd("hincrby", key, field, incr)
  847. c.process(cmd)
  848. return cmd
  849. }
  850. func (c *cmdable) HIncrByFloat(key, field string, incr float64) *FloatCmd {
  851. cmd := NewFloatCmd("hincrbyfloat", key, field, incr)
  852. c.process(cmd)
  853. return cmd
  854. }
  855. func (c *cmdable) HKeys(key string) *StringSliceCmd {
  856. cmd := NewStringSliceCmd("hkeys", key)
  857. c.process(cmd)
  858. return cmd
  859. }
  860. func (c *cmdable) HLen(key string) *IntCmd {
  861. cmd := NewIntCmd("hlen", key)
  862. c.process(cmd)
  863. return cmd
  864. }
  865. func (c *cmdable) HMGet(key string, fields ...string) *SliceCmd {
  866. args := make([]interface{}, 2+len(fields))
  867. args[0] = "hmget"
  868. args[1] = key
  869. for i, field := range fields {
  870. args[2+i] = field
  871. }
  872. cmd := NewSliceCmd(args...)
  873. c.process(cmd)
  874. return cmd
  875. }
  876. func (c *cmdable) HMSet(key string, fields map[string]interface{}) *StatusCmd {
  877. args := make([]interface{}, 2+len(fields)*2)
  878. args[0] = "hmset"
  879. args[1] = key
  880. i := 2
  881. for k, v := range fields {
  882. args[i] = k
  883. args[i+1] = v
  884. i += 2
  885. }
  886. cmd := NewStatusCmd(args...)
  887. c.process(cmd)
  888. return cmd
  889. }
  890. func (c *cmdable) HSet(key, field string, value interface{}) *BoolCmd {
  891. cmd := NewBoolCmd("hset", key, field, value)
  892. c.process(cmd)
  893. return cmd
  894. }
  895. func (c *cmdable) HSetNX(key, field string, value interface{}) *BoolCmd {
  896. cmd := NewBoolCmd("hsetnx", key, field, value)
  897. c.process(cmd)
  898. return cmd
  899. }
  900. func (c *cmdable) HVals(key string) *StringSliceCmd {
  901. cmd := NewStringSliceCmd("hvals", key)
  902. c.process(cmd)
  903. return cmd
  904. }
  905. //------------------------------------------------------------------------------
  906. func (c *cmdable) BLPop(timeout time.Duration, keys ...string) *StringSliceCmd {
  907. args := make([]interface{}, 1+len(keys)+1)
  908. args[0] = "blpop"
  909. for i, key := range keys {
  910. args[1+i] = key
  911. }
  912. args[len(args)-1] = formatSec(timeout)
  913. cmd := NewStringSliceCmd(args...)
  914. cmd.setReadTimeout(timeout)
  915. c.process(cmd)
  916. return cmd
  917. }
  918. func (c *cmdable) BRPop(timeout time.Duration, keys ...string) *StringSliceCmd {
  919. args := make([]interface{}, 1+len(keys)+1)
  920. args[0] = "brpop"
  921. for i, key := range keys {
  922. args[1+i] = key
  923. }
  924. args[len(keys)+1] = formatSec(timeout)
  925. cmd := NewStringSliceCmd(args...)
  926. cmd.setReadTimeout(timeout)
  927. c.process(cmd)
  928. return cmd
  929. }
  930. func (c *cmdable) BRPopLPush(source, destination string, timeout time.Duration) *StringCmd {
  931. cmd := NewStringCmd(
  932. "brpoplpush",
  933. source,
  934. destination,
  935. formatSec(timeout),
  936. )
  937. cmd.setReadTimeout(timeout)
  938. c.process(cmd)
  939. return cmd
  940. }
  941. func (c *cmdable) LIndex(key string, index int64) *StringCmd {
  942. cmd := NewStringCmd("lindex", key, index)
  943. c.process(cmd)
  944. return cmd
  945. }
  946. func (c *cmdable) LInsert(key, op string, pivot, value interface{}) *IntCmd {
  947. cmd := NewIntCmd("linsert", key, op, pivot, value)
  948. c.process(cmd)
  949. return cmd
  950. }
  951. func (c *cmdable) LInsertBefore(key string, pivot, value interface{}) *IntCmd {
  952. cmd := NewIntCmd("linsert", key, "before", pivot, value)
  953. c.process(cmd)
  954. return cmd
  955. }
  956. func (c *cmdable) LInsertAfter(key string, pivot, value interface{}) *IntCmd {
  957. cmd := NewIntCmd("linsert", key, "after", pivot, value)
  958. c.process(cmd)
  959. return cmd
  960. }
  961. func (c *cmdable) LLen(key string) *IntCmd {
  962. cmd := NewIntCmd("llen", key)
  963. c.process(cmd)
  964. return cmd
  965. }
  966. func (c *cmdable) LPop(key string) *StringCmd {
  967. cmd := NewStringCmd("lpop", key)
  968. c.process(cmd)
  969. return cmd
  970. }
  971. func (c *cmdable) LPush(key string, values ...interface{}) *IntCmd {
  972. args := make([]interface{}, 2, 2+len(values))
  973. args[0] = "lpush"
  974. args[1] = key
  975. args = appendArgs(args, values)
  976. cmd := NewIntCmd(args...)
  977. c.process(cmd)
  978. return cmd
  979. }
  980. func (c *cmdable) LPushX(key string, value interface{}) *IntCmd {
  981. cmd := NewIntCmd("lpushx", key, value)
  982. c.process(cmd)
  983. return cmd
  984. }
  985. func (c *cmdable) LRange(key string, start, stop int64) *StringSliceCmd {
  986. cmd := NewStringSliceCmd(
  987. "lrange",
  988. key,
  989. start,
  990. stop,
  991. )
  992. c.process(cmd)
  993. return cmd
  994. }
  995. func (c *cmdable) LRem(key string, count int64, value interface{}) *IntCmd {
  996. cmd := NewIntCmd("lrem", key, count, value)
  997. c.process(cmd)
  998. return cmd
  999. }
  1000. func (c *cmdable) LSet(key string, index int64, value interface{}) *StatusCmd {
  1001. cmd := NewStatusCmd("lset", key, index, value)
  1002. c.process(cmd)
  1003. return cmd
  1004. }
  1005. func (c *cmdable) LTrim(key string, start, stop int64) *StatusCmd {
  1006. cmd := NewStatusCmd(
  1007. "ltrim",
  1008. key,
  1009. start,
  1010. stop,
  1011. )
  1012. c.process(cmd)
  1013. return cmd
  1014. }
  1015. func (c *cmdable) RPop(key string) *StringCmd {
  1016. cmd := NewStringCmd("rpop", key)
  1017. c.process(cmd)
  1018. return cmd
  1019. }
  1020. func (c *cmdable) RPopLPush(source, destination string) *StringCmd {
  1021. cmd := NewStringCmd("rpoplpush", source, destination)
  1022. c.process(cmd)
  1023. return cmd
  1024. }
  1025. func (c *cmdable) RPush(key string, values ...interface{}) *IntCmd {
  1026. args := make([]interface{}, 2, 2+len(values))
  1027. args[0] = "rpush"
  1028. args[1] = key
  1029. args = appendArgs(args, values)
  1030. cmd := NewIntCmd(args...)
  1031. c.process(cmd)
  1032. return cmd
  1033. }
  1034. func (c *cmdable) RPushX(key string, value interface{}) *IntCmd {
  1035. cmd := NewIntCmd("rpushx", key, value)
  1036. c.process(cmd)
  1037. return cmd
  1038. }
  1039. //------------------------------------------------------------------------------
  1040. func (c *cmdable) SAdd(key string, members ...interface{}) *IntCmd {
  1041. args := make([]interface{}, 2, 2+len(members))
  1042. args[0] = "sadd"
  1043. args[1] = key
  1044. args = appendArgs(args, members)
  1045. cmd := NewIntCmd(args...)
  1046. c.process(cmd)
  1047. return cmd
  1048. }
  1049. func (c *cmdable) SCard(key string) *IntCmd {
  1050. cmd := NewIntCmd("scard", key)
  1051. c.process(cmd)
  1052. return cmd
  1053. }
  1054. func (c *cmdable) SDiff(keys ...string) *StringSliceCmd {
  1055. args := make([]interface{}, 1+len(keys))
  1056. args[0] = "sdiff"
  1057. for i, key := range keys {
  1058. args[1+i] = key
  1059. }
  1060. cmd := NewStringSliceCmd(args...)
  1061. c.process(cmd)
  1062. return cmd
  1063. }
  1064. func (c *cmdable) SDiffStore(destination string, keys ...string) *IntCmd {
  1065. args := make([]interface{}, 2+len(keys))
  1066. args[0] = "sdiffstore"
  1067. args[1] = destination
  1068. for i, key := range keys {
  1069. args[2+i] = key
  1070. }
  1071. cmd := NewIntCmd(args...)
  1072. c.process(cmd)
  1073. return cmd
  1074. }
  1075. func (c *cmdable) SInter(keys ...string) *StringSliceCmd {
  1076. args := make([]interface{}, 1+len(keys))
  1077. args[0] = "sinter"
  1078. for i, key := range keys {
  1079. args[1+i] = key
  1080. }
  1081. cmd := NewStringSliceCmd(args...)
  1082. c.process(cmd)
  1083. return cmd
  1084. }
  1085. func (c *cmdable) SInterStore(destination string, keys ...string) *IntCmd {
  1086. args := make([]interface{}, 2+len(keys))
  1087. args[0] = "sinterstore"
  1088. args[1] = destination
  1089. for i, key := range keys {
  1090. args[2+i] = key
  1091. }
  1092. cmd := NewIntCmd(args...)
  1093. c.process(cmd)
  1094. return cmd
  1095. }
  1096. func (c *cmdable) SIsMember(key string, member interface{}) *BoolCmd {
  1097. cmd := NewBoolCmd("sismember", key, member)
  1098. c.process(cmd)
  1099. return cmd
  1100. }
  1101. // Redis `SMEMBERS key` command output as a slice
  1102. func (c *cmdable) SMembers(key string) *StringSliceCmd {
  1103. cmd := NewStringSliceCmd("smembers", key)
  1104. c.process(cmd)
  1105. return cmd
  1106. }
  1107. // Redis `SMEMBERS key` command output as a map
  1108. func (c *cmdable) SMembersMap(key string) *StringStructMapCmd {
  1109. cmd := NewStringStructMapCmd("smembers", key)
  1110. c.process(cmd)
  1111. return cmd
  1112. }
  1113. func (c *cmdable) SMove(source, destination string, member interface{}) *BoolCmd {
  1114. cmd := NewBoolCmd("smove", source, destination, member)
  1115. c.process(cmd)
  1116. return cmd
  1117. }
  1118. // Redis `SPOP key` command.
  1119. func (c *cmdable) SPop(key string) *StringCmd {
  1120. cmd := NewStringCmd("spop", key)
  1121. c.process(cmd)
  1122. return cmd
  1123. }
  1124. // Redis `SPOP key count` command.
  1125. func (c *cmdable) SPopN(key string, count int64) *StringSliceCmd {
  1126. cmd := NewStringSliceCmd("spop", key, count)
  1127. c.process(cmd)
  1128. return cmd
  1129. }
  1130. // Redis `SRANDMEMBER key` command.
  1131. func (c *cmdable) SRandMember(key string) *StringCmd {
  1132. cmd := NewStringCmd("srandmember", key)
  1133. c.process(cmd)
  1134. return cmd
  1135. }
  1136. // Redis `SRANDMEMBER key count` command.
  1137. func (c *cmdable) SRandMemberN(key string, count int64) *StringSliceCmd {
  1138. cmd := NewStringSliceCmd("srandmember", key, count)
  1139. c.process(cmd)
  1140. return cmd
  1141. }
  1142. func (c *cmdable) SRem(key string, members ...interface{}) *IntCmd {
  1143. args := make([]interface{}, 2, 2+len(members))
  1144. args[0] = "srem"
  1145. args[1] = key
  1146. args = appendArgs(args, members)
  1147. cmd := NewIntCmd(args...)
  1148. c.process(cmd)
  1149. return cmd
  1150. }
  1151. func (c *cmdable) SUnion(keys ...string) *StringSliceCmd {
  1152. args := make([]interface{}, 1+len(keys))
  1153. args[0] = "sunion"
  1154. for i, key := range keys {
  1155. args[1+i] = key
  1156. }
  1157. cmd := NewStringSliceCmd(args...)
  1158. c.process(cmd)
  1159. return cmd
  1160. }
  1161. func (c *cmdable) SUnionStore(destination string, keys ...string) *IntCmd {
  1162. args := make([]interface{}, 2+len(keys))
  1163. args[0] = "sunionstore"
  1164. args[1] = destination
  1165. for i, key := range keys {
  1166. args[2+i] = key
  1167. }
  1168. cmd := NewIntCmd(args...)
  1169. c.process(cmd)
  1170. return cmd
  1171. }
  1172. //------------------------------------------------------------------------------
  1173. type XAddArgs struct {
  1174. Stream string
  1175. MaxLen int64 // MAXLEN N
  1176. MaxLenApprox int64 // MAXLEN ~ N
  1177. ID string
  1178. Values map[string]interface{}
  1179. }
  1180. func (c *cmdable) XAdd(a *XAddArgs) *StringCmd {
  1181. args := make([]interface{}, 0, 6+len(a.Values)*2)
  1182. args = append(args, "xadd")
  1183. args = append(args, a.Stream)
  1184. if a.MaxLen > 0 {
  1185. args = append(args, "maxlen", a.MaxLen)
  1186. } else if a.MaxLenApprox > 0 {
  1187. args = append(args, "maxlen", "~", a.MaxLenApprox)
  1188. }
  1189. if a.ID != "" {
  1190. args = append(args, a.ID)
  1191. } else {
  1192. args = append(args, "*")
  1193. }
  1194. for k, v := range a.Values {
  1195. args = append(args, k)
  1196. args = append(args, v)
  1197. }
  1198. cmd := NewStringCmd(args...)
  1199. c.process(cmd)
  1200. return cmd
  1201. }
  1202. func (c *cmdable) XDel(stream string, ids ...string) *IntCmd {
  1203. args := []interface{}{"xdel", stream}
  1204. for _, id := range ids {
  1205. args = append(args, id)
  1206. }
  1207. cmd := NewIntCmd(args...)
  1208. c.process(cmd)
  1209. return cmd
  1210. }
  1211. func (c *cmdable) XLen(stream string) *IntCmd {
  1212. cmd := NewIntCmd("xlen", stream)
  1213. c.process(cmd)
  1214. return cmd
  1215. }
  1216. func (c *cmdable) XRange(stream, start, stop string) *XMessageSliceCmd {
  1217. cmd := NewXMessageSliceCmd("xrange", stream, start, stop)
  1218. c.process(cmd)
  1219. return cmd
  1220. }
  1221. func (c *cmdable) XRangeN(stream, start, stop string, count int64) *XMessageSliceCmd {
  1222. cmd := NewXMessageSliceCmd("xrange", stream, start, stop, "count", count)
  1223. c.process(cmd)
  1224. return cmd
  1225. }
  1226. func (c *cmdable) XRevRange(stream, start, stop string) *XMessageSliceCmd {
  1227. cmd := NewXMessageSliceCmd("xrevrange", stream, start, stop)
  1228. c.process(cmd)
  1229. return cmd
  1230. }
  1231. func (c *cmdable) XRevRangeN(stream, start, stop string, count int64) *XMessageSliceCmd {
  1232. cmd := NewXMessageSliceCmd("xrevrange", stream, start, stop, "count", count)
  1233. c.process(cmd)
  1234. return cmd
  1235. }
  1236. type XReadArgs struct {
  1237. Streams []string
  1238. Count int64
  1239. Block time.Duration
  1240. }
  1241. func (c *cmdable) XRead(a *XReadArgs) *XStreamSliceCmd {
  1242. args := make([]interface{}, 0, 5+len(a.Streams))
  1243. args = append(args, "xread")
  1244. if a.Count > 0 {
  1245. args = append(args, "count")
  1246. args = append(args, a.Count)
  1247. }
  1248. if a.Block >= 0 {
  1249. args = append(args, "block")
  1250. args = append(args, int64(a.Block/time.Millisecond))
  1251. }
  1252. args = append(args, "streams")
  1253. for _, s := range a.Streams {
  1254. args = append(args, s)
  1255. }
  1256. cmd := NewXStreamSliceCmd(args...)
  1257. if a.Block >= 0 {
  1258. cmd.setReadTimeout(a.Block)
  1259. }
  1260. c.process(cmd)
  1261. return cmd
  1262. }
  1263. func (c *cmdable) XReadStreams(streams ...string) *XStreamSliceCmd {
  1264. return c.XRead(&XReadArgs{
  1265. Streams: streams,
  1266. Block: -1,
  1267. })
  1268. }
  1269. func (c *cmdable) XGroupCreate(stream, group, start string) *StatusCmd {
  1270. cmd := NewStatusCmd("xgroup", "create", stream, group, start)
  1271. c.process(cmd)
  1272. return cmd
  1273. }
  1274. func (c *cmdable) XGroupCreateMkStream(stream, group, start string) *StatusCmd {
  1275. cmd := NewStatusCmd("xgroup", "create", stream, group, start, "mkstream")
  1276. c.process(cmd)
  1277. return cmd
  1278. }
  1279. func (c *cmdable) XGroupSetID(stream, group, start string) *StatusCmd {
  1280. cmd := NewStatusCmd("xgroup", "setid", stream, group, start)
  1281. c.process(cmd)
  1282. return cmd
  1283. }
  1284. func (c *cmdable) XGroupDestroy(stream, group string) *IntCmd {
  1285. cmd := NewIntCmd("xgroup", "destroy", stream, group)
  1286. c.process(cmd)
  1287. return cmd
  1288. }
  1289. func (c *cmdable) XGroupDelConsumer(stream, group, consumer string) *IntCmd {
  1290. cmd := NewIntCmd("xgroup", "delconsumer", stream, group, consumer)
  1291. c.process(cmd)
  1292. return cmd
  1293. }
  1294. type XReadGroupArgs struct {
  1295. Group string
  1296. Consumer string
  1297. // List of streams and ids.
  1298. Streams []string
  1299. Count int64
  1300. Block time.Duration
  1301. NoAck bool
  1302. }
  1303. func (c *cmdable) XReadGroup(a *XReadGroupArgs) *XStreamSliceCmd {
  1304. args := make([]interface{}, 0, 8+len(a.Streams))
  1305. args = append(args, "xreadgroup", "group", a.Group, a.Consumer)
  1306. if a.Count > 0 {
  1307. args = append(args, "count", a.Count)
  1308. }
  1309. if a.Block >= 0 {
  1310. args = append(args, "block", int64(a.Block/time.Millisecond))
  1311. }
  1312. if a.NoAck {
  1313. args = append(args, "noack")
  1314. }
  1315. args = append(args, "streams")
  1316. for _, s := range a.Streams {
  1317. args = append(args, s)
  1318. }
  1319. cmd := NewXStreamSliceCmd(args...)
  1320. if a.Block >= 0 {
  1321. cmd.setReadTimeout(a.Block)
  1322. }
  1323. c.process(cmd)
  1324. return cmd
  1325. }
  1326. func (c *cmdable) XAck(stream, group string, ids ...string) *IntCmd {
  1327. args := []interface{}{"xack", stream, group}
  1328. for _, id := range ids {
  1329. args = append(args, id)
  1330. }
  1331. cmd := NewIntCmd(args...)
  1332. c.process(cmd)
  1333. return cmd
  1334. }
  1335. func (c *cmdable) XPending(stream, group string) *XPendingCmd {
  1336. cmd := NewXPendingCmd("xpending", stream, group)
  1337. c.process(cmd)
  1338. return cmd
  1339. }
  1340. type XPendingExtArgs struct {
  1341. Stream string
  1342. Group string
  1343. Start string
  1344. End string
  1345. Count int64
  1346. Consumer string
  1347. }
  1348. func (c *cmdable) XPendingExt(a *XPendingExtArgs) *XPendingExtCmd {
  1349. args := make([]interface{}, 0, 7)
  1350. args = append(args, "xpending", a.Stream, a.Group, a.Start, a.End, a.Count)
  1351. if a.Consumer != "" {
  1352. args = append(args, a.Consumer)
  1353. }
  1354. cmd := NewXPendingExtCmd(args...)
  1355. c.process(cmd)
  1356. return cmd
  1357. }
  1358. type XClaimArgs struct {
  1359. Stream string
  1360. Group string
  1361. Consumer string
  1362. MinIdle time.Duration
  1363. Messages []string
  1364. }
  1365. func (c *cmdable) XClaim(a *XClaimArgs) *XMessageSliceCmd {
  1366. args := xClaimArgs(a)
  1367. cmd := NewXMessageSliceCmd(args...)
  1368. c.process(cmd)
  1369. return cmd
  1370. }
  1371. func (c *cmdable) XClaimJustID(a *XClaimArgs) *StringSliceCmd {
  1372. args := xClaimArgs(a)
  1373. args = append(args, "justid")
  1374. cmd := NewStringSliceCmd(args...)
  1375. c.process(cmd)
  1376. return cmd
  1377. }
  1378. func xClaimArgs(a *XClaimArgs) []interface{} {
  1379. args := make([]interface{}, 0, 4+len(a.Messages))
  1380. args = append(args,
  1381. "xclaim",
  1382. a.Stream,
  1383. a.Group, a.Consumer,
  1384. int64(a.MinIdle/time.Millisecond))
  1385. for _, id := range a.Messages {
  1386. args = append(args, id)
  1387. }
  1388. return args
  1389. }
  1390. func (c *cmdable) XTrim(key string, maxLen int64) *IntCmd {
  1391. cmd := NewIntCmd("xtrim", key, "maxlen", maxLen)
  1392. c.process(cmd)
  1393. return cmd
  1394. }
  1395. func (c *cmdable) XTrimApprox(key string, maxLen int64) *IntCmd {
  1396. cmd := NewIntCmd("xtrim", key, "maxlen", "~", maxLen)
  1397. c.process(cmd)
  1398. return cmd
  1399. }
  1400. //------------------------------------------------------------------------------
  1401. // Z represents sorted set member.
  1402. type Z struct {
  1403. Score float64
  1404. Member interface{}
  1405. }
  1406. // ZWithKey represents sorted set member including the name of the key where it was popped.
  1407. type ZWithKey struct {
  1408. Z
  1409. Key string
  1410. }
  1411. // ZStore is used as an arg to ZInterStore and ZUnionStore.
  1412. type ZStore struct {
  1413. Weights []float64
  1414. // Can be SUM, MIN or MAX.
  1415. Aggregate string
  1416. }
  1417. // Redis `BZPOPMAX key [key ...] timeout` command.
  1418. func (c *cmdable) BZPopMax(timeout time.Duration, keys ...string) *ZWithKeyCmd {
  1419. args := make([]interface{}, 1+len(keys)+1)
  1420. args[0] = "bzpopmax"
  1421. for i, key := range keys {
  1422. args[1+i] = key
  1423. }
  1424. args[len(args)-1] = formatSec(timeout)
  1425. cmd := NewZWithKeyCmd(args...)
  1426. cmd.setReadTimeout(timeout)
  1427. c.process(cmd)
  1428. return cmd
  1429. }
  1430. // Redis `BZPOPMIN key [key ...] timeout` command.
  1431. func (c *cmdable) BZPopMin(timeout time.Duration, keys ...string) *ZWithKeyCmd {
  1432. args := make([]interface{}, 1+len(keys)+1)
  1433. args[0] = "bzpopmin"
  1434. for i, key := range keys {
  1435. args[1+i] = key
  1436. }
  1437. args[len(args)-1] = formatSec(timeout)
  1438. cmd := NewZWithKeyCmd(args...)
  1439. cmd.setReadTimeout(timeout)
  1440. c.process(cmd)
  1441. return cmd
  1442. }
  1443. func (c *cmdable) zAdd(a []interface{}, n int, members ...Z) *IntCmd {
  1444. for i, m := range members {
  1445. a[n+2*i] = m.Score
  1446. a[n+2*i+1] = m.Member
  1447. }
  1448. cmd := NewIntCmd(a...)
  1449. c.process(cmd)
  1450. return cmd
  1451. }
  1452. // Redis `ZADD key score member [score member ...]` command.
  1453. func (c *cmdable) ZAdd(key string, members ...Z) *IntCmd {
  1454. const n = 2
  1455. a := make([]interface{}, n+2*len(members))
  1456. a[0], a[1] = "zadd", key
  1457. return c.zAdd(a, n, members...)
  1458. }
  1459. // Redis `ZADD key NX score member [score member ...]` command.
  1460. func (c *cmdable) ZAddNX(key string, members ...Z) *IntCmd {
  1461. const n = 3
  1462. a := make([]interface{}, n+2*len(members))
  1463. a[0], a[1], a[2] = "zadd", key, "nx"
  1464. return c.zAdd(a, n, members...)
  1465. }
  1466. // Redis `ZADD key XX score member [score member ...]` command.
  1467. func (c *cmdable) ZAddXX(key string, members ...Z) *IntCmd {
  1468. const n = 3
  1469. a := make([]interface{}, n+2*len(members))
  1470. a[0], a[1], a[2] = "zadd", key, "xx"
  1471. return c.zAdd(a, n, members...)
  1472. }
  1473. // Redis `ZADD key CH score member [score member ...]` command.
  1474. func (c *cmdable) ZAddCh(key string, members ...Z) *IntCmd {
  1475. const n = 3
  1476. a := make([]interface{}, n+2*len(members))
  1477. a[0], a[1], a[2] = "zadd", key, "ch"
  1478. return c.zAdd(a, n, members...)
  1479. }
  1480. // Redis `ZADD key NX CH score member [score member ...]` command.
  1481. func (c *cmdable) ZAddNXCh(key string, members ...Z) *IntCmd {
  1482. const n = 4
  1483. a := make([]interface{}, n+2*len(members))
  1484. a[0], a[1], a[2], a[3] = "zadd", key, "nx", "ch"
  1485. return c.zAdd(a, n, members...)
  1486. }
  1487. // Redis `ZADD key XX CH score member [score member ...]` command.
  1488. func (c *cmdable) ZAddXXCh(key string, members ...Z) *IntCmd {
  1489. const n = 4
  1490. a := make([]interface{}, n+2*len(members))
  1491. a[0], a[1], a[2], a[3] = "zadd", key, "xx", "ch"
  1492. return c.zAdd(a, n, members...)
  1493. }
  1494. func (c *cmdable) zIncr(a []interface{}, n int, members ...Z) *FloatCmd {
  1495. for i, m := range members {
  1496. a[n+2*i] = m.Score
  1497. a[n+2*i+1] = m.Member
  1498. }
  1499. cmd := NewFloatCmd(a...)
  1500. c.process(cmd)
  1501. return cmd
  1502. }
  1503. // Redis `ZADD key INCR score member` command.
  1504. func (c *cmdable) ZIncr(key string, member Z) *FloatCmd {
  1505. const n = 3
  1506. a := make([]interface{}, n+2)
  1507. a[0], a[1], a[2] = "zadd", key, "incr"
  1508. return c.zIncr(a, n, member)
  1509. }
  1510. // Redis `ZADD key NX INCR score member` command.
  1511. func (c *cmdable) ZIncrNX(key string, member Z) *FloatCmd {
  1512. const n = 4
  1513. a := make([]interface{}, n+2)
  1514. a[0], a[1], a[2], a[3] = "zadd", key, "incr", "nx"
  1515. return c.zIncr(a, n, member)
  1516. }
  1517. // Redis `ZADD key XX INCR score member` command.
  1518. func (c *cmdable) ZIncrXX(key string, member Z) *FloatCmd {
  1519. const n = 4
  1520. a := make([]interface{}, n+2)
  1521. a[0], a[1], a[2], a[3] = "zadd", key, "incr", "xx"
  1522. return c.zIncr(a, n, member)
  1523. }
  1524. func (c *cmdable) ZCard(key string) *IntCmd {
  1525. cmd := NewIntCmd("zcard", key)
  1526. c.process(cmd)
  1527. return cmd
  1528. }
  1529. func (c *cmdable) ZCount(key, min, max string) *IntCmd {
  1530. cmd := NewIntCmd("zcount", key, min, max)
  1531. c.process(cmd)
  1532. return cmd
  1533. }
  1534. func (c *cmdable) ZLexCount(key, min, max string) *IntCmd {
  1535. cmd := NewIntCmd("zlexcount", key, min, max)
  1536. c.process(cmd)
  1537. return cmd
  1538. }
  1539. func (c *cmdable) ZIncrBy(key string, increment float64, member string) *FloatCmd {
  1540. cmd := NewFloatCmd("zincrby", key, increment, member)
  1541. c.process(cmd)
  1542. return cmd
  1543. }
  1544. func (c *cmdable) ZInterStore(destination string, store ZStore, keys ...string) *IntCmd {
  1545. args := make([]interface{}, 3+len(keys))
  1546. args[0] = "zinterstore"
  1547. args[1] = destination
  1548. args[2] = len(keys)
  1549. for i, key := range keys {
  1550. args[3+i] = key
  1551. }
  1552. if len(store.Weights) > 0 {
  1553. args = append(args, "weights")
  1554. for _, weight := range store.Weights {
  1555. args = append(args, weight)
  1556. }
  1557. }
  1558. if store.Aggregate != "" {
  1559. args = append(args, "aggregate", store.Aggregate)
  1560. }
  1561. cmd := NewIntCmd(args...)
  1562. c.process(cmd)
  1563. return cmd
  1564. }
  1565. func (c *cmdable) ZPopMax(key string, count ...int64) *ZSliceCmd {
  1566. args := []interface{}{
  1567. "zpopmax",
  1568. key,
  1569. }
  1570. switch len(count) {
  1571. case 0:
  1572. break
  1573. case 1:
  1574. args = append(args, count[0])
  1575. default:
  1576. panic("too many arguments")
  1577. }
  1578. cmd := NewZSliceCmd(args...)
  1579. c.process(cmd)
  1580. return cmd
  1581. }
  1582. func (c *cmdable) ZPopMin(key string, count ...int64) *ZSliceCmd {
  1583. args := []interface{}{
  1584. "zpopmin",
  1585. key,
  1586. }
  1587. switch len(count) {
  1588. case 0:
  1589. break
  1590. case 1:
  1591. args = append(args, count[0])
  1592. default:
  1593. panic("too many arguments")
  1594. }
  1595. cmd := NewZSliceCmd(args...)
  1596. c.process(cmd)
  1597. return cmd
  1598. }
  1599. func (c *cmdable) zRange(key string, start, stop int64, withScores bool) *StringSliceCmd {
  1600. args := []interface{}{
  1601. "zrange",
  1602. key,
  1603. start,
  1604. stop,
  1605. }
  1606. if withScores {
  1607. args = append(args, "withscores")
  1608. }
  1609. cmd := NewStringSliceCmd(args...)
  1610. c.process(cmd)
  1611. return cmd
  1612. }
  1613. func (c *cmdable) ZRange(key string, start, stop int64) *StringSliceCmd {
  1614. return c.zRange(key, start, stop, false)
  1615. }
  1616. func (c *cmdable) ZRangeWithScores(key string, start, stop int64) *ZSliceCmd {
  1617. cmd := NewZSliceCmd("zrange", key, start, stop, "withscores")
  1618. c.process(cmd)
  1619. return cmd
  1620. }
  1621. type ZRangeBy struct {
  1622. Min, Max string
  1623. Offset, Count int64
  1624. }
  1625. func (c *cmdable) zRangeBy(zcmd, key string, opt ZRangeBy, withScores bool) *StringSliceCmd {
  1626. args := []interface{}{zcmd, key, opt.Min, opt.Max}
  1627. if withScores {
  1628. args = append(args, "withscores")
  1629. }
  1630. if opt.Offset != 0 || opt.Count != 0 {
  1631. args = append(
  1632. args,
  1633. "limit",
  1634. opt.Offset,
  1635. opt.Count,
  1636. )
  1637. }
  1638. cmd := NewStringSliceCmd(args...)
  1639. c.process(cmd)
  1640. return cmd
  1641. }
  1642. func (c *cmdable) ZRangeByScore(key string, opt ZRangeBy) *StringSliceCmd {
  1643. return c.zRangeBy("zrangebyscore", key, opt, false)
  1644. }
  1645. func (c *cmdable) ZRangeByLex(key string, opt ZRangeBy) *StringSliceCmd {
  1646. return c.zRangeBy("zrangebylex", key, opt, false)
  1647. }
  1648. func (c *cmdable) ZRangeByScoreWithScores(key string, opt ZRangeBy) *ZSliceCmd {
  1649. args := []interface{}{"zrangebyscore", key, opt.Min, opt.Max, "withscores"}
  1650. if opt.Offset != 0 || opt.Count != 0 {
  1651. args = append(
  1652. args,
  1653. "limit",
  1654. opt.Offset,
  1655. opt.Count,
  1656. )
  1657. }
  1658. cmd := NewZSliceCmd(args...)
  1659. c.process(cmd)
  1660. return cmd
  1661. }
  1662. func (c *cmdable) ZRank(key, member string) *IntCmd {
  1663. cmd := NewIntCmd("zrank", key, member)
  1664. c.process(cmd)
  1665. return cmd
  1666. }
  1667. func (c *cmdable) ZRem(key string, members ...interface{}) *IntCmd {
  1668. args := make([]interface{}, 2, 2+len(members))
  1669. args[0] = "zrem"
  1670. args[1] = key
  1671. args = appendArgs(args, members)
  1672. cmd := NewIntCmd(args...)
  1673. c.process(cmd)
  1674. return cmd
  1675. }
  1676. func (c *cmdable) ZRemRangeByRank(key string, start, stop int64) *IntCmd {
  1677. cmd := NewIntCmd(
  1678. "zremrangebyrank",
  1679. key,
  1680. start,
  1681. stop,
  1682. )
  1683. c.process(cmd)
  1684. return cmd
  1685. }
  1686. func (c *cmdable) ZRemRangeByScore(key, min, max string) *IntCmd {
  1687. cmd := NewIntCmd("zremrangebyscore", key, min, max)
  1688. c.process(cmd)
  1689. return cmd
  1690. }
  1691. func (c *cmdable) ZRemRangeByLex(key, min, max string) *IntCmd {
  1692. cmd := NewIntCmd("zremrangebylex", key, min, max)
  1693. c.process(cmd)
  1694. return cmd
  1695. }
  1696. func (c *cmdable) ZRevRange(key string, start, stop int64) *StringSliceCmd {
  1697. cmd := NewStringSliceCmd("zrevrange", key, start, stop)
  1698. c.process(cmd)
  1699. return cmd
  1700. }
  1701. func (c *cmdable) ZRevRangeWithScores(key string, start, stop int64) *ZSliceCmd {
  1702. cmd := NewZSliceCmd("zrevrange", key, start, stop, "withscores")
  1703. c.process(cmd)
  1704. return cmd
  1705. }
  1706. func (c *cmdable) zRevRangeBy(zcmd, key string, opt ZRangeBy) *StringSliceCmd {
  1707. args := []interface{}{zcmd, key, opt.Max, opt.Min}
  1708. if opt.Offset != 0 || opt.Count != 0 {
  1709. args = append(
  1710. args,
  1711. "limit",
  1712. opt.Offset,
  1713. opt.Count,
  1714. )
  1715. }
  1716. cmd := NewStringSliceCmd(args...)
  1717. c.process(cmd)
  1718. return cmd
  1719. }
  1720. func (c *cmdable) ZRevRangeByScore(key string, opt ZRangeBy) *StringSliceCmd {
  1721. return c.zRevRangeBy("zrevrangebyscore", key, opt)
  1722. }
  1723. func (c *cmdable) ZRevRangeByLex(key string, opt ZRangeBy) *StringSliceCmd {
  1724. return c.zRevRangeBy("zrevrangebylex", key, opt)
  1725. }
  1726. func (c *cmdable) ZRevRangeByScoreWithScores(key string, opt ZRangeBy) *ZSliceCmd {
  1727. args := []interface{}{"zrevrangebyscore", key, opt.Max, opt.Min, "withscores"}
  1728. if opt.Offset != 0 || opt.Count != 0 {
  1729. args = append(
  1730. args,
  1731. "limit",
  1732. opt.Offset,
  1733. opt.Count,
  1734. )
  1735. }
  1736. cmd := NewZSliceCmd(args...)
  1737. c.process(cmd)
  1738. return cmd
  1739. }
  1740. func (c *cmdable) ZRevRank(key, member string) *IntCmd {
  1741. cmd := NewIntCmd("zrevrank", key, member)
  1742. c.process(cmd)
  1743. return cmd
  1744. }
  1745. func (c *cmdable) ZScore(key, member string) *FloatCmd {
  1746. cmd := NewFloatCmd("zscore", key, member)
  1747. c.process(cmd)
  1748. return cmd
  1749. }
  1750. func (c *cmdable) ZUnionStore(dest string, store ZStore, keys ...string) *IntCmd {
  1751. args := make([]interface{}, 3+len(keys))
  1752. args[0] = "zunionstore"
  1753. args[1] = dest
  1754. args[2] = len(keys)
  1755. for i, key := range keys {
  1756. args[3+i] = key
  1757. }
  1758. if len(store.Weights) > 0 {
  1759. args = append(args, "weights")
  1760. for _, weight := range store.Weights {
  1761. args = append(args, weight)
  1762. }
  1763. }
  1764. if store.Aggregate != "" {
  1765. args = append(args, "aggregate", store.Aggregate)
  1766. }
  1767. cmd := NewIntCmd(args...)
  1768. c.process(cmd)
  1769. return cmd
  1770. }
  1771. //------------------------------------------------------------------------------
  1772. func (c *cmdable) PFAdd(key string, els ...interface{}) *IntCmd {
  1773. args := make([]interface{}, 2, 2+len(els))
  1774. args[0] = "pfadd"
  1775. args[1] = key
  1776. args = appendArgs(args, els)
  1777. cmd := NewIntCmd(args...)
  1778. c.process(cmd)
  1779. return cmd
  1780. }
  1781. func (c *cmdable) PFCount(keys ...string) *IntCmd {
  1782. args := make([]interface{}, 1+len(keys))
  1783. args[0] = "pfcount"
  1784. for i, key := range keys {
  1785. args[1+i] = key
  1786. }
  1787. cmd := NewIntCmd(args...)
  1788. c.process(cmd)
  1789. return cmd
  1790. }
  1791. func (c *cmdable) PFMerge(dest string, keys ...string) *StatusCmd {
  1792. args := make([]interface{}, 2+len(keys))
  1793. args[0] = "pfmerge"
  1794. args[1] = dest
  1795. for i, key := range keys {
  1796. args[2+i] = key
  1797. }
  1798. cmd := NewStatusCmd(args...)
  1799. c.process(cmd)
  1800. return cmd
  1801. }
  1802. //------------------------------------------------------------------------------
  1803. func (c *cmdable) BgRewriteAOF() *StatusCmd {
  1804. cmd := NewStatusCmd("bgrewriteaof")
  1805. c.process(cmd)
  1806. return cmd
  1807. }
  1808. func (c *cmdable) BgSave() *StatusCmd {
  1809. cmd := NewStatusCmd("bgsave")
  1810. c.process(cmd)
  1811. return cmd
  1812. }
  1813. func (c *cmdable) ClientKill(ipPort string) *StatusCmd {
  1814. cmd := NewStatusCmd("client", "kill", ipPort)
  1815. c.process(cmd)
  1816. return cmd
  1817. }
  1818. // ClientKillByFilter is new style synx, while the ClientKill is old
  1819. // CLIENT KILL <option> [value] ... <option> [value]
  1820. func (c *cmdable) ClientKillByFilter(keys ...string) *IntCmd {
  1821. args := make([]interface{}, 2+len(keys))
  1822. args[0] = "client"
  1823. args[1] = "kill"
  1824. for i, key := range keys {
  1825. args[2+i] = key
  1826. }
  1827. cmd := NewIntCmd(args...)
  1828. c.process(cmd)
  1829. return cmd
  1830. }
  1831. func (c *cmdable) ClientList() *StringCmd {
  1832. cmd := NewStringCmd("client", "list")
  1833. c.process(cmd)
  1834. return cmd
  1835. }
  1836. func (c *cmdable) ClientPause(dur time.Duration) *BoolCmd {
  1837. cmd := NewBoolCmd("client", "pause", formatMs(dur))
  1838. c.process(cmd)
  1839. return cmd
  1840. }
  1841. func (c *cmdable) ClientID() *IntCmd {
  1842. cmd := NewIntCmd("client", "id")
  1843. c.process(cmd)
  1844. return cmd
  1845. }
  1846. func (c *cmdable) ClientUnblock(id int64) *IntCmd {
  1847. cmd := NewIntCmd("client", "unblock", id)
  1848. c.process(cmd)
  1849. return cmd
  1850. }
  1851. func (c *cmdable) ClientUnblockWithError(id int64) *IntCmd {
  1852. cmd := NewIntCmd("client", "unblock", id, "error")
  1853. c.process(cmd)
  1854. return cmd
  1855. }
  1856. // ClientSetName assigns a name to the connection.
  1857. func (c *statefulCmdable) ClientSetName(name string) *BoolCmd {
  1858. cmd := NewBoolCmd("client", "setname", name)
  1859. c.process(cmd)
  1860. return cmd
  1861. }
  1862. // ClientGetName returns the name of the connection.
  1863. func (c *cmdable) ClientGetName() *StringCmd {
  1864. cmd := NewStringCmd("client", "getname")
  1865. c.process(cmd)
  1866. return cmd
  1867. }
  1868. func (c *cmdable) ConfigGet(parameter string) *SliceCmd {
  1869. cmd := NewSliceCmd("config", "get", parameter)
  1870. c.process(cmd)
  1871. return cmd
  1872. }
  1873. func (c *cmdable) ConfigResetStat() *StatusCmd {
  1874. cmd := NewStatusCmd("config", "resetstat")
  1875. c.process(cmd)
  1876. return cmd
  1877. }
  1878. func (c *cmdable) ConfigSet(parameter, value string) *StatusCmd {
  1879. cmd := NewStatusCmd("config", "set", parameter, value)
  1880. c.process(cmd)
  1881. return cmd
  1882. }
  1883. func (c *cmdable) ConfigRewrite() *StatusCmd {
  1884. cmd := NewStatusCmd("config", "rewrite")
  1885. c.process(cmd)
  1886. return cmd
  1887. }
  1888. // Deperecated. Use DBSize instead.
  1889. func (c *cmdable) DbSize() *IntCmd {
  1890. return c.DBSize()
  1891. }
  1892. func (c *cmdable) DBSize() *IntCmd {
  1893. cmd := NewIntCmd("dbsize")
  1894. c.process(cmd)
  1895. return cmd
  1896. }
  1897. func (c *cmdable) FlushAll() *StatusCmd {
  1898. cmd := NewStatusCmd("flushall")
  1899. c.process(cmd)
  1900. return cmd
  1901. }
  1902. func (c *cmdable) FlushAllAsync() *StatusCmd {
  1903. cmd := NewStatusCmd("flushall", "async")
  1904. c.process(cmd)
  1905. return cmd
  1906. }
  1907. // Deprecated. Use FlushDB instead.
  1908. func (c *cmdable) FlushDb() *StatusCmd {
  1909. return c.FlushDB()
  1910. }
  1911. func (c *cmdable) FlushDB() *StatusCmd {
  1912. cmd := NewStatusCmd("flushdb")
  1913. c.process(cmd)
  1914. return cmd
  1915. }
  1916. func (c *cmdable) FlushDBAsync() *StatusCmd {
  1917. cmd := NewStatusCmd("flushdb", "async")
  1918. c.process(cmd)
  1919. return cmd
  1920. }
  1921. func (c *cmdable) Info(section ...string) *StringCmd {
  1922. args := []interface{}{"info"}
  1923. if len(section) > 0 {
  1924. args = append(args, section[0])
  1925. }
  1926. cmd := NewStringCmd(args...)
  1927. c.process(cmd)
  1928. return cmd
  1929. }
  1930. func (c *cmdable) LastSave() *IntCmd {
  1931. cmd := NewIntCmd("lastsave")
  1932. c.process(cmd)
  1933. return cmd
  1934. }
  1935. func (c *cmdable) Save() *StatusCmd {
  1936. cmd := NewStatusCmd("save")
  1937. c.process(cmd)
  1938. return cmd
  1939. }
  1940. func (c *cmdable) shutdown(modifier string) *StatusCmd {
  1941. var args []interface{}
  1942. if modifier == "" {
  1943. args = []interface{}{"shutdown"}
  1944. } else {
  1945. args = []interface{}{"shutdown", modifier}
  1946. }
  1947. cmd := NewStatusCmd(args...)
  1948. c.process(cmd)
  1949. if err := cmd.Err(); err != nil {
  1950. if err == io.EOF {
  1951. // Server quit as expected.
  1952. cmd.err = nil
  1953. }
  1954. } else {
  1955. // Server did not quit. String reply contains the reason.
  1956. cmd.err = errors.New(cmd.val)
  1957. cmd.val = ""
  1958. }
  1959. return cmd
  1960. }
  1961. func (c *cmdable) Shutdown() *StatusCmd {
  1962. return c.shutdown("")
  1963. }
  1964. func (c *cmdable) ShutdownSave() *StatusCmd {
  1965. return c.shutdown("save")
  1966. }
  1967. func (c *cmdable) ShutdownNoSave() *StatusCmd {
  1968. return c.shutdown("nosave")
  1969. }
  1970. func (c *cmdable) SlaveOf(host, port string) *StatusCmd {
  1971. cmd := NewStatusCmd("slaveof", host, port)
  1972. c.process(cmd)
  1973. return cmd
  1974. }
  1975. func (c *cmdable) SlowLog() {
  1976. panic("not implemented")
  1977. }
  1978. func (c *cmdable) Sync() {
  1979. panic("not implemented")
  1980. }
  1981. func (c *cmdable) Time() *TimeCmd {
  1982. cmd := NewTimeCmd("time")
  1983. c.process(cmd)
  1984. return cmd
  1985. }
  1986. //------------------------------------------------------------------------------
  1987. func (c *cmdable) Eval(script string, keys []string, args ...interface{}) *Cmd {
  1988. cmdArgs := make([]interface{}, 3+len(keys), 3+len(keys)+len(args))
  1989. cmdArgs[0] = "eval"
  1990. cmdArgs[1] = script
  1991. cmdArgs[2] = len(keys)
  1992. for i, key := range keys {
  1993. cmdArgs[3+i] = key
  1994. }
  1995. cmdArgs = appendArgs(cmdArgs, args)
  1996. cmd := NewCmd(cmdArgs...)
  1997. c.process(cmd)
  1998. return cmd
  1999. }
  2000. func (c *cmdable) EvalSha(sha1 string, keys []string, args ...interface{}) *Cmd {
  2001. cmdArgs := make([]interface{}, 3+len(keys), 3+len(keys)+len(args))
  2002. cmdArgs[0] = "evalsha"
  2003. cmdArgs[1] = sha1
  2004. cmdArgs[2] = len(keys)
  2005. for i, key := range keys {
  2006. cmdArgs[3+i] = key
  2007. }
  2008. cmdArgs = appendArgs(cmdArgs, args)
  2009. cmd := NewCmd(cmdArgs...)
  2010. c.process(cmd)
  2011. return cmd
  2012. }
  2013. func (c *cmdable) ScriptExists(hashes ...string) *BoolSliceCmd {
  2014. args := make([]interface{}, 2+len(hashes))
  2015. args[0] = "script"
  2016. args[1] = "exists"
  2017. for i, hash := range hashes {
  2018. args[2+i] = hash
  2019. }
  2020. cmd := NewBoolSliceCmd(args...)
  2021. c.process(cmd)
  2022. return cmd
  2023. }
  2024. func (c *cmdable) ScriptFlush() *StatusCmd {
  2025. cmd := NewStatusCmd("script", "flush")
  2026. c.process(cmd)
  2027. return cmd
  2028. }
  2029. func (c *cmdable) ScriptKill() *StatusCmd {
  2030. cmd := NewStatusCmd("script", "kill")
  2031. c.process(cmd)
  2032. return cmd
  2033. }
  2034. func (c *cmdable) ScriptLoad(script string) *StringCmd {
  2035. cmd := NewStringCmd("script", "load", script)
  2036. c.process(cmd)
  2037. return cmd
  2038. }
  2039. //------------------------------------------------------------------------------
  2040. func (c *cmdable) DebugObject(key string) *StringCmd {
  2041. cmd := NewStringCmd("debug", "object", key)
  2042. c.process(cmd)
  2043. return cmd
  2044. }
  2045. //------------------------------------------------------------------------------
  2046. // Publish posts the message to the channel.
  2047. func (c *cmdable) Publish(channel string, message interface{}) *IntCmd {
  2048. cmd := NewIntCmd("publish", channel, message)
  2049. c.process(cmd)
  2050. return cmd
  2051. }
  2052. func (c *cmdable) PubSubChannels(pattern string) *StringSliceCmd {
  2053. args := []interface{}{"pubsub", "channels"}
  2054. if pattern != "*" {
  2055. args = append(args, pattern)
  2056. }
  2057. cmd := NewStringSliceCmd(args...)
  2058. c.process(cmd)
  2059. return cmd
  2060. }
  2061. func (c *cmdable) PubSubNumSub(channels ...string) *StringIntMapCmd {
  2062. args := make([]interface{}, 2+len(channels))
  2063. args[0] = "pubsub"
  2064. args[1] = "numsub"
  2065. for i, channel := range channels {
  2066. args[2+i] = channel
  2067. }
  2068. cmd := NewStringIntMapCmd(args...)
  2069. c.process(cmd)
  2070. return cmd
  2071. }
  2072. func (c *cmdable) PubSubNumPat() *IntCmd {
  2073. cmd := NewIntCmd("pubsub", "numpat")
  2074. c.process(cmd)
  2075. return cmd
  2076. }
  2077. //------------------------------------------------------------------------------
  2078. func (c *cmdable) ClusterSlots() *ClusterSlotsCmd {
  2079. cmd := NewClusterSlotsCmd("cluster", "slots")
  2080. c.process(cmd)
  2081. return cmd
  2082. }
  2083. func (c *cmdable) ClusterNodes() *StringCmd {
  2084. cmd := NewStringCmd("cluster", "nodes")
  2085. c.process(cmd)
  2086. return cmd
  2087. }
  2088. func (c *cmdable) ClusterMeet(host, port string) *StatusCmd {
  2089. cmd := NewStatusCmd("cluster", "meet", host, port)
  2090. c.process(cmd)
  2091. return cmd
  2092. }
  2093. func (c *cmdable) ClusterForget(nodeID string) *StatusCmd {
  2094. cmd := NewStatusCmd("cluster", "forget", nodeID)
  2095. c.process(cmd)
  2096. return cmd
  2097. }
  2098. func (c *cmdable) ClusterReplicate(nodeID string) *StatusCmd {
  2099. cmd := NewStatusCmd("cluster", "replicate", nodeID)
  2100. c.process(cmd)
  2101. return cmd
  2102. }
  2103. func (c *cmdable) ClusterResetSoft() *StatusCmd {
  2104. cmd := NewStatusCmd("cluster", "reset", "soft")
  2105. c.process(cmd)
  2106. return cmd
  2107. }
  2108. func (c *cmdable) ClusterResetHard() *StatusCmd {
  2109. cmd := NewStatusCmd("cluster", "reset", "hard")
  2110. c.process(cmd)
  2111. return cmd
  2112. }
  2113. func (c *cmdable) ClusterInfo() *StringCmd {
  2114. cmd := NewStringCmd("cluster", "info")
  2115. c.process(cmd)
  2116. return cmd
  2117. }
  2118. func (c *cmdable) ClusterKeySlot(key string) *IntCmd {
  2119. cmd := NewIntCmd("cluster", "keyslot", key)
  2120. c.process(cmd)
  2121. return cmd
  2122. }
  2123. func (c *cmdable) ClusterGetKeysInSlot(slot int, count int) *StringSliceCmd {
  2124. cmd := NewStringSliceCmd("cluster", "getkeysinslot", slot, count)
  2125. c.process(cmd)
  2126. return cmd
  2127. }
  2128. func (c *cmdable) ClusterCountFailureReports(nodeID string) *IntCmd {
  2129. cmd := NewIntCmd("cluster", "count-failure-reports", nodeID)
  2130. c.process(cmd)
  2131. return cmd
  2132. }
  2133. func (c *cmdable) ClusterCountKeysInSlot(slot int) *IntCmd {
  2134. cmd := NewIntCmd("cluster", "countkeysinslot", slot)
  2135. c.process(cmd)
  2136. return cmd
  2137. }
  2138. func (c *cmdable) ClusterDelSlots(slots ...int) *StatusCmd {
  2139. args := make([]interface{}, 2+len(slots))
  2140. args[0] = "cluster"
  2141. args[1] = "delslots"
  2142. for i, slot := range slots {
  2143. args[2+i] = slot
  2144. }
  2145. cmd := NewStatusCmd(args...)
  2146. c.process(cmd)
  2147. return cmd
  2148. }
  2149. func (c *cmdable) ClusterDelSlotsRange(min, max int) *StatusCmd {
  2150. size := max - min + 1
  2151. slots := make([]int, size)
  2152. for i := 0; i < size; i++ {
  2153. slots[i] = min + i
  2154. }
  2155. return c.ClusterDelSlots(slots...)
  2156. }
  2157. func (c *cmdable) ClusterSaveConfig() *StatusCmd {
  2158. cmd := NewStatusCmd("cluster", "saveconfig")
  2159. c.process(cmd)
  2160. return cmd
  2161. }
  2162. func (c *cmdable) ClusterSlaves(nodeID string) *StringSliceCmd {
  2163. cmd := NewStringSliceCmd("cluster", "slaves", nodeID)
  2164. c.process(cmd)
  2165. return cmd
  2166. }
  2167. func (c *cmdable) ReadOnly() *StatusCmd {
  2168. cmd := NewStatusCmd("readonly")
  2169. c.process(cmd)
  2170. return cmd
  2171. }
  2172. func (c *cmdable) ReadWrite() *StatusCmd {
  2173. cmd := NewStatusCmd("readwrite")
  2174. c.process(cmd)
  2175. return cmd
  2176. }
  2177. func (c *cmdable) ClusterFailover() *StatusCmd {
  2178. cmd := NewStatusCmd("cluster", "failover")
  2179. c.process(cmd)
  2180. return cmd
  2181. }
  2182. func (c *cmdable) ClusterAddSlots(slots ...int) *StatusCmd {
  2183. args := make([]interface{}, 2+len(slots))
  2184. args[0] = "cluster"
  2185. args[1] = "addslots"
  2186. for i, num := range slots {
  2187. args[2+i] = num
  2188. }
  2189. cmd := NewStatusCmd(args...)
  2190. c.process(cmd)
  2191. return cmd
  2192. }
  2193. func (c *cmdable) ClusterAddSlotsRange(min, max int) *StatusCmd {
  2194. size := max - min + 1
  2195. slots := make([]int, size)
  2196. for i := 0; i < size; i++ {
  2197. slots[i] = min + i
  2198. }
  2199. return c.ClusterAddSlots(slots...)
  2200. }
  2201. //------------------------------------------------------------------------------
  2202. func (c *cmdable) GeoAdd(key string, geoLocation ...*GeoLocation) *IntCmd {
  2203. args := make([]interface{}, 2+3*len(geoLocation))
  2204. args[0] = "geoadd"
  2205. args[1] = key
  2206. for i, eachLoc := range geoLocation {
  2207. args[2+3*i] = eachLoc.Longitude
  2208. args[2+3*i+1] = eachLoc.Latitude
  2209. args[2+3*i+2] = eachLoc.Name
  2210. }
  2211. cmd := NewIntCmd(args...)
  2212. c.process(cmd)
  2213. return cmd
  2214. }
  2215. func (c *cmdable) GeoRadius(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd {
  2216. cmd := NewGeoLocationCmd(query, "georadius", key, longitude, latitude)
  2217. c.process(cmd)
  2218. return cmd
  2219. }
  2220. func (c *cmdable) GeoRadiusRO(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd {
  2221. cmd := NewGeoLocationCmd(query, "georadius_ro", key, longitude, latitude)
  2222. c.process(cmd)
  2223. return cmd
  2224. }
  2225. func (c *cmdable) GeoRadiusByMember(key, member string, query *GeoRadiusQuery) *GeoLocationCmd {
  2226. cmd := NewGeoLocationCmd(query, "georadiusbymember", key, member)
  2227. c.process(cmd)
  2228. return cmd
  2229. }
  2230. func (c *cmdable) GeoRadiusByMemberRO(key, member string, query *GeoRadiusQuery) *GeoLocationCmd {
  2231. cmd := NewGeoLocationCmd(query, "georadiusbymember_ro", key, member)
  2232. c.process(cmd)
  2233. return cmd
  2234. }
  2235. func (c *cmdable) GeoDist(key string, member1, member2, unit string) *FloatCmd {
  2236. if unit == "" {
  2237. unit = "km"
  2238. }
  2239. cmd := NewFloatCmd("geodist", key, member1, member2, unit)
  2240. c.process(cmd)
  2241. return cmd
  2242. }
  2243. func (c *cmdable) GeoHash(key string, members ...string) *StringSliceCmd {
  2244. args := make([]interface{}, 2+len(members))
  2245. args[0] = "geohash"
  2246. args[1] = key
  2247. for i, member := range members {
  2248. args[2+i] = member
  2249. }
  2250. cmd := NewStringSliceCmd(args...)
  2251. c.process(cmd)
  2252. return cmd
  2253. }
  2254. func (c *cmdable) GeoPos(key string, members ...string) *GeoPosCmd {
  2255. args := make([]interface{}, 2+len(members))
  2256. args[0] = "geopos"
  2257. args[1] = key
  2258. for i, member := range members {
  2259. args[2+i] = member
  2260. }
  2261. cmd := NewGeoPosCmd(args...)
  2262. c.process(cmd)
  2263. return cmd
  2264. }
  2265. //------------------------------------------------------------------------------
  2266. func (c *cmdable) MemoryUsage(key string, samples ...int) *IntCmd {
  2267. args := []interface{}{"memory", "usage", key}
  2268. if len(samples) > 0 {
  2269. if len(samples) != 1 {
  2270. panic("MemoryUsage expects single sample count")
  2271. }
  2272. args = append(args, "SAMPLES", samples[0])
  2273. }
  2274. cmd := NewIntCmd(args...)
  2275. c.process(cmd)
  2276. return cmd
  2277. }
上海开阖软件有限公司 沪ICP备12045867号-1