mirror of https://github.com/go-redis/redis.git
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.
This commit is contained in:
parent
b3e0aa270a
commit
c2351b491a
17
commands.go
17
commands.go
|
@ -141,6 +141,7 @@ type Cmdable interface {
|
|||
BitField(ctx context.Context, key string, args ...interface{}) *IntSliceCmd
|
||||
|
||||
Scan(ctx context.Context, cursor uint64, match string, count int64) *ScanCmd
|
||||
ScanType(ctx context.Context, cursor uint64, match string, count int64, keyType string) *ScanCmd
|
||||
SScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
|
||||
HScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
|
||||
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
|
|||
return cmd
|
||||
}
|
||||
|
||||
func (c cmdable) ScanType(ctx context.Context, cursor uint64, match string, count int64, keyType string) *ScanCmd {
|
||||
args := []interface{}{"scan", cursor}
|
||||
if match != "" {
|
||||
args = append(args, "match", match)
|
||||
}
|
||||
if count > 0 {
|
||||
args = append(args, "count", count)
|
||||
}
|
||||
if keyType != "" {
|
||||
args = append(args, "type", keyType)
|
||||
}
|
||||
cmd := NewScanCmd(ctx, c, args...)
|
||||
_ = c(ctx, cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c cmdable) SScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd {
|
||||
args := []interface{}{"sscan", key, cursor}
|
||||
if match != "" {
|
||||
|
|
|
@ -770,6 +770,18 @@ var _ = Describe("Commands", func() {
|
|||
Expect(cursor).NotTo(BeZero())
|
||||
})
|
||||
|
||||
It("should ScanType", func() {
|
||||
for i := 0; i < 1000; i++ {
|
||||
set := client.Set(ctx, fmt.Sprintf("key%d", i), "hello", 0)
|
||||
Expect(set.Err()).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
keys, cursor, err := client.ScanType(ctx, 0, "", 0, "string").Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(keys).NotTo(BeEmpty())
|
||||
Expect(cursor).NotTo(BeZero())
|
||||
})
|
||||
|
||||
It("should SScan", func() {
|
||||
for i := 0; i < 1000; i++ {
|
||||
sadd := client.SAdd(ctx, "myset", fmt.Sprintf("member%d", i))
|
||||
|
|
|
@ -248,6 +248,34 @@ func ExampleClient_Scan() {
|
|||
// Output: found 33 keys
|
||||
}
|
||||
|
||||
func ExampleClient_ScanType() {
|
||||
rdb.FlushDB(ctx)
|
||||
for i := 0; i < 33; i++ {
|
||||
err := rdb.Set(ctx, fmt.Sprintf("key%d", i), "value", 0).Err()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
var cursor uint64
|
||||
var n int
|
||||
for {
|
||||
var keys []string
|
||||
var err error
|
||||
keys, cursor, err = rdb.ScanType(ctx, cursor, "key*", 10, "string").Result()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
n += len(keys)
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("found %d keys\n", n)
|
||||
// Output: found 33 keys
|
||||
}
|
||||
|
||||
func ExampleClient_Pipelined() {
|
||||
var incr *redis.IntCmd
|
||||
_, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {
|
||||
|
|
Loading…
Reference in New Issue