diff --git a/commands_test.go b/commands_test.go index d30a9d8bb3..e35609d5e3 100644 --- a/commands_test.go +++ b/commands_test.go @@ -1098,10 +1098,28 @@ var _ = Describe("Commands", func() { Expect(sadd.Err()).NotTo(HaveOccurred()) } - keys, cursor, err := client.HScan(ctx, "myhash", 0, "", 0).Result() + keys, cursor, err := client.HScan(ctx, "myhash", 0, "", 0, false).Result() Expect(err).NotTo(HaveOccurred()) - Expect(keys).NotTo(BeEmpty()) - Expect(cursor).NotTo(BeZero()) + // If we don't get at least two items back, it's really strange. + Expect(len(keys)).To(BeNumerically(">=", 2)) + Expect(keys[0]).To(HavePrefix("key")) + Expect(keys[1]).To(Equal("hello")) + Expect(cursor).To(BeNumerically(">=", 2)) + }) + + It("should HScan without values", func() { + for i := 0; i < 1000; i++ { + sadd := client.HSet(ctx, "myhash", fmt.Sprintf("key%d", i), "hello") + Expect(sadd.Err()).NotTo(HaveOccurred()) + } + + keys, cursor, err := client.HScan(ctx, "myhash", 0, "", 0, true).Result() + Expect(err).NotTo(HaveOccurred()) + // If we don't get at least two items back, it's really strange. + Expect(len(keys)).To(BeNumerically(">=", 2)) + Expect(keys[0]).To(HavePrefix("key")) + Expect(keys[1]).To(HavePrefix("key")) + Expect(cursor).To(BeNumerically(">=", 2)) }) It("should ZScan", func() { diff --git a/hash_commands.go b/hash_commands.go index 2c62a75ad9..0ed0688f37 100644 --- a/hash_commands.go +++ b/hash_commands.go @@ -15,7 +15,7 @@ type HashCmdable interface { HSet(ctx context.Context, key string, values ...interface{}) *IntCmd HMSet(ctx context.Context, key string, values ...interface{}) *BoolCmd HSetNX(ctx context.Context, key, field string, value interface{}) *BoolCmd - HScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd + HScan(ctx context.Context, key string, cursor uint64, match string, count int64, noValues bool) *ScanCmd HVals(ctx context.Context, key string) *StringSliceCmd HRandField(ctx context.Context, key string, count int) *StringSliceCmd HRandFieldWithValues(ctx context.Context, key string, count int) *KeyValueSliceCmd @@ -160,7 +160,7 @@ func (c cmdable) HRandFieldWithValues(ctx context.Context, key string, count int return cmd } -func (c cmdable) HScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd { +func (c cmdable) HScan(ctx context.Context, key string, cursor uint64, match string, count int64, noValues bool) *ScanCmd { args := []interface{}{"hscan", key, cursor} if match != "" { args = append(args, "match", match) @@ -168,6 +168,9 @@ func (c cmdable) HScan(ctx context.Context, key string, cursor uint64, match str if count > 0 { args = append(args, "count", count) } + if noValues { + args = append(args, "novalues") + } cmd := NewScanCmd(ctx, c, args...) _ = c(ctx, cmd) return cmd diff --git a/iterator_test.go b/iterator_test.go index ccd9414780..68e9e92fb4 100644 --- a/iterator_test.go +++ b/iterator_test.go @@ -88,7 +88,7 @@ var _ = Describe("ScanIterator", func() { Expect(hashSeed(71)).NotTo(HaveOccurred()) var vals []string - iter := client.HScan(ctx, hashKey, 0, "", 10).Iterator() + iter := client.HScan(ctx, hashKey, 0, "", 10, false).Iterator() for iter.Next(ctx) { vals = append(vals, iter.Val()) } @@ -96,6 +96,22 @@ var _ = Describe("ScanIterator", func() { 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", func() { + Expect(hashSeed(71)).NotTo(HaveOccurred()) + + var vals []string + iter := client.HScan(ctx, hashKey, 0, "", 10, true).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 scan to page borders", func() {