github.com/shuguocloud/go-zero@v1.3.0/core/stores/redis/redis.go (about) 1 package redis 2 3 import ( 4 "errors" 5 "fmt" 6 "strconv" 7 "time" 8 9 red "github.com/go-redis/redis" 10 "github.com/shuguocloud/go-zero/core/breaker" 11 "github.com/shuguocloud/go-zero/core/mapping" 12 "github.com/shuguocloud/go-zero/core/syncx" 13 ) 14 15 const ( 16 // ClusterType means redis cluster. 17 ClusterType = "cluster" 18 // NodeType means redis node. 19 NodeType = "node" 20 // Nil is an alias of redis.Nil. 21 Nil = red.Nil 22 23 blockingQueryTimeout = 5 * time.Second 24 readWriteTimeout = 2 * time.Second 25 defaultSlowThreshold = time.Millisecond * 100 26 ) 27 28 var ( 29 // ErrNilNode is an error that indicates a nil redis node. 30 ErrNilNode = errors.New("nil redis node") 31 slowThreshold = syncx.ForAtomicDuration(defaultSlowThreshold) 32 ) 33 34 type ( 35 // Option defines the method to customize a Redis. 36 Option func(r *Redis) 37 38 // A Pair is a key/pair set used in redis zset. 39 Pair struct { 40 Key string 41 Score int64 42 } 43 44 // Redis defines a redis node/cluster. It is thread-safe. 45 Redis struct { 46 Addr string 47 Type string 48 Pass string 49 tls bool 50 brk breaker.Breaker 51 } 52 53 // RedisNode interface represents a redis node. 54 RedisNode interface { 55 red.Cmdable 56 } 57 58 // GeoLocation is used with GeoAdd to add geospatial location. 59 GeoLocation = red.GeoLocation 60 // GeoRadiusQuery is used with GeoRadius to query geospatial index. 61 GeoRadiusQuery = red.GeoRadiusQuery 62 // GeoPos is used to represent a geo position. 63 GeoPos = red.GeoPos 64 65 // Pipeliner is an alias of redis.Pipeliner. 66 Pipeliner = red.Pipeliner 67 68 // Z represents sorted set member. 69 Z = red.Z 70 // ZStore is an alias of redis.ZStore. 71 ZStore = red.ZStore 72 73 // IntCmd is an alias of redis.IntCmd. 74 IntCmd = red.IntCmd 75 // FloatCmd is an alias of redis.FloatCmd. 76 FloatCmd = red.FloatCmd 77 // StringCmd is an alias of redis.StringCmd. 78 StringCmd = red.StringCmd 79 ) 80 81 // New returns a Redis with given options. 82 func New(addr string, opts ...Option) *Redis { 83 r := &Redis{ 84 Addr: addr, 85 Type: NodeType, 86 brk: breaker.NewBreaker(), 87 } 88 89 for _, opt := range opts { 90 opt(r) 91 } 92 93 return r 94 } 95 96 // NewRedis returns a Redis. 97 // Deprecated: use New instead, will be removed in v2. 98 func NewRedis(redisAddr, redisType string, redisPass ...string) *Redis { 99 var opts []Option 100 if redisType == ClusterType { 101 opts = append(opts, Cluster()) 102 } 103 for _, v := range redisPass { 104 opts = append(opts, WithPass(v)) 105 } 106 107 return New(redisAddr, opts...) 108 } 109 110 // BitCount is redis bitcount command implementation. 111 func (s *Redis) BitCount(key string, start, end int64) (val int64, err error) { 112 err = s.brk.DoWithAcceptable(func() error { 113 conn, err := getRedis(s) 114 if err != nil { 115 return err 116 } 117 118 val, err = conn.BitCount(key, &red.BitCount{ 119 Start: start, 120 End: end, 121 }).Result() 122 return err 123 }, acceptable) 124 125 return 126 } 127 128 // BitOpAnd is redis bit operation (and) command implementation. 129 func (s *Redis) BitOpAnd(destKey string, keys ...string) (val int64, err error) { 130 err = s.brk.DoWithAcceptable(func() error { 131 conn, err := getRedis(s) 132 if err != nil { 133 return err 134 } 135 136 val, err = conn.BitOpAnd(destKey, keys...).Result() 137 return err 138 }, acceptable) 139 140 return 141 } 142 143 // BitOpNot is redis bit operation (not) command implementation. 144 func (s *Redis) BitOpNot(destKey, key string) (val int64, err error) { 145 err = s.brk.DoWithAcceptable(func() error { 146 conn, err := getRedis(s) 147 if err != nil { 148 return err 149 } 150 151 val, err = conn.BitOpNot(destKey, key).Result() 152 return err 153 }, acceptable) 154 155 return 156 } 157 158 // BitOpOr is redis bit operation (or) command implementation. 159 func (s *Redis) BitOpOr(destKey string, keys ...string) (val int64, err error) { 160 err = s.brk.DoWithAcceptable(func() error { 161 conn, err := getRedis(s) 162 if err != nil { 163 return err 164 } 165 166 val, err = conn.BitOpOr(destKey, keys...).Result() 167 return err 168 }, acceptable) 169 170 return 171 } 172 173 // BitOpXor is redis bit operation (xor) command implementation. 174 func (s *Redis) BitOpXor(destKey string, keys ...string) (val int64, err error) { 175 err = s.brk.DoWithAcceptable(func() error { 176 conn, err := getRedis(s) 177 if err != nil { 178 return err 179 } 180 181 val, err = conn.BitOpXor(destKey, keys...).Result() 182 return err 183 }, acceptable) 184 185 return 186 } 187 188 // BitPos is redis bitpos command implementation. 189 func (s *Redis) BitPos(key string, bit, start, end int64) (val int64, err error) { 190 err = s.brk.DoWithAcceptable(func() error { 191 conn, err := getRedis(s) 192 if err != nil { 193 return err 194 } 195 196 val, err = conn.BitPos(key, bit, start, end).Result() 197 return err 198 }, acceptable) 199 200 return 201 } 202 203 // Blpop uses passed in redis connection to execute blocking queries. 204 // Doesn't benefit from pooling redis connections of blocking queries 205 func (s *Redis) Blpop(redisNode RedisNode, key string) (string, error) { 206 if redisNode == nil { 207 return "", ErrNilNode 208 } 209 210 vals, err := redisNode.BLPop(blockingQueryTimeout, key).Result() 211 if err != nil { 212 return "", err 213 } 214 215 if len(vals) < 2 { 216 return "", fmt.Errorf("no value on key: %s", key) 217 } 218 219 return vals[1], nil 220 } 221 222 // BlpopEx uses passed in redis connection to execute blpop command. 223 // The difference against Blpop is that this method returns a bool to indicate success. 224 func (s *Redis) BlpopEx(redisNode RedisNode, key string) (string, bool, error) { 225 if redisNode == nil { 226 return "", false, ErrNilNode 227 } 228 229 vals, err := redisNode.BLPop(blockingQueryTimeout, key).Result() 230 if err != nil { 231 return "", false, err 232 } 233 234 if len(vals) < 2 { 235 return "", false, fmt.Errorf("no value on key: %s", key) 236 } 237 238 return vals[1], true, nil 239 } 240 241 // Decr is the implementation of redis decr command. 242 func (s *Redis) Decr(key string) (val int64, err error) { 243 err = s.brk.DoWithAcceptable(func() error { 244 conn, err := getRedis(s) 245 if err != nil { 246 return err 247 } 248 249 val, err = conn.Decr(key).Result() 250 return err 251 }, acceptable) 252 253 return 254 } 255 256 // Decrby is the implementation of redis decrby command. 257 func (s *Redis) Decrby(key string, increment int64) (val int64, err error) { 258 err = s.brk.DoWithAcceptable(func() error { 259 conn, err := getRedis(s) 260 if err != nil { 261 return err 262 } 263 264 val, err = conn.DecrBy(key, increment).Result() 265 return err 266 }, acceptable) 267 268 return 269 } 270 271 // Del deletes keys. 272 func (s *Redis) Del(keys ...string) (val int, err error) { 273 err = s.brk.DoWithAcceptable(func() error { 274 conn, err := getRedis(s) 275 if err != nil { 276 return err 277 } 278 279 v, err := conn.Del(keys...).Result() 280 if err != nil { 281 return err 282 } 283 284 val = int(v) 285 return nil 286 }, acceptable) 287 288 return 289 } 290 291 // Eval is the implementation of redis eval command. 292 func (s *Redis) Eval(script string, keys []string, args ...interface{}) (val interface{}, err error) { 293 err = s.brk.DoWithAcceptable(func() error { 294 conn, err := getRedis(s) 295 if err != nil { 296 return err 297 } 298 299 val, err = conn.Eval(script, keys, args...).Result() 300 return err 301 }, acceptable) 302 303 return 304 } 305 306 // EvalSha is the implementation of redis evalsha command. 307 func (s *Redis) EvalSha(sha string, keys []string, args ...interface{}) (val interface{}, err error) { 308 err = s.brk.DoWithAcceptable(func() error { 309 conn, err := getRedis(s) 310 if err != nil { 311 return err 312 } 313 314 val, err = conn.EvalSha(sha, keys, args...).Result() 315 return err 316 }, acceptable) 317 318 return 319 } 320 321 // Exists is the implementation of redis exists command. 322 func (s *Redis) Exists(key string) (val bool, err error) { 323 err = s.brk.DoWithAcceptable(func() error { 324 conn, err := getRedis(s) 325 if err != nil { 326 return err 327 } 328 329 v, err := conn.Exists(key).Result() 330 if err != nil { 331 return err 332 } 333 334 val = v == 1 335 return nil 336 }, acceptable) 337 338 return 339 } 340 341 // Expire is the implementation of redis expire command. 342 func (s *Redis) Expire(key string, seconds int) error { 343 return s.brk.DoWithAcceptable(func() error { 344 conn, err := getRedis(s) 345 if err != nil { 346 return err 347 } 348 349 return conn.Expire(key, time.Duration(seconds)*time.Second).Err() 350 }, acceptable) 351 } 352 353 // Expireat is the implementation of redis expireat command. 354 func (s *Redis) Expireat(key string, expireTime int64) error { 355 return s.brk.DoWithAcceptable(func() error { 356 conn, err := getRedis(s) 357 if err != nil { 358 return err 359 } 360 361 return conn.ExpireAt(key, time.Unix(expireTime, 0)).Err() 362 }, acceptable) 363 } 364 365 // GeoAdd is the implementation of redis geoadd command. 366 func (s *Redis) GeoAdd(key string, geoLocation ...*GeoLocation) (val int64, err error) { 367 err = s.brk.DoWithAcceptable(func() error { 368 conn, err := getRedis(s) 369 if err != nil { 370 return err 371 } 372 373 v, err := conn.GeoAdd(key, geoLocation...).Result() 374 if err != nil { 375 return err 376 } 377 378 val = v 379 return nil 380 }, acceptable) 381 return 382 } 383 384 // GeoDist is the implementation of redis geodist command. 385 func (s *Redis) GeoDist(key, member1, member2, unit string) (val float64, err error) { 386 err = s.brk.DoWithAcceptable(func() error { 387 conn, err := getRedis(s) 388 if err != nil { 389 return err 390 } 391 392 v, err := conn.GeoDist(key, member1, member2, unit).Result() 393 if err != nil { 394 return err 395 } 396 397 val = v 398 return nil 399 }, acceptable) 400 return 401 } 402 403 // GeoHash is the implementation of redis geohash command. 404 func (s *Redis) GeoHash(key string, members ...string) (val []string, err error) { 405 err = s.brk.DoWithAcceptable(func() error { 406 conn, err := getRedis(s) 407 if err != nil { 408 return err 409 } 410 411 v, err := conn.GeoHash(key, members...).Result() 412 if err != nil { 413 return err 414 } 415 416 val = v 417 return nil 418 }, acceptable) 419 return 420 } 421 422 // GeoRadius is the implementation of redis georadius command. 423 func (s *Redis) GeoRadius(key string, longitude, latitude float64, query *GeoRadiusQuery) (val []GeoLocation, err error) { 424 err = s.brk.DoWithAcceptable(func() error { 425 conn, err := getRedis(s) 426 if err != nil { 427 return err 428 } 429 430 v, err := conn.GeoRadius(key, longitude, latitude, query).Result() 431 if err != nil { 432 return err 433 } 434 435 val = v 436 return nil 437 }, acceptable) 438 return 439 } 440 441 // GeoRadiusByMember is the implementation of redis georadiusbymember command. 442 func (s *Redis) GeoRadiusByMember(key, member string, query *GeoRadiusQuery) (val []GeoLocation, err error) { 443 err = s.brk.DoWithAcceptable(func() error { 444 conn, err := getRedis(s) 445 if err != nil { 446 return err 447 } 448 449 v, err := conn.GeoRadiusByMember(key, member, query).Result() 450 if err != nil { 451 return err 452 } 453 454 val = v 455 return nil 456 }, acceptable) 457 return 458 } 459 460 // GeoPos is the implementation of redis geopos command. 461 func (s *Redis) GeoPos(key string, members ...string) (val []*GeoPos, err error) { 462 err = s.brk.DoWithAcceptable(func() error { 463 conn, err := getRedis(s) 464 if err != nil { 465 return err 466 } 467 468 v, err := conn.GeoPos(key, members...).Result() 469 if err != nil { 470 return err 471 } 472 473 val = v 474 return nil 475 }, acceptable) 476 return 477 } 478 479 // Get is the implementation of redis get command. 480 func (s *Redis) Get(key string) (val string, err error) { 481 err = s.brk.DoWithAcceptable(func() error { 482 conn, err := getRedis(s) 483 if err != nil { 484 return err 485 } 486 487 if val, err = conn.Get(key).Result(); err == red.Nil { 488 return nil 489 } else if err != nil { 490 return err 491 } else { 492 return nil 493 } 494 }, acceptable) 495 496 return 497 } 498 499 // GetBit is the implementation of redis getbit command. 500 func (s *Redis) GetBit(key string, offset int64) (val int, err error) { 501 err = s.brk.DoWithAcceptable(func() error { 502 conn, err := getRedis(s) 503 if err != nil { 504 return err 505 } 506 507 v, err := conn.GetBit(key, offset).Result() 508 if err != nil { 509 return err 510 } 511 512 val = int(v) 513 return nil 514 }, acceptable) 515 516 return 517 } 518 519 // Hdel is the implementation of redis hdel command. 520 func (s *Redis) Hdel(key string, fields ...string) (val bool, err error) { 521 err = s.brk.DoWithAcceptable(func() error { 522 conn, err := getRedis(s) 523 if err != nil { 524 return err 525 } 526 527 v, err := conn.HDel(key, fields...).Result() 528 if err != nil { 529 return err 530 } 531 532 val = v == 1 533 return nil 534 }, acceptable) 535 536 return 537 } 538 539 // Hexists is the implementation of redis hexists command. 540 func (s *Redis) Hexists(key, field string) (val bool, err error) { 541 err = s.brk.DoWithAcceptable(func() error { 542 conn, err := getRedis(s) 543 if err != nil { 544 return err 545 } 546 547 val, err = conn.HExists(key, field).Result() 548 return err 549 }, acceptable) 550 551 return 552 } 553 554 // Hget is the implementation of redis hget command. 555 func (s *Redis) Hget(key, field string) (val string, err error) { 556 err = s.brk.DoWithAcceptable(func() error { 557 conn, err := getRedis(s) 558 if err != nil { 559 return err 560 } 561 562 val, err = conn.HGet(key, field).Result() 563 return err 564 }, acceptable) 565 566 return 567 } 568 569 // Hgetall is the implementation of redis hgetall command. 570 func (s *Redis) Hgetall(key string) (val map[string]string, err error) { 571 err = s.brk.DoWithAcceptable(func() error { 572 conn, err := getRedis(s) 573 if err != nil { 574 return err 575 } 576 577 val, err = conn.HGetAll(key).Result() 578 return err 579 }, acceptable) 580 581 return 582 } 583 584 // Hincrby is the implementation of redis hincrby command. 585 func (s *Redis) Hincrby(key, field string, increment int) (val int, err error) { 586 err = s.brk.DoWithAcceptable(func() error { 587 conn, err := getRedis(s) 588 if err != nil { 589 return err 590 } 591 592 v, err := conn.HIncrBy(key, field, int64(increment)).Result() 593 if err != nil { 594 return err 595 } 596 597 val = int(v) 598 return nil 599 }, acceptable) 600 601 return 602 } 603 604 // Hkeys is the implementation of redis hkeys command. 605 func (s *Redis) Hkeys(key string) (val []string, err error) { 606 err = s.brk.DoWithAcceptable(func() error { 607 conn, err := getRedis(s) 608 if err != nil { 609 return err 610 } 611 612 val, err = conn.HKeys(key).Result() 613 return err 614 }, acceptable) 615 616 return 617 } 618 619 // Hlen is the implementation of redis hlen command. 620 func (s *Redis) Hlen(key string) (val int, err error) { 621 err = s.brk.DoWithAcceptable(func() error { 622 conn, err := getRedis(s) 623 if err != nil { 624 return err 625 } 626 627 v, err := conn.HLen(key).Result() 628 if err != nil { 629 return err 630 } 631 632 val = int(v) 633 return nil 634 }, acceptable) 635 636 return 637 } 638 639 // Hmget is the implementation of redis hmget command. 640 func (s *Redis) Hmget(key string, fields ...string) (val []string, err error) { 641 err = s.brk.DoWithAcceptable(func() error { 642 conn, err := getRedis(s) 643 if err != nil { 644 return err 645 } 646 647 v, err := conn.HMGet(key, fields...).Result() 648 if err != nil { 649 return err 650 } 651 652 val = toStrings(v) 653 return nil 654 }, acceptable) 655 656 return 657 } 658 659 // Hset is the implementation of redis hset command. 660 func (s *Redis) Hset(key, field, value string) error { 661 return s.brk.DoWithAcceptable(func() error { 662 conn, err := getRedis(s) 663 if err != nil { 664 return err 665 } 666 667 return conn.HSet(key, field, value).Err() 668 }, acceptable) 669 } 670 671 // Hsetnx is the implementation of redis hsetnx command. 672 func (s *Redis) Hsetnx(key, field, value string) (val bool, err error) { 673 err = s.brk.DoWithAcceptable(func() error { 674 conn, err := getRedis(s) 675 if err != nil { 676 return err 677 } 678 679 val, err = conn.HSetNX(key, field, value).Result() 680 return err 681 }, acceptable) 682 683 return 684 } 685 686 // Hmset is the implementation of redis hmset command. 687 func (s *Redis) Hmset(key string, fieldsAndValues map[string]string) error { 688 return s.brk.DoWithAcceptable(func() error { 689 conn, err := getRedis(s) 690 if err != nil { 691 return err 692 } 693 694 vals := make(map[string]interface{}, len(fieldsAndValues)) 695 for k, v := range fieldsAndValues { 696 vals[k] = v 697 } 698 699 return conn.HMSet(key, vals).Err() 700 }, acceptable) 701 } 702 703 // Hscan is the implementation of redis hscan command. 704 func (s *Redis) Hscan(key string, cursor uint64, match string, count int64) (keys []string, cur uint64, err error) { 705 err = s.brk.DoWithAcceptable(func() error { 706 conn, err := getRedis(s) 707 if err != nil { 708 return err 709 } 710 711 keys, cur, err = conn.HScan(key, cursor, match, count).Result() 712 return err 713 }, acceptable) 714 715 return 716 } 717 718 // Hvals is the implementation of redis hvals command. 719 func (s *Redis) Hvals(key string) (val []string, err error) { 720 err = s.brk.DoWithAcceptable(func() error { 721 conn, err := getRedis(s) 722 if err != nil { 723 return err 724 } 725 726 val, err = conn.HVals(key).Result() 727 return err 728 }, acceptable) 729 730 return 731 } 732 733 // Incr is the implementation of redis incr command. 734 func (s *Redis) Incr(key string) (val int64, err error) { 735 err = s.brk.DoWithAcceptable(func() error { 736 conn, err := getRedis(s) 737 if err != nil { 738 return err 739 } 740 741 val, err = conn.Incr(key).Result() 742 return err 743 }, acceptable) 744 745 return 746 } 747 748 // Incrby is the implementation of redis incrby command. 749 func (s *Redis) Incrby(key string, increment int64) (val int64, err error) { 750 err = s.brk.DoWithAcceptable(func() error { 751 conn, err := getRedis(s) 752 if err != nil { 753 return err 754 } 755 756 val, err = conn.IncrBy(key, int64(increment)).Result() 757 return err 758 }, acceptable) 759 760 return 761 } 762 763 // Keys is the implementation of redis keys command. 764 func (s *Redis) Keys(pattern string) (val []string, err error) { 765 err = s.brk.DoWithAcceptable(func() error { 766 conn, err := getRedis(s) 767 if err != nil { 768 return err 769 } 770 771 val, err = conn.Keys(pattern).Result() 772 return err 773 }, acceptable) 774 775 return 776 } 777 778 // Llen is the implementation of redis llen command. 779 func (s *Redis) Llen(key string) (val int, err error) { 780 err = s.brk.DoWithAcceptable(func() error { 781 conn, err := getRedis(s) 782 if err != nil { 783 return err 784 } 785 786 v, err := conn.LLen(key).Result() 787 if err != nil { 788 return err 789 } 790 791 val = int(v) 792 return nil 793 }, acceptable) 794 795 return 796 } 797 798 // Lindex is the implementation of redis lindex command. 799 func (s *Redis) Lindex(key string, index int64) (val string, err error) { 800 err = s.brk.DoWithAcceptable(func() error { 801 conn, err := getRedis(s) 802 if err != nil { 803 return err 804 } 805 806 val, err = conn.LIndex(key, index).Result() 807 return err 808 }, acceptable) 809 810 return 811 } 812 813 // Lpop is the implementation of redis lpop command. 814 func (s *Redis) Lpop(key string) (val string, err error) { 815 err = s.brk.DoWithAcceptable(func() error { 816 conn, err := getRedis(s) 817 if err != nil { 818 return err 819 } 820 821 val, err = conn.LPop(key).Result() 822 return err 823 }, acceptable) 824 825 return 826 } 827 828 // Lpush is the implementation of redis lpush command. 829 func (s *Redis) Lpush(key string, values ...interface{}) (val int, err error) { 830 err = s.brk.DoWithAcceptable(func() error { 831 conn, err := getRedis(s) 832 if err != nil { 833 return err 834 } 835 836 v, err := conn.LPush(key, values...).Result() 837 if err != nil { 838 return err 839 } 840 841 val = int(v) 842 return nil 843 }, acceptable) 844 845 return 846 } 847 848 // Lrange is the implementation of redis lrange command. 849 func (s *Redis) Lrange(key string, start, stop int) (val []string, err error) { 850 err = s.brk.DoWithAcceptable(func() error { 851 conn, err := getRedis(s) 852 if err != nil { 853 return err 854 } 855 856 val, err = conn.LRange(key, int64(start), int64(stop)).Result() 857 return err 858 }, acceptable) 859 860 return 861 } 862 863 // Lrem is the implementation of redis lrem command. 864 func (s *Redis) Lrem(key string, count int, value string) (val int, err error) { 865 err = s.brk.DoWithAcceptable(func() error { 866 conn, err := getRedis(s) 867 if err != nil { 868 return err 869 } 870 871 v, err := conn.LRem(key, int64(count), value).Result() 872 if err != nil { 873 return err 874 } 875 876 val = int(v) 877 return nil 878 }, acceptable) 879 880 return 881 } 882 883 // Ltrim is the implementation of redis ltrim command. 884 func (s *Redis) Ltrim(key string, start, stop int64) error { 885 return s.brk.DoWithAcceptable(func() error { 886 conn, err := getRedis(s) 887 if err != nil { 888 return err 889 } 890 891 return conn.LTrim(key, start, stop).Err() 892 }, acceptable) 893 } 894 895 // Mget is the implementation of redis mget command. 896 func (s *Redis) Mget(keys ...string) (val []string, err error) { 897 err = s.brk.DoWithAcceptable(func() error { 898 conn, err := getRedis(s) 899 if err != nil { 900 return err 901 } 902 903 v, err := conn.MGet(keys...).Result() 904 if err != nil { 905 return err 906 } 907 908 val = toStrings(v) 909 return nil 910 }, acceptable) 911 912 return 913 } 914 915 // Persist is the implementation of redis persist command. 916 func (s *Redis) Persist(key string) (val bool, err error) { 917 err = s.brk.DoWithAcceptable(func() error { 918 conn, err := getRedis(s) 919 if err != nil { 920 return err 921 } 922 923 val, err = conn.Persist(key).Result() 924 return err 925 }, acceptable) 926 927 return 928 } 929 930 // Pfadd is the implementation of redis pfadd command. 931 func (s *Redis) Pfadd(key string, values ...interface{}) (val bool, err error) { 932 err = s.brk.DoWithAcceptable(func() error { 933 conn, err := getRedis(s) 934 if err != nil { 935 return err 936 } 937 938 v, err := conn.PFAdd(key, values...).Result() 939 if err != nil { 940 return err 941 } 942 943 val = v == 1 944 return nil 945 }, acceptable) 946 947 return 948 } 949 950 // Pfcount is the implementation of redis pfcount command. 951 func (s *Redis) Pfcount(key string) (val int64, err error) { 952 err = s.brk.DoWithAcceptable(func() error { 953 conn, err := getRedis(s) 954 if err != nil { 955 return err 956 } 957 958 val, err = conn.PFCount(key).Result() 959 return err 960 }, acceptable) 961 962 return 963 } 964 965 // Pfmerge is the implementation of redis pfmerge command. 966 func (s *Redis) Pfmerge(dest string, keys ...string) error { 967 return s.brk.DoWithAcceptable(func() error { 968 conn, err := getRedis(s) 969 if err != nil { 970 return err 971 } 972 973 _, err = conn.PFMerge(dest, keys...).Result() 974 return err 975 }, acceptable) 976 } 977 978 // Ping is the implementation of redis ping command. 979 func (s *Redis) Ping() (val bool) { 980 // ignore error, error means false 981 _ = s.brk.DoWithAcceptable(func() error { 982 conn, err := getRedis(s) 983 if err != nil { 984 val = false 985 return nil 986 } 987 988 v, err := conn.Ping().Result() 989 if err != nil { 990 val = false 991 return nil 992 } 993 994 val = v == "PONG" 995 return nil 996 }, acceptable) 997 998 return 999 } 1000 1001 // Pipelined lets fn to execute pipelined commands. 1002 func (s *Redis) Pipelined(fn func(Pipeliner) error) (err error) { 1003 err = s.brk.DoWithAcceptable(func() error { 1004 conn, err := getRedis(s) 1005 if err != nil { 1006 return err 1007 } 1008 1009 _, err = conn.Pipelined(fn) 1010 return err 1011 }, acceptable) 1012 1013 return 1014 } 1015 1016 // Rpop is the implementation of redis rpop command. 1017 func (s *Redis) Rpop(key string) (val string, err error) { 1018 err = s.brk.DoWithAcceptable(func() error { 1019 conn, err := getRedis(s) 1020 if err != nil { 1021 return err 1022 } 1023 1024 val, err = conn.RPop(key).Result() 1025 return err 1026 }, acceptable) 1027 1028 return 1029 } 1030 1031 // Rpush is the implementation of redis rpush command. 1032 func (s *Redis) Rpush(key string, values ...interface{}) (val int, err error) { 1033 err = s.brk.DoWithAcceptable(func() error { 1034 conn, err := getRedis(s) 1035 if err != nil { 1036 return err 1037 } 1038 1039 v, err := conn.RPush(key, values...).Result() 1040 if err != nil { 1041 return err 1042 } 1043 1044 val = int(v) 1045 return nil 1046 }, acceptable) 1047 1048 return 1049 } 1050 1051 // Sadd is the implementation of redis sadd command. 1052 func (s *Redis) Sadd(key string, values ...interface{}) (val int, err error) { 1053 err = s.brk.DoWithAcceptable(func() error { 1054 conn, err := getRedis(s) 1055 if err != nil { 1056 return err 1057 } 1058 1059 v, err := conn.SAdd(key, values...).Result() 1060 if err != nil { 1061 return err 1062 } 1063 1064 val = int(v) 1065 return nil 1066 }, acceptable) 1067 1068 return 1069 } 1070 1071 // Scan is the implementation of redis scan command. 1072 func (s *Redis) Scan(cursor uint64, match string, count int64) (keys []string, cur uint64, err error) { 1073 err = s.brk.DoWithAcceptable(func() error { 1074 conn, err := getRedis(s) 1075 if err != nil { 1076 return err 1077 } 1078 1079 keys, cur, err = conn.Scan(cursor, match, count).Result() 1080 return err 1081 }, acceptable) 1082 1083 return 1084 } 1085 1086 // SetBit is the implementation of redis setbit command. 1087 func (s *Redis) SetBit(key string, offset int64, value int) error { 1088 return s.brk.DoWithAcceptable(func() error { 1089 conn, err := getRedis(s) 1090 if err != nil { 1091 return err 1092 } 1093 1094 _, err = conn.SetBit(key, offset, value).Result() 1095 return err 1096 }, acceptable) 1097 } 1098 1099 // Sscan is the implementation of redis sscan command. 1100 func (s *Redis) Sscan(key string, cursor uint64, match string, count int64) (keys []string, cur uint64, err error) { 1101 err = s.brk.DoWithAcceptable(func() error { 1102 conn, err := getRedis(s) 1103 if err != nil { 1104 return err 1105 } 1106 1107 keys, cur, err = conn.SScan(key, cursor, match, count).Result() 1108 return err 1109 }, acceptable) 1110 1111 return 1112 } 1113 1114 // Scard is the implementation of redis scard command. 1115 func (s *Redis) Scard(key string) (val int64, err error) { 1116 err = s.brk.DoWithAcceptable(func() error { 1117 conn, err := getRedis(s) 1118 if err != nil { 1119 return err 1120 } 1121 1122 val, err = conn.SCard(key).Result() 1123 return err 1124 }, acceptable) 1125 1126 return 1127 } 1128 1129 // ScriptLoad is the implementation of redis script load command. 1130 func (s *Redis) ScriptLoad(script string) (string, error) { 1131 conn, err := getRedis(s) 1132 if err != nil { 1133 return "", err 1134 } 1135 1136 return conn.ScriptLoad(script).Result() 1137 } 1138 1139 // Set is the implementation of redis set command. 1140 func (s *Redis) Set(key, value string) error { 1141 return s.brk.DoWithAcceptable(func() error { 1142 conn, err := getRedis(s) 1143 if err != nil { 1144 return err 1145 } 1146 1147 return conn.Set(key, value, 0).Err() 1148 }, acceptable) 1149 } 1150 1151 // Setex is the implementation of redis setex command. 1152 func (s *Redis) Setex(key, value string, seconds int) error { 1153 return s.brk.DoWithAcceptable(func() error { 1154 conn, err := getRedis(s) 1155 if err != nil { 1156 return err 1157 } 1158 1159 return conn.Set(key, value, time.Duration(seconds)*time.Second).Err() 1160 }, acceptable) 1161 } 1162 1163 // Setnx is the implementation of redis setnx command. 1164 func (s *Redis) Setnx(key, value string) (val bool, err error) { 1165 err = s.brk.DoWithAcceptable(func() error { 1166 conn, err := getRedis(s) 1167 if err != nil { 1168 return err 1169 } 1170 1171 val, err = conn.SetNX(key, value, 0).Result() 1172 return err 1173 }, acceptable) 1174 1175 return 1176 } 1177 1178 // SetnxEx is the implementation of redis setnx command with expire. 1179 func (s *Redis) SetnxEx(key, value string, seconds int) (val bool, err error) { 1180 err = s.brk.DoWithAcceptable(func() error { 1181 conn, err := getRedis(s) 1182 if err != nil { 1183 return err 1184 } 1185 1186 val, err = conn.SetNX(key, value, time.Duration(seconds)*time.Second).Result() 1187 return err 1188 }, acceptable) 1189 1190 return 1191 } 1192 1193 // Sismember is the implementation of redis sismember command. 1194 func (s *Redis) Sismember(key string, value interface{}) (val bool, err error) { 1195 err = s.brk.DoWithAcceptable(func() error { 1196 conn, err := getRedis(s) 1197 if err != nil { 1198 return err 1199 } 1200 1201 val, err = conn.SIsMember(key, value).Result() 1202 return err 1203 }, acceptable) 1204 1205 return 1206 } 1207 1208 // Smembers is the implementation of redis smembers command. 1209 func (s *Redis) Smembers(key string) (val []string, err error) { 1210 err = s.brk.DoWithAcceptable(func() error { 1211 conn, err := getRedis(s) 1212 if err != nil { 1213 return err 1214 } 1215 1216 val, err = conn.SMembers(key).Result() 1217 return err 1218 }, acceptable) 1219 1220 return 1221 } 1222 1223 // Spop is the implementation of redis spop command. 1224 func (s *Redis) Spop(key string) (val string, err error) { 1225 err = s.brk.DoWithAcceptable(func() error { 1226 conn, err := getRedis(s) 1227 if err != nil { 1228 return err 1229 } 1230 1231 val, err = conn.SPop(key).Result() 1232 return err 1233 }, acceptable) 1234 1235 return 1236 } 1237 1238 // Srandmember is the implementation of redis srandmember command. 1239 func (s *Redis) Srandmember(key string, count int) (val []string, err error) { 1240 err = s.brk.DoWithAcceptable(func() error { 1241 conn, err := getRedis(s) 1242 if err != nil { 1243 return err 1244 } 1245 1246 val, err = conn.SRandMemberN(key, int64(count)).Result() 1247 return err 1248 }, acceptable) 1249 1250 return 1251 } 1252 1253 // Srem is the implementation of redis srem command. 1254 func (s *Redis) Srem(key string, values ...interface{}) (val int, err error) { 1255 err = s.brk.DoWithAcceptable(func() error { 1256 conn, err := getRedis(s) 1257 if err != nil { 1258 return err 1259 } 1260 1261 v, err := conn.SRem(key, values...).Result() 1262 if err != nil { 1263 return err 1264 } 1265 1266 val = int(v) 1267 return nil 1268 }, acceptable) 1269 1270 return 1271 } 1272 1273 // String returns the string representation of s. 1274 func (s *Redis) String() string { 1275 return s.Addr 1276 } 1277 1278 // Sunion is the implementation of redis sunion command. 1279 func (s *Redis) Sunion(keys ...string) (val []string, err error) { 1280 err = s.brk.DoWithAcceptable(func() error { 1281 conn, err := getRedis(s) 1282 if err != nil { 1283 return err 1284 } 1285 1286 val, err = conn.SUnion(keys...).Result() 1287 return err 1288 }, acceptable) 1289 1290 return 1291 } 1292 1293 // Sunionstore is the implementation of redis sunionstore command. 1294 func (s *Redis) Sunionstore(destination string, keys ...string) (val int, err error) { 1295 err = s.brk.DoWithAcceptable(func() error { 1296 conn, err := getRedis(s) 1297 if err != nil { 1298 return err 1299 } 1300 1301 v, err := conn.SUnionStore(destination, keys...).Result() 1302 if err != nil { 1303 return err 1304 } 1305 1306 val = int(v) 1307 return nil 1308 }, acceptable) 1309 1310 return 1311 } 1312 1313 // Sdiff is the implementation of redis sdiff command. 1314 func (s *Redis) Sdiff(keys ...string) (val []string, err error) { 1315 err = s.brk.DoWithAcceptable(func() error { 1316 conn, err := getRedis(s) 1317 if err != nil { 1318 return err 1319 } 1320 1321 val, err = conn.SDiff(keys...).Result() 1322 return err 1323 }, acceptable) 1324 1325 return 1326 } 1327 1328 // Sdiffstore is the implementation of redis sdiffstore command. 1329 func (s *Redis) Sdiffstore(destination string, keys ...string) (val int, err error) { 1330 err = s.brk.DoWithAcceptable(func() error { 1331 conn, err := getRedis(s) 1332 if err != nil { 1333 return err 1334 } 1335 1336 v, err := conn.SDiffStore(destination, keys...).Result() 1337 if err != nil { 1338 return err 1339 } 1340 1341 val = int(v) 1342 return nil 1343 }, acceptable) 1344 1345 return 1346 } 1347 1348 // Sinter is the implementation of redis sinter command. 1349 func (s *Redis) Sinter(keys ...string) (val []string, err error) { 1350 err = s.brk.DoWithAcceptable(func() error { 1351 conn, err := getRedis(s) 1352 if err != nil { 1353 return err 1354 } 1355 1356 val, err = conn.SInter(keys...).Result() 1357 return err 1358 }, acceptable) 1359 1360 return 1361 } 1362 1363 // Sinterstore is the implementation of redis sinterstore command. 1364 func (s *Redis) Sinterstore(destination string, keys ...string) (val int, err error) { 1365 err = s.brk.DoWithAcceptable(func() error { 1366 conn, err := getRedis(s) 1367 if err != nil { 1368 return err 1369 } 1370 1371 v, err := conn.SInterStore(destination, keys...).Result() 1372 if err != nil { 1373 return err 1374 } 1375 1376 val = int(v) 1377 return nil 1378 }, acceptable) 1379 1380 return 1381 } 1382 1383 // Ttl is the implementation of redis ttl command. 1384 func (s *Redis) Ttl(key string) (val int, err error) { 1385 err = s.brk.DoWithAcceptable(func() error { 1386 conn, err := getRedis(s) 1387 if err != nil { 1388 return err 1389 } 1390 1391 duration, err := conn.TTL(key).Result() 1392 if err != nil { 1393 return err 1394 } 1395 1396 val = int(duration / time.Second) 1397 return nil 1398 }, acceptable) 1399 1400 return 1401 } 1402 1403 // Zadd is the implementation of redis zadd command. 1404 func (s *Redis) Zadd(key string, score int64, value string) (val bool, err error) { 1405 err = s.brk.DoWithAcceptable(func() error { 1406 conn, err := getRedis(s) 1407 if err != nil { 1408 return err 1409 } 1410 1411 v, err := conn.ZAdd(key, red.Z{ 1412 Score: float64(score), 1413 Member: value, 1414 }).Result() 1415 if err != nil { 1416 return err 1417 } 1418 1419 val = v == 1 1420 return nil 1421 }, acceptable) 1422 1423 return 1424 } 1425 1426 // Zadds is the implementation of redis zadds command. 1427 func (s *Redis) Zadds(key string, ps ...Pair) (val int64, err error) { 1428 err = s.brk.DoWithAcceptable(func() error { 1429 conn, err := getRedis(s) 1430 if err != nil { 1431 return err 1432 } 1433 1434 var zs []red.Z 1435 for _, p := range ps { 1436 z := red.Z{Score: float64(p.Score), Member: p.Key} 1437 zs = append(zs, z) 1438 } 1439 1440 v, err := conn.ZAdd(key, zs...).Result() 1441 if err != nil { 1442 return err 1443 } 1444 1445 val = v 1446 return nil 1447 }, acceptable) 1448 1449 return 1450 } 1451 1452 // Zcard is the implementation of redis zcard command. 1453 func (s *Redis) Zcard(key string) (val int, err error) { 1454 err = s.brk.DoWithAcceptable(func() error { 1455 conn, err := getRedis(s) 1456 if err != nil { 1457 return err 1458 } 1459 1460 v, err := conn.ZCard(key).Result() 1461 if err != nil { 1462 return err 1463 } 1464 1465 val = int(v) 1466 return nil 1467 }, acceptable) 1468 1469 return 1470 } 1471 1472 // Zcount is the implementation of redis zcount command. 1473 func (s *Redis) Zcount(key string, start, stop int64) (val int, err error) { 1474 err = s.brk.DoWithAcceptable(func() error { 1475 conn, err := getRedis(s) 1476 if err != nil { 1477 return err 1478 } 1479 1480 v, err := conn.ZCount(key, strconv.FormatInt(start, 10), strconv.FormatInt(stop, 10)).Result() 1481 if err != nil { 1482 return err 1483 } 1484 1485 val = int(v) 1486 return nil 1487 }, acceptable) 1488 1489 return 1490 } 1491 1492 // Zincrby is the implementation of redis zincrby command. 1493 func (s *Redis) Zincrby(key string, increment int64, field string) (val int64, err error) { 1494 err = s.brk.DoWithAcceptable(func() error { 1495 conn, err := getRedis(s) 1496 if err != nil { 1497 return err 1498 } 1499 1500 v, err := conn.ZIncrBy(key, float64(increment), field).Result() 1501 if err != nil { 1502 return err 1503 } 1504 1505 val = int64(v) 1506 return nil 1507 }, acceptable) 1508 1509 return 1510 } 1511 1512 // Zscore is the implementation of redis zscore command. 1513 func (s *Redis) Zscore(key, value string) (val int64, err error) { 1514 err = s.brk.DoWithAcceptable(func() error { 1515 conn, err := getRedis(s) 1516 if err != nil { 1517 return err 1518 } 1519 1520 v, err := conn.ZScore(key, value).Result() 1521 if err != nil { 1522 return err 1523 } 1524 1525 val = int64(v) 1526 return nil 1527 }, acceptable) 1528 1529 return 1530 } 1531 1532 // Zrank is the implementation of redis zrank command. 1533 func (s *Redis) Zrank(key, field string) (val int64, err error) { 1534 err = s.brk.DoWithAcceptable(func() error { 1535 conn, err := getRedis(s) 1536 if err != nil { 1537 return err 1538 } 1539 1540 val, err = conn.ZRank(key, field).Result() 1541 return err 1542 }, acceptable) 1543 1544 return 1545 } 1546 1547 // Zrem is the implementation of redis zrem command. 1548 func (s *Redis) Zrem(key string, values ...interface{}) (val int, err error) { 1549 err = s.brk.DoWithAcceptable(func() error { 1550 conn, err := getRedis(s) 1551 if err != nil { 1552 return err 1553 } 1554 1555 v, err := conn.ZRem(key, values...).Result() 1556 if err != nil { 1557 return err 1558 } 1559 1560 val = int(v) 1561 return nil 1562 }, acceptable) 1563 1564 return 1565 } 1566 1567 // Zremrangebyscore is the implementation of redis zremrangebyscore command. 1568 func (s *Redis) Zremrangebyscore(key string, start, stop int64) (val int, err error) { 1569 err = s.brk.DoWithAcceptable(func() error { 1570 conn, err := getRedis(s) 1571 if err != nil { 1572 return err 1573 } 1574 1575 v, err := conn.ZRemRangeByScore(key, strconv.FormatInt(start, 10), 1576 strconv.FormatInt(stop, 10)).Result() 1577 if err != nil { 1578 return err 1579 } 1580 1581 val = int(v) 1582 return nil 1583 }, acceptable) 1584 1585 return 1586 } 1587 1588 // Zremrangebyrank is the implementation of redis zremrangebyrank command. 1589 func (s *Redis) Zremrangebyrank(key string, start, stop int64) (val int, err error) { 1590 err = s.brk.DoWithAcceptable(func() error { 1591 conn, err := getRedis(s) 1592 if err != nil { 1593 return err 1594 } 1595 1596 v, err := conn.ZRemRangeByRank(key, start, stop).Result() 1597 if err != nil { 1598 return err 1599 } 1600 1601 val = int(v) 1602 return nil 1603 }, acceptable) 1604 1605 return 1606 } 1607 1608 // Zrange is the implementation of redis zrange command. 1609 func (s *Redis) Zrange(key string, start, stop int64) (val []string, err error) { 1610 err = s.brk.DoWithAcceptable(func() error { 1611 conn, err := getRedis(s) 1612 if err != nil { 1613 return err 1614 } 1615 1616 val, err = conn.ZRange(key, start, stop).Result() 1617 return err 1618 }, acceptable) 1619 1620 return 1621 } 1622 1623 // ZrangeWithScores is the implementation of redis zrange command with scores. 1624 func (s *Redis) ZrangeWithScores(key string, start, stop int64) (val []Pair, err error) { 1625 err = s.brk.DoWithAcceptable(func() error { 1626 conn, err := getRedis(s) 1627 if err != nil { 1628 return err 1629 } 1630 1631 v, err := conn.ZRangeWithScores(key, start, stop).Result() 1632 if err != nil { 1633 return err 1634 } 1635 1636 val = toPairs(v) 1637 return nil 1638 }, acceptable) 1639 1640 return 1641 } 1642 1643 // ZRevRangeWithScores is the implementation of redis zrevrange command with scores. 1644 func (s *Redis) ZRevRangeWithScores(key string, start, stop int64) (val []Pair, err error) { 1645 err = s.brk.DoWithAcceptable(func() error { 1646 conn, err := getRedis(s) 1647 if err != nil { 1648 return err 1649 } 1650 1651 v, err := conn.ZRevRangeWithScores(key, start, stop).Result() 1652 if err != nil { 1653 return err 1654 } 1655 1656 val = toPairs(v) 1657 return nil 1658 }, acceptable) 1659 1660 return 1661 } 1662 1663 // ZrangebyscoreWithScores is the implementation of redis zrangebyscore command with scores. 1664 func (s *Redis) ZrangebyscoreWithScores(key string, start, stop int64) (val []Pair, err error) { 1665 err = s.brk.DoWithAcceptable(func() error { 1666 conn, err := getRedis(s) 1667 if err != nil { 1668 return err 1669 } 1670 1671 v, err := conn.ZRangeByScoreWithScores(key, red.ZRangeBy{ 1672 Min: strconv.FormatInt(start, 10), 1673 Max: strconv.FormatInt(stop, 10), 1674 }).Result() 1675 if err != nil { 1676 return err 1677 } 1678 1679 val = toPairs(v) 1680 return nil 1681 }, acceptable) 1682 1683 return 1684 } 1685 1686 // ZrangebyscoreWithScoresAndLimit is the implementation of redis zrangebyscore command with scores and limit. 1687 func (s *Redis) ZrangebyscoreWithScoresAndLimit(key string, start, stop int64, page, size int) ( 1688 val []Pair, err error) { 1689 err = s.brk.DoWithAcceptable(func() error { 1690 if size <= 0 { 1691 return nil 1692 } 1693 1694 conn, err := getRedis(s) 1695 if err != nil { 1696 return err 1697 } 1698 1699 v, err := conn.ZRangeByScoreWithScores(key, red.ZRangeBy{ 1700 Min: strconv.FormatInt(start, 10), 1701 Max: strconv.FormatInt(stop, 10), 1702 Offset: int64(page * size), 1703 Count: int64(size), 1704 }).Result() 1705 if err != nil { 1706 return err 1707 } 1708 1709 val = toPairs(v) 1710 return nil 1711 }, acceptable) 1712 1713 return 1714 } 1715 1716 // Zrevrange is the implementation of redis zrevrange command. 1717 func (s *Redis) Zrevrange(key string, start, stop int64) (val []string, err error) { 1718 err = s.brk.DoWithAcceptable(func() error { 1719 conn, err := getRedis(s) 1720 if err != nil { 1721 return err 1722 } 1723 1724 val, err = conn.ZRevRange(key, start, stop).Result() 1725 return err 1726 }, acceptable) 1727 1728 return 1729 } 1730 1731 // ZrevrangebyscoreWithScores is the implementation of redis zrevrangebyscore command with scores. 1732 func (s *Redis) ZrevrangebyscoreWithScores(key string, start, stop int64) (val []Pair, err error) { 1733 err = s.brk.DoWithAcceptable(func() error { 1734 conn, err := getRedis(s) 1735 if err != nil { 1736 return err 1737 } 1738 1739 v, err := conn.ZRevRangeByScoreWithScores(key, red.ZRangeBy{ 1740 Min: strconv.FormatInt(start, 10), 1741 Max: strconv.FormatInt(stop, 10), 1742 }).Result() 1743 if err != nil { 1744 return err 1745 } 1746 1747 val = toPairs(v) 1748 return nil 1749 }, acceptable) 1750 1751 return 1752 } 1753 1754 // ZrevrangebyscoreWithScoresAndLimit is the implementation of redis zrevrangebyscore command with scores and limit. 1755 func (s *Redis) ZrevrangebyscoreWithScoresAndLimit(key string, start, stop int64, page, size int) ( 1756 val []Pair, err error) { 1757 err = s.brk.DoWithAcceptable(func() error { 1758 if size <= 0 { 1759 return nil 1760 } 1761 1762 conn, err := getRedis(s) 1763 if err != nil { 1764 return err 1765 } 1766 1767 v, err := conn.ZRevRangeByScoreWithScores(key, red.ZRangeBy{ 1768 Min: strconv.FormatInt(start, 10), 1769 Max: strconv.FormatInt(stop, 10), 1770 Offset: int64(page * size), 1771 Count: int64(size), 1772 }).Result() 1773 if err != nil { 1774 return err 1775 } 1776 1777 val = toPairs(v) 1778 return nil 1779 }, acceptable) 1780 1781 return 1782 } 1783 1784 // Zrevrank is the implementation of redis zrevrank command. 1785 func (s *Redis) Zrevrank(key, field string) (val int64, err error) { 1786 err = s.brk.DoWithAcceptable(func() error { 1787 conn, err := getRedis(s) 1788 if err != nil { 1789 return err 1790 } 1791 1792 val, err = conn.ZRevRank(key, field).Result() 1793 return err 1794 }, acceptable) 1795 1796 return 1797 } 1798 1799 // Zunionstore is the implementation of redis zunionstore command. 1800 func (s *Redis) Zunionstore(dest string, store ZStore, keys ...string) (val int64, err error) { 1801 err = s.brk.DoWithAcceptable(func() error { 1802 conn, err := getRedis(s) 1803 if err != nil { 1804 return err 1805 } 1806 1807 val, err = conn.ZUnionStore(dest, store, keys...).Result() 1808 return err 1809 }, acceptable) 1810 1811 return 1812 } 1813 1814 // Cluster customizes the given Redis as a cluster. 1815 func Cluster() Option { 1816 return func(r *Redis) { 1817 r.Type = ClusterType 1818 } 1819 } 1820 1821 // SetSlowThreshold sets the slow threshold. 1822 func SetSlowThreshold(threshold time.Duration) { 1823 slowThreshold.Set(threshold) 1824 } 1825 1826 // WithPass customizes the given Redis with given password. 1827 func WithPass(pass string) Option { 1828 return func(r *Redis) { 1829 r.Pass = pass 1830 } 1831 } 1832 1833 // WithTLS customizes the given Redis with TLS enabled. 1834 func WithTLS() Option { 1835 return func(r *Redis) { 1836 r.tls = true 1837 } 1838 } 1839 1840 func acceptable(err error) bool { 1841 return err == nil || err == red.Nil 1842 } 1843 1844 func getRedis(r *Redis) (RedisNode, error) { 1845 switch r.Type { 1846 case ClusterType: 1847 return getCluster(r) 1848 case NodeType: 1849 return getClient(r) 1850 default: 1851 return nil, fmt.Errorf("redis type '%s' is not supported", r.Type) 1852 } 1853 } 1854 1855 func toPairs(vals []red.Z) []Pair { 1856 pairs := make([]Pair, len(vals)) 1857 for i, val := range vals { 1858 switch member := val.Member.(type) { 1859 case string: 1860 pairs[i] = Pair{ 1861 Key: member, 1862 Score: int64(val.Score), 1863 } 1864 default: 1865 pairs[i] = Pair{ 1866 Key: mapping.Repr(val.Member), 1867 Score: int64(val.Score), 1868 } 1869 } 1870 } 1871 return pairs 1872 } 1873 1874 func toStrings(vals []interface{}) []string { 1875 ret := make([]string, len(vals)) 1876 for i, val := range vals { 1877 if val == nil { 1878 ret[i] = "" 1879 } else { 1880 switch val := val.(type) { 1881 case string: 1882 ret[i] = val 1883 default: 1884 ret[i] = mapping.Repr(val) 1885 } 1886 } 1887 } 1888 return ret 1889 }