add new cmd: getEX getDel

Signed-off-by: monkey <golang@88.com>
This commit is contained in:
monkey 2021-03-26 17:13:22 +08:00
parent 55db07d5d1
commit cb1be727e3
2 changed files with 103 additions and 1 deletions

View File

@ -117,6 +117,8 @@ type Cmdable interface {
Get(ctx context.Context, key string) *StringCmd
GetRange(ctx context.Context, key string, start, end int64) *StringCmd
GetSet(ctx context.Context, key string, value interface{}) *StringCmd
GetEX(ctx context.Context, key string, ttl *SetTTL) *StringCmd
GetDel(ctx context.Context, key string) *StringCmd
Incr(ctx context.Context, key string) *IntCmd
IncrBy(ctx context.Context, key string, value int64) *IntCmd
IncrByFloat(ctx context.Context, key string, value float64) *FloatCmd
@ -361,6 +363,58 @@ type statefulCmdable func(ctx context.Context, cmd Cmder) error
//------------------------------------------------------------------------------
type ttlAttr int
const (
TExpire ttlAttr = 1 << iota
TExpireAT
TKeepTTL
TPersist
)
// TTL related parameters, not all commands support all ttl attributes.
// priority: Expire > ExpireAt > KeepTTL > Persist
type SetTTL struct {
// set the specified expire time.
// Expire > time.Second AND Expire % time.Second == 0: set key EX Expire/time.Second
// Expire < time.Second OR Expire % time.Second != 0: set key PX Expire/time.Millisecond
Expire time.Duration
// set the specified Unix time at which the key will expire.
// Example: set key EXAT ExpireAt.Unix()
// Don't consider milliseconds for now(PXAT)
ExpireAt time.Time
// Retain the time to live associated with the key.
KeepTTL bool
// Remove the time to live associated with the key, Change to never expire
Persist bool
}
func appendTTL(ctx context.Context, args []interface{}, t *SetTTL, attr ttlAttr) []interface{} {
if t == nil {
return args
}
switch {
case attr&TExpire == 1 && t.Expire > 0:
if usePrecise(t.Expire) {
args = append(args, "px", formatMs(ctx, t.Expire))
} else {
args = append(args, "ex", formatSec(ctx, t.Expire))
}
case attr&TExpireAT == 1 && !t.ExpireAt.IsZero():
args = append(args, "exat", t.ExpireAt.Unix())
case attr&TKeepTTL == 1 && t.KeepTTL:
args = append(args, "keepttl")
case attr&TPersist == 1 && t.Persist:
args = append(args, "persist")
}
return args
}
func (c statefulCmdable) Auth(ctx context.Context, password string) *StatusCmd {
cmd := NewStatusCmd(ctx, "auth", password)
_ = c(ctx, cmd)
@ -710,6 +764,23 @@ func (c cmdable) GetSet(ctx context.Context, key string, value interface{}) *Str
return cmd
}
// redis-server version >= 6.2.0
func (c cmdable) GetEX(ctx context.Context, key string, ttl *SetTTL) *StringCmd {
args := make([]interface{}, 2, 4)
args = append(args, "getex", key)
args = appendTTL(ctx, args, ttl, TExpire|TExpireAT|TPersist)
cmd := NewStringCmd(ctx, args...)
_ = c(ctx, cmd)
return cmd
}
// redis-server version >= 6.2.0
func (c cmdable) GetDel(ctx context.Context, key string) *StringCmd {
cmd := NewStringCmd(ctx, "getdel", key)
_ = c(ctx, cmd)
return cmd
}
func (c cmdable) Incr(ctx context.Context, key string) *IntCmd {
cmd := NewIntCmd(ctx, "incr", key)
_ = c(ctx, cmd)

View File

@ -477,7 +477,7 @@ var _ = Describe("Commands", func() {
//if too much time (>1s) is used during command execution, it may also cause the test to fail.
//so the ObjectIdleTime result should be <=now-start+1s
//link: https://github.com/redis/redis/blob/5b48d900498c85bbf4772c1d466c214439888115/src/object.c#L1265-L1272
Expect(idleTime.Val()).To(BeNumerically("<=", time.Now().Sub(start) + time.Second))
Expect(idleTime.Val()).To(BeNumerically("<=", time.Now().Sub(start)+time.Second))
})
It("should Persist", func() {
@ -1083,6 +1083,37 @@ var _ = Describe("Commands", func() {
Expect(get.Val()).To(Equal("0"))
})
It("should GetEX", func() {
set := client.Set(ctx, "key", "value", 100*time.Second)
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
ttl := client.TTL(ctx, "key")
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val()).To(BeNumerically("~", 100*time.Second, 3*time.Second))
getEX := client.GetEX(ctx, "key", &redis.SetTTL{Expire: 200 * time.Second})
Expect(getEX.Err()).NotTo(HaveOccurred())
Expect(getEX.Val()).To(Equal("value"))
ttl = client.TTL(ctx, "key")
Expect(ttl.Err()).NotTo(HaveOccurred())
Expect(ttl.Val()).To(BeNumerically("~", 200*time.Second, 3*time.Second))
})
It("should GetDel", func() {
set := client.Set(ctx, "key", "value", 0)
Expect(set.Err()).NotTo(HaveOccurred())
Expect(set.Val()).To(Equal("OK"))
getDel := client.GetDel(ctx, "key")
Expect(getDel.Err()).NotTo(HaveOccurred())
Expect(getDel.Val()).To(Equal("value"))
get := client.Get(ctx, "key")
Expect(get.Err()).To(Equal(redis.Nil))
})
It("should Incr", func() {
set := client.Set(ctx, "key", "10", 0)
Expect(set.Err()).NotTo(HaveOccurred())