@@ -117,6 +117,8 @@ type Cmdable interface {
117117 Get (ctx context.Context , key string ) * StringCmd
118118 GetRange (ctx context.Context , key string , start , end int64 ) * StringCmd
119119 GetSet (ctx context.Context , key string , value interface {}) * StringCmd
120+ GetEX (ctx context.Context , key string , ttl * SetTTL ) * StringCmd
121+ GetDel (ctx context.Context , key string ) * StringCmd
120122 Incr (ctx context.Context , key string ) * IntCmd
121123 IncrBy (ctx context.Context , key string , value int64 ) * IntCmd
122124 IncrByFloat (ctx context.Context , key string , value float64 ) * FloatCmd
@@ -361,6 +363,58 @@ type statefulCmdable func(ctx context.Context, cmd Cmder) error
361363
362364//------------------------------------------------------------------------------
363365
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+
364418func (c statefulCmdable ) Auth (ctx context.Context , password string ) * StatusCmd {
365419 cmd := NewStatusCmd (ctx , "auth" , password )
366420 _ = c (ctx , cmd )
@@ -710,6 +764,23 @@ func (c cmdable) GetSet(ctx context.Context, key string, value interface{}) *Str
710764 return cmd
711765}
712766
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 )
770+ args = append (args , "getex" , key )
771+ args = appendTTL (ctx , args , ttl , TExpire | TExpireAT | TPersist )
772+ cmd := NewStringCmd (ctx , args ... )
773+ _ = c (ctx , cmd )
774+ return cmd
775+ }
776+
777+ // redis-server version >= 6.2.0
778+ func (c cmdable ) GetDel (ctx context.Context , key string ) * StringCmd {
779+ cmd := NewStringCmd (ctx , "getdel" , key )
780+ _ = c (ctx , cmd )
781+ return cmd
782+ }
783+
713784func (c cmdable ) Incr (ctx context.Context , key string ) * IntCmd {
714785 cmd := NewIntCmd (ctx , "incr" , key )
715786 _ = c (ctx , cmd )
0 commit comments