Merge pull request #1711 from monkey92t/add-cmd

add cmd(getex / getdel / hrandfield / zrandmember)
This commit is contained in:
Vladimir Mihailenco 2021-03-27 17:14:30 +02:00 committed by GitHub
commit 2be507f8e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 133 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, expiration time.Duration) *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
@ -160,6 +162,7 @@ type Cmdable interface {
HMSet(ctx context.Context, key string, values ...interface{}) *BoolCmd
HSetNX(ctx context.Context, key, field string, value interface{}) *BoolCmd
HVals(ctx context.Context, key string) *StringSliceCmd
HRandField(ctx context.Context, key string, count int, withValues bool) *StringSliceCmd
BLPop(ctx context.Context, timeout time.Duration, keys ...string) *StringSliceCmd
BRPop(ctx context.Context, timeout time.Duration, keys ...string) *StringSliceCmd
@ -263,6 +266,7 @@ type Cmdable interface {
ZRevRank(ctx context.Context, key, member string) *IntCmd
ZScore(ctx context.Context, key, member string) *FloatCmd
ZUnionStore(ctx context.Context, dest string, store *ZStore) *IntCmd
ZRandMember(ctx context.Context, key string, count int, withScores bool) *StringSliceCmd
PFAdd(ctx context.Context, key string, els ...interface{}) *IntCmd
PFCount(ctx context.Context, keys ...string) *IntCmd
@ -710,6 +714,33 @@ func (c cmdable) GetSet(ctx context.Context, key string, value interface{}) *Str
return cmd
}
// redis-server version >= 6.2.0.
// A expiration of zero remove the time to live associated with the key(GetEX key persist).
func (c cmdable) GetEX(ctx context.Context, key string, expiration time.Duration) *StringCmd {
args := make([]interface{}, 0, 4)
args = append(args, "getex", key)
if expiration > 0 {
if usePrecise(expiration) {
args = append(args, "px", formatMs(ctx, expiration))
} else {
args = append(args, "ex", formatSec(ctx, expiration))
}
} else if expiration == 0 {
args = append(args, "persist")
}
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)
@ -1182,6 +1213,21 @@ func (c cmdable) HVals(ctx context.Context, key string) *StringSliceCmd {
return cmd
}
// redis-server version >= 6.2.0.
func (c cmdable) HRandField(ctx context.Context, key string, count int, withValues bool) *StringSliceCmd {
args := make([]interface{}, 0, 4)
// Although count=0 is meaningless, redis accepts count=0.
args = append(args, "hrandfield", key, count)
if withValues {
args = append(args, "withvalues")
}
cmd := NewStringSliceCmd(ctx, args...)
_ = c(ctx, cmd)
return cmd
}
//------------------------------------------------------------------------------
func (c cmdable) BLPop(ctx context.Context, timeout time.Duration, keys ...string) *StringSliceCmd {
@ -2256,6 +2302,21 @@ func (c cmdable) ZUnionStore(ctx context.Context, dest string, store *ZStore) *I
return cmd
}
// redis-server version >= 6.2.0.
func (c cmdable) ZRandMember(ctx context.Context, key string, count int, withScores bool) *StringSliceCmd {
args := make([]interface{}, 0, 4)
// Although count=0 is meaningless, redis accepts count=0.
args = append(args, "zrandmember", key, count)
if withScores {
args = append(args, "withscores")
}
cmd := NewStringSliceCmd(ctx, args...)
_ = c(ctx, cmd)
return cmd
}
//------------------------------------------------------------------------------
func (c cmdable) PFAdd(ctx context.Context, key string, els ...interface{}) *IntCmd {

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", 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())
@ -1801,6 +1832,26 @@ var _ = Describe("Commands", func() {
Expect(err).NotTo(HaveOccurred())
Expect(slice).To(Equal([]string{"hello1", "hello2"}))
})
It("should HRandField", func() {
err := client.HSet(ctx, "hash", "key1", "hello1").Err()
Expect(err).NotTo(HaveOccurred())
err = client.HSet(ctx, "hash", "key2", "hello2").Err()
Expect(err).NotTo(HaveOccurred())
v := client.HRandField(ctx, "hash", 1, false)
Expect(v.Err()).NotTo(HaveOccurred())
Expect(v.Val()).To(Or(Equal([]string{"key1"}), Equal([]string{"key2"})))
v = client.HRandField(ctx, "hash", 0, false)
Expect(v.Err()).NotTo(HaveOccurred())
Expect(v.Val()).To(HaveLen(0))
var slice []string
err = client.HRandField(ctx, "hash", 1, true).ScanSlice(&slice)
Expect(err).NotTo(HaveOccurred())
Expect(slice).To(Or(Equal([]string{"key1", "hello1"}), Equal([]string{"key2", "hello2"})))
})
})
Describe("hyperloglog", func() {
@ -3839,6 +3890,26 @@ var _ = Describe("Commands", func() {
Member: "two",
}}))
})
It("should ZRandMember", func() {
err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err()
Expect(err).NotTo(HaveOccurred())
err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err()
Expect(err).NotTo(HaveOccurred())
v := client.ZRandMember(ctx, "zset", 1, false)
Expect(v.Err()).NotTo(HaveOccurred())
Expect(v.Val()).To(Or(Equal([]string{"one"}), Equal([]string{"two"})))
v = client.ZRandMember(ctx, "zset", 0, false)
Expect(v.Err()).NotTo(HaveOccurred())
Expect(v.Val()).To(HaveLen(0))
var slice []string
err = client.ZRandMember(ctx, "zset", 1, true).ScanSlice(&slice)
Expect(err).NotTo(HaveOccurred())
Expect(slice).To(Or(Equal([]string{"one", "1"}), Equal([]string{"two", "2"})))
})
})
Describe("streams", func() {