1 package redis
2
3 import (
4 "context"
5 "strings"
6 "time"
7
8 "github.com/redis/go-redis/v9/internal/hashtag"
9 )
10
11 type SortedSetCmdable interface {
12 BZPopMax(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd
13 BZPopMin(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd
14 BZMPop(ctx context.Context, timeout time.Duration, order string, count int64, keys ...string) *ZSliceWithKeyCmd
15 ZAdd(ctx context.Context, key string, members ...Z) *IntCmd
16 ZAddLT(ctx context.Context, key string, members ...Z) *IntCmd
17 ZAddGT(ctx context.Context, key string, members ...Z) *IntCmd
18 ZAddNX(ctx context.Context, key string, members ...Z) *IntCmd
19 ZAddXX(ctx context.Context, key string, members ...Z) *IntCmd
20 ZAddArgs(ctx context.Context, key string, args ZAddArgs) *IntCmd
21 ZAddArgsIncr(ctx context.Context, key string, args ZAddArgs) *FloatCmd
22 ZCard(ctx context.Context, key string) *IntCmd
23 ZCount(ctx context.Context, key, min, max string) *IntCmd
24 ZLexCount(ctx context.Context, key, min, max string) *IntCmd
25 ZIncrBy(ctx context.Context, key string, increment float64, member string) *FloatCmd
26 ZInter(ctx context.Context, store *ZStore) *StringSliceCmd
27 ZInterWithScores(ctx context.Context, store *ZStore) *ZSliceCmd
28 ZInterCard(ctx context.Context, limit int64, keys ...string) *IntCmd
29 ZInterStore(ctx context.Context, destination string, store *ZStore) *IntCmd
30 ZMPop(ctx context.Context, order string, count int64, keys ...string) *ZSliceWithKeyCmd
31 ZMScore(ctx context.Context, key string, members ...string) *FloatSliceCmd
32 ZPopMax(ctx context.Context, key string, count ...int64) *ZSliceCmd
33 ZPopMin(ctx context.Context, key string, count ...int64) *ZSliceCmd
34 ZRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd
35 ZRangeWithScores(ctx context.Context, key string, start, stop int64) *ZSliceCmd
36 ZRangeByScore(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd
37 ZRangeByLex(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd
38 ZRangeByScoreWithScores(ctx context.Context, key string, opt *ZRangeBy) *ZSliceCmd
39 ZRangeArgs(ctx context.Context, z ZRangeArgs) *StringSliceCmd
40 ZRangeArgsWithScores(ctx context.Context, z ZRangeArgs) *ZSliceCmd
41 ZRangeStore(ctx context.Context, dst string, z ZRangeArgs) *IntCmd
42 ZRank(ctx context.Context, key, member string) *IntCmd
43 ZRankWithScore(ctx context.Context, key, member string) *RankWithScoreCmd
44 ZRem(ctx context.Context, key string, members ...interface{}) *IntCmd
45 ZRemRangeByRank(ctx context.Context, key string, start, stop int64) *IntCmd
46 ZRemRangeByScore(ctx context.Context, key, min, max string) *IntCmd
47 ZRemRangeByLex(ctx context.Context, key, min, max string) *IntCmd
48 ZRevRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd
49 ZRevRangeWithScores(ctx context.Context, key string, start, stop int64) *ZSliceCmd
50 ZRevRangeByScore(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd
51 ZRevRangeByLex(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd
52 ZRevRangeByScoreWithScores(ctx context.Context, key string, opt *ZRangeBy) *ZSliceCmd
53 ZRevRank(ctx context.Context, key, member string) *IntCmd
54 ZRevRankWithScore(ctx context.Context, key, member string) *RankWithScoreCmd
55 ZScore(ctx context.Context, key, member string) *FloatCmd
56 ZUnionStore(ctx context.Context, dest string, store *ZStore) *IntCmd
57 ZRandMember(ctx context.Context, key string, count int) *StringSliceCmd
58 ZRandMemberWithScores(ctx context.Context, key string, count int) *ZSliceCmd
59 ZUnion(ctx context.Context, store ZStore) *StringSliceCmd
60 ZUnionWithScores(ctx context.Context, store ZStore) *ZSliceCmd
61 ZDiff(ctx context.Context, keys ...string) *StringSliceCmd
62 ZDiffWithScores(ctx context.Context, keys ...string) *ZSliceCmd
63 ZDiffStore(ctx context.Context, destination string, keys ...string) *IntCmd
64 ZScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
65 }
66
67
68 func (c cmdable) BZPopMax(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd {
69 args := make([]interface{}, 1+len(keys)+1)
70 args[0] = "bzpopmax"
71 for i, key := range keys {
72 args[1+i] = key
73 }
74 args[len(args)-1] = formatSec(ctx, timeout)
75 cmd := NewZWithKeyCmd(ctx, args...)
76 cmd.setReadTimeout(timeout)
77 _ = c(ctx, cmd)
78 return cmd
79 }
80
81
82 func (c cmdable) BZPopMin(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd {
83 args := make([]interface{}, 1+len(keys)+1)
84 args[0] = "bzpopmin"
85 for i, key := range keys {
86 args[1+i] = key
87 }
88 args[len(args)-1] = formatSec(ctx, timeout)
89 cmd := NewZWithKeyCmd(ctx, args...)
90 cmd.setReadTimeout(timeout)
91 _ = c(ctx, cmd)
92 return cmd
93 }
94
95
96
97
98
99
100 func (c cmdable) BZMPop(ctx context.Context, timeout time.Duration, order string, count int64, keys ...string) *ZSliceWithKeyCmd {
101 args := make([]interface{}, 3+len(keys), 6+len(keys))
102 args[0] = "bzmpop"
103 args[1] = formatSec(ctx, timeout)
104 args[2] = len(keys)
105 for i, key := range keys {
106 args[3+i] = key
107 }
108 args = append(args, strings.ToLower(order), "count", count)
109 cmd := NewZSliceWithKeyCmd(ctx, args...)
110 cmd.setReadTimeout(timeout)
111 _ = c(ctx, cmd)
112 return cmd
113 }
114
115
116 type ZAddArgs struct {
117 NX bool
118 XX bool
119 LT bool
120 GT bool
121 Ch bool
122 Members []Z
123 }
124
125 func (c cmdable) zAddArgs(key string, args ZAddArgs, incr bool) []interface{} {
126 a := make([]interface{}, 0, 6+2*len(args.Members))
127 a = append(a, "zadd", key)
128
129
130 if args.NX {
131 a = append(a, "nx")
132 } else {
133 if args.XX {
134 a = append(a, "xx")
135 }
136 if args.GT {
137 a = append(a, "gt")
138 } else if args.LT {
139 a = append(a, "lt")
140 }
141 }
142 if args.Ch {
143 a = append(a, "ch")
144 }
145 if incr {
146 a = append(a, "incr")
147 }
148 for _, m := range args.Members {
149 a = append(a, m.Score)
150 a = append(a, m.Member)
151 }
152 return a
153 }
154
155 func (c cmdable) ZAddArgs(ctx context.Context, key string, args ZAddArgs) *IntCmd {
156 cmd := NewIntCmd(ctx, c.zAddArgs(key, args, false)...)
157 _ = c(ctx, cmd)
158 return cmd
159 }
160
161 func (c cmdable) ZAddArgsIncr(ctx context.Context, key string, args ZAddArgs) *FloatCmd {
162 cmd := NewFloatCmd(ctx, c.zAddArgs(key, args, true)...)
163 _ = c(ctx, cmd)
164 return cmd
165 }
166
167
168 func (c cmdable) ZAdd(ctx context.Context, key string, members ...Z) *IntCmd {
169 return c.ZAddArgs(ctx, key, ZAddArgs{
170 Members: members,
171 })
172 }
173
174
175 func (c cmdable) ZAddLT(ctx context.Context, key string, members ...Z) *IntCmd {
176 return c.ZAddArgs(ctx, key, ZAddArgs{
177 LT: true,
178 Members: members,
179 })
180 }
181
182
183 func (c cmdable) ZAddGT(ctx context.Context, key string, members ...Z) *IntCmd {
184 return c.ZAddArgs(ctx, key, ZAddArgs{
185 GT: true,
186 Members: members,
187 })
188 }
189
190
191 func (c cmdable) ZAddNX(ctx context.Context, key string, members ...Z) *IntCmd {
192 return c.ZAddArgs(ctx, key, ZAddArgs{
193 NX: true,
194 Members: members,
195 })
196 }
197
198
199 func (c cmdable) ZAddXX(ctx context.Context, key string, members ...Z) *IntCmd {
200 return c.ZAddArgs(ctx, key, ZAddArgs{
201 XX: true,
202 Members: members,
203 })
204 }
205
206 func (c cmdable) ZCard(ctx context.Context, key string) *IntCmd {
207 cmd := NewIntCmd(ctx, "zcard", key)
208 _ = c(ctx, cmd)
209 return cmd
210 }
211
212 func (c cmdable) ZCount(ctx context.Context, key, min, max string) *IntCmd {
213 cmd := NewIntCmd(ctx, "zcount", key, min, max)
214 _ = c(ctx, cmd)
215 return cmd
216 }
217
218 func (c cmdable) ZLexCount(ctx context.Context, key, min, max string) *IntCmd {
219 cmd := NewIntCmd(ctx, "zlexcount", key, min, max)
220 _ = c(ctx, cmd)
221 return cmd
222 }
223
224 func (c cmdable) ZIncrBy(ctx context.Context, key string, increment float64, member string) *FloatCmd {
225 cmd := NewFloatCmd(ctx, "zincrby", key, increment, member)
226 _ = c(ctx, cmd)
227 return cmd
228 }
229
230 func (c cmdable) ZInterStore(ctx context.Context, destination string, store *ZStore) *IntCmd {
231 args := make([]interface{}, 0, 3+store.len())
232 args = append(args, "zinterstore", destination, len(store.Keys))
233 args = store.appendArgs(args)
234 cmd := NewIntCmd(ctx, args...)
235 cmd.SetFirstKeyPos(3)
236 _ = c(ctx, cmd)
237 return cmd
238 }
239
240 func (c cmdable) ZInter(ctx context.Context, store *ZStore) *StringSliceCmd {
241 args := make([]interface{}, 0, 2+store.len())
242 args = append(args, "zinter", len(store.Keys))
243 args = store.appendArgs(args)
244 cmd := NewStringSliceCmd(ctx, args...)
245 cmd.SetFirstKeyPos(2)
246 _ = c(ctx, cmd)
247 return cmd
248 }
249
250 func (c cmdable) ZInterWithScores(ctx context.Context, store *ZStore) *ZSliceCmd {
251 args := make([]interface{}, 0, 3+store.len())
252 args = append(args, "zinter", len(store.Keys))
253 args = store.appendArgs(args)
254 args = append(args, "withscores")
255 cmd := NewZSliceCmd(ctx, args...)
256 cmd.SetFirstKeyPos(2)
257 _ = c(ctx, cmd)
258 return cmd
259 }
260
261 func (c cmdable) ZInterCard(ctx context.Context, limit int64, keys ...string) *IntCmd {
262 numKeys := len(keys)
263 args := make([]interface{}, 4+numKeys)
264 args[0] = "zintercard"
265 args[1] = numKeys
266 for i, key := range keys {
267 args[2+i] = key
268 }
269 args[2+numKeys] = "limit"
270 args[3+numKeys] = limit
271 cmd := NewIntCmd(ctx, args...)
272 _ = c(ctx, cmd)
273 return cmd
274 }
275
276
277
278
279 func (c cmdable) ZMPop(ctx context.Context, order string, count int64, keys ...string) *ZSliceWithKeyCmd {
280 args := make([]interface{}, 2+len(keys), 5+len(keys))
281 args[0] = "zmpop"
282 args[1] = len(keys)
283 for i, key := range keys {
284 args[2+i] = key
285 }
286 args = append(args, strings.ToLower(order), "count", count)
287 cmd := NewZSliceWithKeyCmd(ctx, args...)
288 _ = c(ctx, cmd)
289 return cmd
290 }
291
292 func (c cmdable) ZMScore(ctx context.Context, key string, members ...string) *FloatSliceCmd {
293 args := make([]interface{}, 2+len(members))
294 args[0] = "zmscore"
295 args[1] = key
296 for i, member := range members {
297 args[2+i] = member
298 }
299 cmd := NewFloatSliceCmd(ctx, args...)
300 _ = c(ctx, cmd)
301 return cmd
302 }
303
304 func (c cmdable) ZPopMax(ctx context.Context, key string, count ...int64) *ZSliceCmd {
305 args := []interface{}{
306 "zpopmax",
307 key,
308 }
309
310 switch len(count) {
311 case 0:
312 break
313 case 1:
314 args = append(args, count[0])
315 default:
316 panic("too many arguments")
317 }
318
319 cmd := NewZSliceCmd(ctx, args...)
320 _ = c(ctx, cmd)
321 return cmd
322 }
323
324 func (c cmdable) ZPopMin(ctx context.Context, key string, count ...int64) *ZSliceCmd {
325 args := []interface{}{
326 "zpopmin",
327 key,
328 }
329
330 switch len(count) {
331 case 0:
332 break
333 case 1:
334 args = append(args, count[0])
335 default:
336 panic("too many arguments")
337 }
338
339 cmd := NewZSliceCmd(ctx, args...)
340 _ = c(ctx, cmd)
341 return cmd
342 }
343
344
345
346
347
348
349
350
351
352
353
354
355
356 type ZRangeArgs struct {
357 Key string
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383 Start interface{}
384 Stop interface{}
385
386
387 ByScore bool
388 ByLex bool
389
390 Rev bool
391
392
393 Offset int64
394 Count int64
395 }
396
397 func (z ZRangeArgs) appendArgs(args []interface{}) []interface{} {
398
399 if z.Rev && (z.ByScore || z.ByLex) {
400 args = append(args, z.Key, z.Stop, z.Start)
401 } else {
402 args = append(args, z.Key, z.Start, z.Stop)
403 }
404
405 if z.ByScore {
406 args = append(args, "byscore")
407 } else if z.ByLex {
408 args = append(args, "bylex")
409 }
410 if z.Rev {
411 args = append(args, "rev")
412 }
413 if z.Offset != 0 || z.Count != 0 {
414 args = append(args, "limit", z.Offset, z.Count)
415 }
416 return args
417 }
418
419 func (c cmdable) ZRangeArgs(ctx context.Context, z ZRangeArgs) *StringSliceCmd {
420 args := make([]interface{}, 0, 9)
421 args = append(args, "zrange")
422 args = z.appendArgs(args)
423 cmd := NewStringSliceCmd(ctx, args...)
424 _ = c(ctx, cmd)
425 return cmd
426 }
427
428 func (c cmdable) ZRangeArgsWithScores(ctx context.Context, z ZRangeArgs) *ZSliceCmd {
429 args := make([]interface{}, 0, 10)
430 args = append(args, "zrange")
431 args = z.appendArgs(args)
432 args = append(args, "withscores")
433 cmd := NewZSliceCmd(ctx, args...)
434 _ = c(ctx, cmd)
435 return cmd
436 }
437
438 func (c cmdable) ZRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd {
439 return c.ZRangeArgs(ctx, ZRangeArgs{
440 Key: key,
441 Start: start,
442 Stop: stop,
443 })
444 }
445
446 func (c cmdable) ZRangeWithScores(ctx context.Context, key string, start, stop int64) *ZSliceCmd {
447 return c.ZRangeArgsWithScores(ctx, ZRangeArgs{
448 Key: key,
449 Start: start,
450 Stop: stop,
451 })
452 }
453
454 type ZRangeBy struct {
455 Min, Max string
456 Offset, Count int64
457 }
458
459 func (c cmdable) zRangeBy(ctx context.Context, zcmd, key string, opt *ZRangeBy, withScores bool) *StringSliceCmd {
460 args := []interface{}{zcmd, key, opt.Min, opt.Max}
461 if withScores {
462 args = append(args, "withscores")
463 }
464 if opt.Offset != 0 || opt.Count != 0 {
465 args = append(
466 args,
467 "limit",
468 opt.Offset,
469 opt.Count,
470 )
471 }
472 cmd := NewStringSliceCmd(ctx, args...)
473 _ = c(ctx, cmd)
474 return cmd
475 }
476
477 func (c cmdable) ZRangeByScore(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd {
478 return c.zRangeBy(ctx, "zrangebyscore", key, opt, false)
479 }
480
481 func (c cmdable) ZRangeByLex(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd {
482 return c.zRangeBy(ctx, "zrangebylex", key, opt, false)
483 }
484
485 func (c cmdable) ZRangeByScoreWithScores(ctx context.Context, key string, opt *ZRangeBy) *ZSliceCmd {
486 args := []interface{}{"zrangebyscore", key, opt.Min, opt.Max, "withscores"}
487 if opt.Offset != 0 || opt.Count != 0 {
488 args = append(
489 args,
490 "limit",
491 opt.Offset,
492 opt.Count,
493 )
494 }
495 cmd := NewZSliceCmd(ctx, args...)
496 _ = c(ctx, cmd)
497 return cmd
498 }
499
500 func (c cmdable) ZRangeStore(ctx context.Context, dst string, z ZRangeArgs) *IntCmd {
501 args := make([]interface{}, 0, 10)
502 args = append(args, "zrangestore", dst)
503 args = z.appendArgs(args)
504 cmd := NewIntCmd(ctx, args...)
505 _ = c(ctx, cmd)
506 return cmd
507 }
508
509 func (c cmdable) ZRank(ctx context.Context, key, member string) *IntCmd {
510 cmd := NewIntCmd(ctx, "zrank", key, member)
511 _ = c(ctx, cmd)
512 return cmd
513 }
514
515
516
517 func (c cmdable) ZRankWithScore(ctx context.Context, key, member string) *RankWithScoreCmd {
518 cmd := NewRankWithScoreCmd(ctx, "zrank", key, member, "withscore")
519 _ = c(ctx, cmd)
520 return cmd
521 }
522
523 func (c cmdable) ZRem(ctx context.Context, key string, members ...interface{}) *IntCmd {
524 args := make([]interface{}, 2, 2+len(members))
525 args[0] = "zrem"
526 args[1] = key
527 args = appendArgs(args, members)
528 cmd := NewIntCmd(ctx, args...)
529 _ = c(ctx, cmd)
530 return cmd
531 }
532
533 func (c cmdable) ZRemRangeByRank(ctx context.Context, key string, start, stop int64) *IntCmd {
534 cmd := NewIntCmd(
535 ctx,
536 "zremrangebyrank",
537 key,
538 start,
539 stop,
540 )
541 _ = c(ctx, cmd)
542 return cmd
543 }
544
545 func (c cmdable) ZRemRangeByScore(ctx context.Context, key, min, max string) *IntCmd {
546 cmd := NewIntCmd(ctx, "zremrangebyscore", key, min, max)
547 _ = c(ctx, cmd)
548 return cmd
549 }
550
551 func (c cmdable) ZRemRangeByLex(ctx context.Context, key, min, max string) *IntCmd {
552 cmd := NewIntCmd(ctx, "zremrangebylex", key, min, max)
553 _ = c(ctx, cmd)
554 return cmd
555 }
556
557 func (c cmdable) ZRevRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd {
558 cmd := NewStringSliceCmd(ctx, "zrevrange", key, start, stop)
559 _ = c(ctx, cmd)
560 return cmd
561 }
562
563
564
565 func (c cmdable) ZRevRangeWithScores(ctx context.Context, key string, start, stop int64) *ZSliceCmd {
566 cmd := NewZSliceCmd(ctx, "zrevrange", key, start, stop, "withscores")
567 _ = c(ctx, cmd)
568 return cmd
569 }
570
571 func (c cmdable) zRevRangeBy(ctx context.Context, zcmd, key string, opt *ZRangeBy) *StringSliceCmd {
572 args := []interface{}{zcmd, key, opt.Max, opt.Min}
573 if opt.Offset != 0 || opt.Count != 0 {
574 args = append(
575 args,
576 "limit",
577 opt.Offset,
578 opt.Count,
579 )
580 }
581 cmd := NewStringSliceCmd(ctx, args...)
582 _ = c(ctx, cmd)
583 return cmd
584 }
585
586 func (c cmdable) ZRevRangeByScore(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd {
587 return c.zRevRangeBy(ctx, "zrevrangebyscore", key, opt)
588 }
589
590 func (c cmdable) ZRevRangeByLex(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd {
591 return c.zRevRangeBy(ctx, "zrevrangebylex", key, opt)
592 }
593
594 func (c cmdable) ZRevRangeByScoreWithScores(ctx context.Context, key string, opt *ZRangeBy) *ZSliceCmd {
595 args := []interface{}{"zrevrangebyscore", key, opt.Max, opt.Min, "withscores"}
596 if opt.Offset != 0 || opt.Count != 0 {
597 args = append(
598 args,
599 "limit",
600 opt.Offset,
601 opt.Count,
602 )
603 }
604 cmd := NewZSliceCmd(ctx, args...)
605 _ = c(ctx, cmd)
606 return cmd
607 }
608
609 func (c cmdable) ZRevRank(ctx context.Context, key, member string) *IntCmd {
610 cmd := NewIntCmd(ctx, "zrevrank", key, member)
611 _ = c(ctx, cmd)
612 return cmd
613 }
614
615 func (c cmdable) ZRevRankWithScore(ctx context.Context, key, member string) *RankWithScoreCmd {
616 cmd := NewRankWithScoreCmd(ctx, "zrevrank", key, member, "withscore")
617 _ = c(ctx, cmd)
618 return cmd
619 }
620
621 func (c cmdable) ZScore(ctx context.Context, key, member string) *FloatCmd {
622 cmd := NewFloatCmd(ctx, "zscore", key, member)
623 _ = c(ctx, cmd)
624 return cmd
625 }
626
627 func (c cmdable) ZUnion(ctx context.Context, store ZStore) *StringSliceCmd {
628 args := make([]interface{}, 0, 2+store.len())
629 args = append(args, "zunion", len(store.Keys))
630 args = store.appendArgs(args)
631 cmd := NewStringSliceCmd(ctx, args...)
632 cmd.SetFirstKeyPos(2)
633 _ = c(ctx, cmd)
634 return cmd
635 }
636
637 func (c cmdable) ZUnionWithScores(ctx context.Context, store ZStore) *ZSliceCmd {
638 args := make([]interface{}, 0, 3+store.len())
639 args = append(args, "zunion", len(store.Keys))
640 args = store.appendArgs(args)
641 args = append(args, "withscores")
642 cmd := NewZSliceCmd(ctx, args...)
643 cmd.SetFirstKeyPos(2)
644 _ = c(ctx, cmd)
645 return cmd
646 }
647
648 func (c cmdable) ZUnionStore(ctx context.Context, dest string, store *ZStore) *IntCmd {
649 args := make([]interface{}, 0, 3+store.len())
650 args = append(args, "zunionstore", dest, len(store.Keys))
651 args = store.appendArgs(args)
652 cmd := NewIntCmd(ctx, args...)
653 cmd.SetFirstKeyPos(3)
654 _ = c(ctx, cmd)
655 return cmd
656 }
657
658
659 func (c cmdable) ZRandMember(ctx context.Context, key string, count int) *StringSliceCmd {
660 cmd := NewStringSliceCmd(ctx, "zrandmember", key, count)
661 _ = c(ctx, cmd)
662 return cmd
663 }
664
665
666 func (c cmdable) ZRandMemberWithScores(ctx context.Context, key string, count int) *ZSliceCmd {
667 cmd := NewZSliceCmd(ctx, "zrandmember", key, count, "withscores")
668 _ = c(ctx, cmd)
669 return cmd
670 }
671
672
673 func (c cmdable) ZDiff(ctx context.Context, keys ...string) *StringSliceCmd {
674 args := make([]interface{}, 2+len(keys))
675 args[0] = "zdiff"
676 args[1] = len(keys)
677 for i, key := range keys {
678 args[i+2] = key
679 }
680
681 cmd := NewStringSliceCmd(ctx, args...)
682 cmd.SetFirstKeyPos(2)
683 _ = c(ctx, cmd)
684 return cmd
685 }
686
687
688 func (c cmdable) ZDiffWithScores(ctx context.Context, keys ...string) *ZSliceCmd {
689 args := make([]interface{}, 3+len(keys))
690 args[0] = "zdiff"
691 args[1] = len(keys)
692 for i, key := range keys {
693 args[i+2] = key
694 }
695 args[len(keys)+2] = "withscores"
696
697 cmd := NewZSliceCmd(ctx, args...)
698 cmd.SetFirstKeyPos(2)
699 _ = c(ctx, cmd)
700 return cmd
701 }
702
703
704 func (c cmdable) ZDiffStore(ctx context.Context, destination string, keys ...string) *IntCmd {
705 args := make([]interface{}, 0, 3+len(keys))
706 args = append(args, "zdiffstore", destination, len(keys))
707 for _, key := range keys {
708 args = append(args, key)
709 }
710 cmd := NewIntCmd(ctx, args...)
711 _ = c(ctx, cmd)
712 return cmd
713 }
714
715 func (c cmdable) ZScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd {
716 args := []interface{}{"zscan", key, cursor}
717 if match != "" {
718 args = append(args, "match", match)
719 }
720 if count > 0 {
721 args = append(args, "count", count)
722 }
723 cmd := NewScanCmd(ctx, c, args...)
724 if hashtag.Present(match) {
725 cmd.SetFirstKeyPos(4)
726 }
727 _ = c(ctx, cmd)
728 return cmd
729 }
730
731
732 type Z struct {
733 Score float64
734 Member interface{}
735 }
736
737
738 type ZWithKey struct {
739 Z
740 Key string
741 }
742
743
744 type ZStore struct {
745 Keys []string
746 Weights []float64
747
748 Aggregate string
749 }
750
751 func (z ZStore) len() (n int) {
752 n = len(z.Keys)
753 if len(z.Weights) > 0 {
754 n += 1 + len(z.Weights)
755 }
756 if z.Aggregate != "" {
757 n += 2
758 }
759 return n
760 }
761
762 func (z ZStore) appendArgs(args []interface{}) []interface{} {
763 for _, key := range z.Keys {
764 args = append(args, key)
765 }
766 if len(z.Weights) > 0 {
767 args = append(args, "weights")
768 for _, weights := range z.Weights {
769 args = append(args, weights)
770 }
771 }
772 if z.Aggregate != "" {
773 args = append(args, "aggregate", z.Aggregate)
774 }
775 return args
776 }
777
View as plain text