mirror of
https://github.com/redis/go-redis.git
synced 2026-10-28 08:24:54 +08:00
* Add support for iter.Seq for ScanIterator * Simplify Vals * Review fixes
239 lines
6.8 KiB
Go
239 lines
6.8 KiB
Go
package redis_test
|
|
|
|
import (
|
|
"fmt"
|
|
"slices"
|
|
|
|
. "github.com/bsm/ginkgo/v2"
|
|
. "github.com/bsm/gomega"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
var _ = Describe("ScanIterator", func() {
|
|
var client redis.UniversalClient
|
|
var rawClient *redis.Client
|
|
var closeSubject func() error
|
|
|
|
seed := func(n int) error {
|
|
pipe := client.Pipeline()
|
|
for i := 1; i <= n; i++ {
|
|
pipe.Set(ctx, fmt.Sprintf("K%02d", i), "x", 0).Err()
|
|
}
|
|
_, err := pipe.Exec(ctx)
|
|
return err
|
|
}
|
|
|
|
extraSeed := func(n int, m int) error {
|
|
pipe := client.Pipeline()
|
|
for i := 1; i <= m; i++ {
|
|
pipe.Set(ctx, fmt.Sprintf("A%02d", i), "x", 0).Err()
|
|
}
|
|
for i := 1; i <= n; i++ {
|
|
pipe.Set(ctx, fmt.Sprintf("K%02d", i), "x", 0).Err()
|
|
}
|
|
_, err := pipe.Exec(ctx)
|
|
return err
|
|
}
|
|
|
|
hashKey := "K_HASHTEST"
|
|
hashSeed := func(n int) error {
|
|
pipe := client.Pipeline()
|
|
for i := 1; i <= n; i++ {
|
|
pipe.HSet(ctx, hashKey, fmt.Sprintf("K%02d", i), "x").Err()
|
|
}
|
|
_, err := pipe.Exec(ctx)
|
|
return err
|
|
}
|
|
|
|
BeforeEach(func() {
|
|
rawClient = redis.NewClient(redisOptions())
|
|
client, closeSubject = newUniversalSubject(rawClient)
|
|
Expect(rawClient.FlushDB(ctx).Err()).NotTo(HaveOccurred())
|
|
})
|
|
|
|
AfterEach(func() {
|
|
Expect(closeSubject()).NotTo(HaveOccurred())
|
|
})
|
|
|
|
It("should scan across empty DBs using Next", func() {
|
|
iter := client.Scan(ctx, 0, "", 10).Iterator()
|
|
Expect(iter.Next(ctx)).To(BeFalse())
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
})
|
|
|
|
It("should scan across empty DBs using Vals", func() {
|
|
iter := client.Scan(ctx, 0, "", 10).Iterator()
|
|
vals := slices.Collect(iter.Vals(ctx))
|
|
Expect(vals).To(BeEmpty())
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
})
|
|
|
|
It("should scan across one page using Next", func() {
|
|
Expect(seed(7)).NotTo(HaveOccurred())
|
|
|
|
var vals []string
|
|
iter := client.Scan(ctx, 0, "", 0).Iterator()
|
|
for iter.Next(ctx) {
|
|
vals = append(vals, iter.Val())
|
|
}
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(ConsistOf([]string{"K01", "K02", "K03", "K04", "K05", "K06", "K07"}))
|
|
})
|
|
|
|
It("should scan across one page using Vals", func() {
|
|
Expect(seed(7)).NotTo(HaveOccurred())
|
|
|
|
iter := client.Scan(ctx, 0, "", 0).Iterator()
|
|
vals := slices.Collect(iter.Vals(ctx))
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(ConsistOf([]string{"K01", "K02", "K03", "K04", "K05", "K06", "K07"}))
|
|
})
|
|
|
|
It("should scan across multiple pages using Next", func() {
|
|
Expect(seed(71)).NotTo(HaveOccurred())
|
|
|
|
var vals []string
|
|
iter := client.Scan(ctx, 0, "", 10).Iterator()
|
|
for iter.Next(ctx) {
|
|
vals = append(vals, iter.Val())
|
|
}
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(71))
|
|
Expect(vals).To(ContainElement("K01"))
|
|
Expect(vals).To(ContainElement("K71"))
|
|
})
|
|
|
|
It("should scan across multiple pages using Vals", func() {
|
|
Expect(seed(71)).NotTo(HaveOccurred())
|
|
|
|
iter := client.Scan(ctx, 0, "", 10).Iterator()
|
|
vals := slices.Collect(iter.Vals(ctx))
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(71))
|
|
Expect(vals).To(ContainElement("K01"))
|
|
Expect(vals).To(ContainElement("K71"))
|
|
})
|
|
|
|
It("should hscan across multiple pages using Next", func() {
|
|
SkipBeforeRedisVersion("7.4", "doesn't work with older redis stack images")
|
|
Expect(hashSeed(71)).NotTo(HaveOccurred())
|
|
|
|
var vals []string
|
|
iter := client.HScan(ctx, hashKey, 0, "", 10).Iterator()
|
|
for iter.Next(ctx) {
|
|
vals = append(vals, iter.Val())
|
|
}
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(71 * 2))
|
|
Expect(vals).To(ContainElement("K01"))
|
|
Expect(vals).To(ContainElement("K71"))
|
|
Expect(vals).To(ContainElement("x"))
|
|
})
|
|
|
|
It("should hscan across multiple pages using Vals", func() {
|
|
SkipBeforeRedisVersion("7.4", "doesn't work with older redis stack images")
|
|
Expect(hashSeed(71)).NotTo(HaveOccurred())
|
|
|
|
iter := client.HScan(ctx, hashKey, 0, "", 10).Iterator()
|
|
vals := slices.Collect(iter.Vals(ctx))
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(71 * 2))
|
|
Expect(vals).To(ContainElement("K01"))
|
|
Expect(vals).To(ContainElement("K71"))
|
|
Expect(vals).To(ContainElement("x"))
|
|
})
|
|
|
|
It("should hscan without values across multiple pages using Next", Label("NonRedisEnterprise"), func() {
|
|
SkipBeforeRedisVersion("7.4", "doesn't work with older redis stack images")
|
|
Expect(hashSeed(71)).NotTo(HaveOccurred())
|
|
|
|
var vals []string
|
|
iter := client.HScanNoValues(ctx, hashKey, 0, "", 10).Iterator()
|
|
for iter.Next(ctx) {
|
|
vals = append(vals, iter.Val())
|
|
}
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(71))
|
|
Expect(vals).To(ContainElement("K01"))
|
|
Expect(vals).To(ContainElement("K71"))
|
|
Expect(vals).NotTo(ContainElement("x"))
|
|
})
|
|
|
|
It("should hscan without values across multiple pages using Vals", Label("NonRedisEnterprise"), func() {
|
|
SkipBeforeRedisVersion("7.4", "doesn't work with older redis stack images")
|
|
Expect(hashSeed(71)).NotTo(HaveOccurred())
|
|
|
|
iter := client.HScanNoValues(ctx, hashKey, 0, "", 10).Iterator()
|
|
vals := slices.Collect(iter.Vals(ctx))
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(71))
|
|
Expect(vals).To(ContainElement("K01"))
|
|
Expect(vals).To(ContainElement("K71"))
|
|
Expect(vals).NotTo(ContainElement("x"))
|
|
})
|
|
|
|
It("should scan to page borders using Next", func() {
|
|
Expect(seed(20)).NotTo(HaveOccurred())
|
|
|
|
var vals []string
|
|
iter := client.Scan(ctx, 0, "", 10).Iterator()
|
|
for iter.Next(ctx) {
|
|
vals = append(vals, iter.Val())
|
|
}
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(20))
|
|
})
|
|
|
|
It("should scan to page borders using Vals", func() {
|
|
Expect(seed(20)).NotTo(HaveOccurred())
|
|
|
|
iter := client.Scan(ctx, 0, "", 10).Iterator()
|
|
vals := slices.Collect(iter.Vals(ctx))
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(20))
|
|
})
|
|
|
|
It("should scan with match using Next", func() {
|
|
Expect(seed(33)).NotTo(HaveOccurred())
|
|
|
|
var vals []string
|
|
iter := client.Scan(ctx, 0, "K*2*", 10).Iterator()
|
|
for iter.Next(ctx) {
|
|
vals = append(vals, iter.Val())
|
|
}
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(13))
|
|
})
|
|
|
|
It("should scan with match using Vals", func() {
|
|
Expect(seed(33)).NotTo(HaveOccurred())
|
|
|
|
iter := client.Scan(ctx, 0, "K*2*", 10).Iterator()
|
|
vals := slices.Collect(iter.Vals(ctx))
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(13))
|
|
})
|
|
|
|
It("should scan with match across empty pages using Next", func() {
|
|
Expect(extraSeed(2, 10)).NotTo(HaveOccurred())
|
|
|
|
var vals []string
|
|
iter := client.Scan(ctx, 0, "K*", 1).Iterator()
|
|
for iter.Next(ctx) {
|
|
vals = append(vals, iter.Val())
|
|
}
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(2))
|
|
})
|
|
|
|
It("should scan with match across empty pages using Vals", func() {
|
|
Expect(extraSeed(2, 10)).NotTo(HaveOccurred())
|
|
|
|
iter := client.Scan(ctx, 0, "K*", 1).Iterator()
|
|
vals := slices.Collect(iter.Vals(ctx))
|
|
Expect(iter.Err()).NotTo(HaveOccurred())
|
|
Expect(vals).To(HaveLen(2))
|
|
})
|
|
})
|