Skip to content

Commit c2351b4

Browse files
committed
Add ScanType command to Scan with 'type' option
As of version 6.0 you can use this 'type' option to ask SCAN to only return objects that match a given type, allowing you to iterate through the database looking for keys of a specific type.
1 parent b3e0aa2 commit c2351b4

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

commands.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ type Cmdable interface {
141141
BitField(ctx context.Context, key string, args ...interface{}) *IntSliceCmd
142142

143143
Scan(ctx context.Context, cursor uint64, match string, count int64) *ScanCmd
144+
ScanType(ctx context.Context, cursor uint64, match string, count int64, keyType string) *ScanCmd
144145
SScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
145146
HScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
146147
ZScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
@@ -965,6 +966,22 @@ func (c cmdable) Scan(ctx context.Context, cursor uint64, match string, count in
965966
return cmd
966967
}
967968

969+
func (c cmdable) ScanType(ctx context.Context, cursor uint64, match string, count int64, keyType string) *ScanCmd {
970+
args := []interface{}{"scan", cursor}
971+
if match != "" {
972+
args = append(args, "match", match)
973+
}
974+
if count > 0 {
975+
args = append(args, "count", count)
976+
}
977+
if keyType != "" {
978+
args = append(args, "type", keyType)
979+
}
980+
cmd := NewScanCmd(ctx, c, args...)
981+
_ = c(ctx, cmd)
982+
return cmd
983+
}
984+
968985
func (c cmdable) SScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd {
969986
args := []interface{}{"sscan", key, cursor}
970987
if match != "" {

commands_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,18 @@ var _ = Describe("Commands", func() {
770770
Expect(cursor).NotTo(BeZero())
771771
})
772772

773+
It("should ScanType", func() {
774+
for i := 0; i < 1000; i++ {
775+
set := client.Set(ctx, fmt.Sprintf("key%d", i), "hello", 0)
776+
Expect(set.Err()).NotTo(HaveOccurred())
777+
}
778+
779+
keys, cursor, err := client.ScanType(ctx, 0, "", 0, "string").Result()
780+
Expect(err).NotTo(HaveOccurred())
781+
Expect(keys).NotTo(BeEmpty())
782+
Expect(cursor).NotTo(BeZero())
783+
})
784+
773785
It("should SScan", func() {
774786
for i := 0; i < 1000; i++ {
775787
sadd := client.SAdd(ctx, "myset", fmt.Sprintf("member%d", i))

example_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,34 @@ func ExampleClient_Scan() {
248248
// Output: found 33 keys
249249
}
250250

251+
func ExampleClient_ScanType() {
252+
rdb.FlushDB(ctx)
253+
for i := 0; i < 33; i++ {
254+
err := rdb.Set(ctx, fmt.Sprintf("key%d", i), "value", 0).Err()
255+
if err != nil {
256+
panic(err)
257+
}
258+
}
259+
260+
var cursor uint64
261+
var n int
262+
for {
263+
var keys []string
264+
var err error
265+
keys, cursor, err = rdb.ScanType(ctx, cursor, "key*", 10, "string").Result()
266+
if err != nil {
267+
panic(err)
268+
}
269+
n += len(keys)
270+
if cursor == 0 {
271+
break
272+
}
273+
}
274+
275+
fmt.Printf("found %d keys\n", n)
276+
// Output: found 33 keys
277+
}
278+
251279
func ExampleClient_Pipelined() {
252280
var incr *redis.IntCmd
253281
_, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {

0 commit comments

Comments
 (0)