@@ -9,11 +9,18 @@ import (
9
9
"github.com/go-redis/redis/v8/internal"
10
10
)
11
11
12
- // KeepTTL is an option for Set command to keep key's existing TTL.
13
- // For example:
14
- //
15
- // rdb.Set(ctx, key, value, redis.KeepTTL)
16
- const KeepTTL = - 1
12
+ const (
13
+ // KeepTTL is an option for Set command to keep key's existing TTL.
14
+ // For example:
15
+ //
16
+ // rdb.Set(ctx, key, value, redis.KeepTTL)
17
+ KeepTTL = - 1
18
+
19
+ // Persist is remove the time to live associated with the key.
20
+ // For example:
21
+ // rdb.GetEX(ctx, key, redis.Persist)
22
+ Persist = - 2
23
+ )
17
24
18
25
func usePrecise (dur time.Duration ) bool {
19
26
return dur < time .Second || dur % time .Second != 0
@@ -117,7 +124,7 @@ type Cmdable interface {
117
124
Get (ctx context.Context , key string ) * StringCmd
118
125
GetRange (ctx context.Context , key string , start , end int64 ) * StringCmd
119
126
GetSet (ctx context.Context , key string , value interface {}) * StringCmd
120
- GetEX (ctx context.Context , key string , ttl * SetTTL ) * StringCmd
127
+ GetEX (ctx context.Context , key string , expiration time. Duration ) * StringCmd
121
128
GetDel (ctx context.Context , key string ) * StringCmd
122
129
Incr (ctx context.Context , key string ) * IntCmd
123
130
IncrBy (ctx context.Context , key string , value int64 ) * IntCmd
@@ -162,6 +169,7 @@ type Cmdable interface {
162
169
HMSet (ctx context.Context , key string , values ... interface {}) * BoolCmd
163
170
HSetNX (ctx context.Context , key , field string , value interface {}) * BoolCmd
164
171
HVals (ctx context.Context , key string ) * StringSliceCmd
172
+ HRandField (ctx context.Context , key string , count int , withValues bool ) * StringSliceCmd
165
173
166
174
BLPop (ctx context.Context , timeout time.Duration , keys ... string ) * StringSliceCmd
167
175
BRPop (ctx context.Context , timeout time.Duration , keys ... string ) * StringSliceCmd
@@ -265,6 +273,7 @@ type Cmdable interface {
265
273
ZRevRank (ctx context.Context , key , member string ) * IntCmd
266
274
ZScore (ctx context.Context , key , member string ) * FloatCmd
267
275
ZUnionStore (ctx context.Context , dest string , store * ZStore ) * IntCmd
276
+ ZRandMember (ctx context.Context , key string , count int , withScores bool ) * StringSliceCmd
268
277
269
278
PFAdd (ctx context.Context , key string , els ... interface {}) * IntCmd
270
279
PFCount (ctx context.Context , keys ... string ) * IntCmd
@@ -363,58 +372,6 @@ type statefulCmdable func(ctx context.Context, cmd Cmder) error
363
372
364
373
//------------------------------------------------------------------------------
365
374
366
- type ttlAttr int
367
-
368
- const (
369
- TExpire ttlAttr = 1 << iota
370
- TExpireAT
371
- TKeepTTL
372
- TPersist
373
- )
374
-
375
- // TTL related parameters, not all commands support all ttl attributes.
376
- // priority: Expire > ExpireAt > KeepTTL > Persist
377
- type SetTTL struct {
378
- // set the specified expire time.
379
- // Expire > time.Second AND Expire % time.Second == 0: set key EX Expire/time.Second
380
- // Expire < time.Second OR Expire % time.Second != 0: set key PX Expire/time.Millisecond
381
- Expire time.Duration
382
-
383
- // set the specified Unix time at which the key will expire.
384
- // Example: set key EXAT ExpireAt.Unix()
385
- // Don't consider milliseconds for now(PXAT)
386
- ExpireAt time.Time
387
-
388
- // Retain the time to live associated with the key.
389
- KeepTTL bool
390
-
391
- // Remove the time to live associated with the key, Change to never expire
392
- Persist bool
393
- }
394
-
395
- func appendTTL (ctx context.Context , args []interface {}, t * SetTTL , attr ttlAttr ) []interface {} {
396
- if t == nil {
397
- return args
398
- }
399
-
400
- switch {
401
- case attr & TExpire == 1 && t .Expire > 0 :
402
- if usePrecise (t .Expire ) {
403
- args = append (args , "px" , formatMs (ctx , t .Expire ))
404
- } else {
405
- args = append (args , "ex" , formatSec (ctx , t .Expire ))
406
- }
407
- case attr & TExpireAT == 1 && ! t .ExpireAt .IsZero ():
408
- args = append (args , "exat" , t .ExpireAt .Unix ())
409
- case attr & TKeepTTL == 1 && t .KeepTTL :
410
- args = append (args , "keepttl" )
411
- case attr & TPersist == 1 && t .Persist :
412
- args = append (args , "persist" )
413
- }
414
-
415
- return args
416
- }
417
-
418
375
func (c statefulCmdable ) Auth (ctx context.Context , password string ) * StatusCmd {
419
376
cmd := NewStatusCmd (ctx , "auth" , password )
420
377
_ = c (ctx , cmd )
@@ -764,17 +721,29 @@ func (c cmdable) GetSet(ctx context.Context, key string, value interface{}) *Str
764
721
return cmd
765
722
}
766
723
767
- // redis-server version >= 6.2.0
768
- func (c cmdable ) GetEX (ctx context.Context , key string , ttl * SetTTL ) * StringCmd {
769
- args := make ([]interface {}, 2 , 4 )
724
+ // redis-server version >= 6.2.0.
725
+ //
726
+ // A value of zero means that the expiration time will not be changed.
727
+ // Persist(-2) Remove the time to live associated with the key.
728
+ func (c cmdable ) GetEX (ctx context.Context , key string , expiration time.Duration ) * StringCmd {
729
+ args := make ([]interface {}, 0 , 4 )
770
730
args = append (args , "getex" , key )
771
- args = appendTTL (ctx , args , ttl , TExpire | TExpireAT | TPersist )
731
+ if expiration > 0 {
732
+ if usePrecise (expiration ) {
733
+ args = append (args , "px" , formatMs (ctx , expiration ))
734
+ } else {
735
+ args = append (args , "ex" , formatSec (ctx , expiration ))
736
+ }
737
+ } else if expiration == Persist {
738
+ args = append (args , "persist" )
739
+ }
740
+
772
741
cmd := NewStringCmd (ctx , args ... )
773
742
_ = c (ctx , cmd )
774
743
return cmd
775
744
}
776
745
777
- // redis-server version >= 6.2.0
746
+ // redis-server version >= 6.2.0.
778
747
func (c cmdable ) GetDel (ctx context.Context , key string ) * StringCmd {
779
748
cmd := NewStringCmd (ctx , "getdel" , key )
780
749
_ = c (ctx , cmd )
@@ -1253,6 +1222,20 @@ func (c cmdable) HVals(ctx context.Context, key string) *StringSliceCmd {
1253
1222
return cmd
1254
1223
}
1255
1224
1225
+ func (c cmdable ) HRandField (ctx context.Context , key string , count int , withValues bool ) * StringSliceCmd {
1226
+ args := make ([]interface {}, 0 , 4 )
1227
+
1228
+ // Although count=0 is meaningless, redis accepts count=0.
1229
+ args = append (args , "hrandfield" , key , count )
1230
+ if withValues {
1231
+ args = append (args , "withvalues" )
1232
+ }
1233
+
1234
+ cmd := NewStringSliceCmd (ctx , args ... )
1235
+ _ = c (ctx , cmd )
1236
+ return cmd
1237
+ }
1238
+
1256
1239
//------------------------------------------------------------------------------
1257
1240
1258
1241
func (c cmdable ) BLPop (ctx context.Context , timeout time.Duration , keys ... string ) * StringSliceCmd {
@@ -2327,6 +2310,18 @@ func (c cmdable) ZUnionStore(ctx context.Context, dest string, store *ZStore) *I
2327
2310
return cmd
2328
2311
}
2329
2312
2313
+ func (c cmdable ) ZRandMember (ctx context.Context , key string , count int , withScores bool ) * StringSliceCmd {
2314
+ args := make ([]interface {}, 0 , 4 )
2315
+ args = append (args , "zrandmember" , key , count )
2316
+ if withScores {
2317
+ args = append (args , "withscores" )
2318
+ }
2319
+
2320
+ cmd := NewStringSliceCmd (ctx , args ... )
2321
+ _ = c (ctx , cmd )
2322
+ return cmd
2323
+ }
2324
+
2330
2325
//------------------------------------------------------------------------------
2331
2326
2332
2327
func (c cmdable ) PFAdd (ctx context.Context , key string , els ... interface {}) * IntCmd {
0 commit comments