Skip to content

Commit 2be507f

Browse files
authored
Merge pull request #1711 from monkey92t/add-cmd
add cmd(getex / getdel / hrandfield / zrandmember)
2 parents 55db07d + e3ce4ea commit 2be507f

File tree

2 files changed

+133
-1
lines changed

2 files changed

+133
-1
lines changed

commands.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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, expiration time.Duration) *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
@@ -160,6 +162,7 @@ type Cmdable interface {
160162
HMSet(ctx context.Context, key string, values ...interface{}) *BoolCmd
161163
HSetNX(ctx context.Context, key, field string, value interface{}) *BoolCmd
162164
HVals(ctx context.Context, key string) *StringSliceCmd
165+
HRandField(ctx context.Context, key string, count int, withValues bool) *StringSliceCmd
163166

164167
BLPop(ctx context.Context, timeout time.Duration, keys ...string) *StringSliceCmd
165168
BRPop(ctx context.Context, timeout time.Duration, keys ...string) *StringSliceCmd
@@ -263,6 +266,7 @@ type Cmdable interface {
263266
ZRevRank(ctx context.Context, key, member string) *IntCmd
264267
ZScore(ctx context.Context, key, member string) *FloatCmd
265268
ZUnionStore(ctx context.Context, dest string, store *ZStore) *IntCmd
269+
ZRandMember(ctx context.Context, key string, count int, withScores bool) *StringSliceCmd
266270

267271
PFAdd(ctx context.Context, key string, els ...interface{}) *IntCmd
268272
PFCount(ctx context.Context, keys ...string) *IntCmd
@@ -710,6 +714,33 @@ func (c cmdable) GetSet(ctx context.Context, key string, value interface{}) *Str
710714
return cmd
711715
}
712716

717+
// redis-server version >= 6.2.0.
718+
// A expiration of zero remove the time to live associated with the key(GetEX key persist).
719+
func (c cmdable) GetEX(ctx context.Context, key string, expiration time.Duration) *StringCmd {
720+
args := make([]interface{}, 0, 4)
721+
args = append(args, "getex", key)
722+
if expiration > 0 {
723+
if usePrecise(expiration) {
724+
args = append(args, "px", formatMs(ctx, expiration))
725+
} else {
726+
args = append(args, "ex", formatSec(ctx, expiration))
727+
}
728+
} else if expiration == 0 {
729+
args = append(args, "persist")
730+
}
731+
732+
cmd := NewStringCmd(ctx, args...)
733+
_ = c(ctx, cmd)
734+
return cmd
735+
}
736+
737+
// redis-server version >= 6.2.0.
738+
func (c cmdable) GetDel(ctx context.Context, key string) *StringCmd {
739+
cmd := NewStringCmd(ctx, "getdel", key)
740+
_ = c(ctx, cmd)
741+
return cmd
742+
}
743+
713744
func (c cmdable) Incr(ctx context.Context, key string) *IntCmd {
714745
cmd := NewIntCmd(ctx, "incr", key)
715746
_ = c(ctx, cmd)
@@ -1182,6 +1213,21 @@ func (c cmdable) HVals(ctx context.Context, key string) *StringSliceCmd {
11821213
return cmd
11831214
}
11841215

1216+
// redis-server version >= 6.2.0.
1217+
func (c cmdable) HRandField(ctx context.Context, key string, count int, withValues bool) *StringSliceCmd {
1218+
args := make([]interface{}, 0, 4)
1219+
1220+
// Although count=0 is meaningless, redis accepts count=0.
1221+
args = append(args, "hrandfield", key, count)
1222+
if withValues {
1223+
args = append(args, "withvalues")
1224+
}
1225+
1226+
cmd := NewStringSliceCmd(ctx, args...)
1227+
_ = c(ctx, cmd)
1228+
return cmd
1229+
}
1230+
11851231
//------------------------------------------------------------------------------
11861232

11871233
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
22562302
return cmd
22572303
}
22582304

2305+
// redis-server version >= 6.2.0.
2306+
func (c cmdable) ZRandMember(ctx context.Context, key string, count int, withScores bool) *StringSliceCmd {
2307+
args := make([]interface{}, 0, 4)
2308+
2309+
// Although count=0 is meaningless, redis accepts count=0.
2310+
args = append(args, "zrandmember", key, count)
2311+
if withScores {
2312+
args = append(args, "withscores")
2313+
}
2314+
2315+
cmd := NewStringSliceCmd(ctx, args...)
2316+
_ = c(ctx, cmd)
2317+
return cmd
2318+
}
2319+
22592320
//------------------------------------------------------------------------------
22602321

22612322
func (c cmdable) PFAdd(ctx context.Context, key string, els ...interface{}) *IntCmd {

commands_test.go

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ var _ = Describe("Commands", func() {
477477
//if too much time (>1s) is used during command execution, it may also cause the test to fail.
478478
//so the ObjectIdleTime result should be <=now-start+1s
479479
//link: https://github.com/redis/redis/blob/5b48d900498c85bbf4772c1d466c214439888115/src/object.c#L1265-L1272
480-
Expect(idleTime.Val()).To(BeNumerically("<=", time.Now().Sub(start) + time.Second))
480+
Expect(idleTime.Val()).To(BeNumerically("<=", time.Now().Sub(start)+time.Second))
481481
})
482482

483483
It("should Persist", func() {
@@ -1083,6 +1083,37 @@ var _ = Describe("Commands", func() {
10831083
Expect(get.Val()).To(Equal("0"))
10841084
})
10851085

1086+
It("should GetEX", func() {
1087+
set := client.Set(ctx, "key", "value", 100*time.Second)
1088+
Expect(set.Err()).NotTo(HaveOccurred())
1089+
Expect(set.Val()).To(Equal("OK"))
1090+
1091+
ttl := client.TTL(ctx, "key")
1092+
Expect(ttl.Err()).NotTo(HaveOccurred())
1093+
Expect(ttl.Val()).To(BeNumerically("~", 100*time.Second, 3*time.Second))
1094+
1095+
getEX := client.GetEX(ctx, "key", 200*time.Second)
1096+
Expect(getEX.Err()).NotTo(HaveOccurred())
1097+
Expect(getEX.Val()).To(Equal("value"))
1098+
1099+
ttl = client.TTL(ctx, "key")
1100+
Expect(ttl.Err()).NotTo(HaveOccurred())
1101+
Expect(ttl.Val()).To(BeNumerically("~", 200*time.Second, 3*time.Second))
1102+
})
1103+
1104+
It("should GetDel", func() {
1105+
set := client.Set(ctx, "key", "value", 0)
1106+
Expect(set.Err()).NotTo(HaveOccurred())
1107+
Expect(set.Val()).To(Equal("OK"))
1108+
1109+
getDel := client.GetDel(ctx, "key")
1110+
Expect(getDel.Err()).NotTo(HaveOccurred())
1111+
Expect(getDel.Val()).To(Equal("value"))
1112+
1113+
get := client.Get(ctx, "key")
1114+
Expect(get.Err()).To(Equal(redis.Nil))
1115+
})
1116+
10861117
It("should Incr", func() {
10871118
set := client.Set(ctx, "key", "10", 0)
10881119
Expect(set.Err()).NotTo(HaveOccurred())
@@ -1801,6 +1832,26 @@ var _ = Describe("Commands", func() {
18011832
Expect(err).NotTo(HaveOccurred())
18021833
Expect(slice).To(Equal([]string{"hello1", "hello2"}))
18031834
})
1835+
1836+
It("should HRandField", func() {
1837+
err := client.HSet(ctx, "hash", "key1", "hello1").Err()
1838+
Expect(err).NotTo(HaveOccurred())
1839+
err = client.HSet(ctx, "hash", "key2", "hello2").Err()
1840+
Expect(err).NotTo(HaveOccurred())
1841+
1842+
v := client.HRandField(ctx, "hash", 1, false)
1843+
Expect(v.Err()).NotTo(HaveOccurred())
1844+
Expect(v.Val()).To(Or(Equal([]string{"key1"}), Equal([]string{"key2"})))
1845+
1846+
v = client.HRandField(ctx, "hash", 0, false)
1847+
Expect(v.Err()).NotTo(HaveOccurred())
1848+
Expect(v.Val()).To(HaveLen(0))
1849+
1850+
var slice []string
1851+
err = client.HRandField(ctx, "hash", 1, true).ScanSlice(&slice)
1852+
Expect(err).NotTo(HaveOccurred())
1853+
Expect(slice).To(Or(Equal([]string{"key1", "hello1"}), Equal([]string{"key2", "hello2"})))
1854+
})
18041855
})
18051856

18061857
Describe("hyperloglog", func() {
@@ -3839,6 +3890,26 @@ var _ = Describe("Commands", func() {
38393890
Member: "two",
38403891
}}))
38413892
})
3893+
3894+
It("should ZRandMember", func() {
3895+
err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err()
3896+
Expect(err).NotTo(HaveOccurred())
3897+
err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err()
3898+
Expect(err).NotTo(HaveOccurred())
3899+
3900+
v := client.ZRandMember(ctx, "zset", 1, false)
3901+
Expect(v.Err()).NotTo(HaveOccurred())
3902+
Expect(v.Val()).To(Or(Equal([]string{"one"}), Equal([]string{"two"})))
3903+
3904+
v = client.ZRandMember(ctx, "zset", 0, false)
3905+
Expect(v.Err()).NotTo(HaveOccurred())
3906+
Expect(v.Val()).To(HaveLen(0))
3907+
3908+
var slice []string
3909+
err = client.ZRandMember(ctx, "zset", 1, true).ScanSlice(&slice)
3910+
Expect(err).NotTo(HaveOccurred())
3911+
Expect(slice).To(Or(Equal([]string{"one", "1"}), Equal([]string{"two", "2"})))
3912+
})
38423913
})
38433914

38443915
Describe("streams", func() {

0 commit comments

Comments
 (0)