Skip to content

Commit ce49c4d

Browse files
authored
Merge pull request #1327 from a5-stable/hscan-novalue-option
Add novalues option support for HSCAN command
2 parents 2ab09ff + d0afe54 commit ce49c4d

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

lib/redis/commands/hashes.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,20 @@ def hgetall(key)
220220
# @param [Hash] options
221221
# - `:match => String`: only return keys matching the pattern
222222
# - `:count => Integer`: return count keys at most per iteration
223+
# - `:novalues => Boolean`: whether or not to include values in the output (default: false)
223224
#
224-
# @return [String, Array<[String, String]>] the next cursor and all found keys
225+
# @return [String, Array<[String, String]>, Array<String>] the next cursor and all found keys
226+
# - when `:novalues` is false: [cursor, [[field1, value1], [field2, value2], ...]]
227+
# - when `:novalues` is true: [cursor, [field1, field2, ...]]
225228
#
226229
# See the [Redis Server HSCAN documentation](https://redis.io/docs/latest/commands/hscan/) for further details
227230
def hscan(key, cursor, **options)
228231
_scan(:hscan, cursor, [key], **options) do |reply|
229-
[reply[0], reply[1].each_slice(2).to_a]
232+
if options[:novalues]
233+
reply
234+
else
235+
[reply[0], reply[1].each_slice(2).to_a]
236+
end
230237
end
231238
end
232239

@@ -239,6 +246,7 @@ def hscan(key, cursor, **options)
239246
# @param [Hash] options
240247
# - `:match => String`: only return keys matching the pattern
241248
# - `:count => Integer`: return count keys at most per iteration
249+
# - `:novalues => Boolean`: whether or not to include values in the output (default: false)
242250
#
243251
# @return [Enumerator] an enumerator for all found keys
244252
#

lib/redis/commands/keys.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,13 +447,14 @@ def type(key)
447447

448448
private
449449

450-
def _scan(command, cursor, args, match: nil, count: nil, type: nil, &block)
450+
def _scan(command, cursor, args, match: nil, count: nil, type: nil, novalues: false, &block)
451451
# SSCAN/ZSCAN/HSCAN already prepend the key to +args+.
452452

453453
args << cursor
454454
args << "MATCH" << match if match
455455
args << "COUNT" << Integer(count) if count
456456
args << "TYPE" << type if type
457+
args << "NOVALUES" if novalues
457458

458459
send_command([command] + args, &block)
459460
end

test/redis/scanning_test.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,26 @@ def test_hscan_with_encoding
213213
end
214214
end
215215

216+
def test_hscan_novalues
217+
target_version "7.4.0" do
218+
count = 1000
219+
elements = []
220+
count.times { |j| elements << "key:#{j}" << j.to_s }
221+
r.hmset "hash", *elements
222+
223+
cursor = 0
224+
all_keys = []
225+
loop do
226+
cursor, keys = r.hscan "hash", cursor, novalues: true
227+
all_keys.concat keys
228+
break if cursor == "0"
229+
end
230+
231+
assert_equal count, all_keys.uniq.size
232+
assert_equal true, all_keys.all? { |k| k.start_with?("key:") }
233+
end
234+
end
235+
216236
def test_hscan_each_enumerator
217237
count = 1000
218238
elements = []
@@ -270,6 +290,25 @@ def test_hscan_each_block_match
270290
assert all_keys.sort == keys_from_scan.uniq.sort
271291
end
272292

293+
def test_hscan_each_block_novalues
294+
target_version "7.4.0" do
295+
count = 1000
296+
elements = []
297+
count.times { |j| elements << "key:#{j}" << j.to_s }
298+
r.hmset "hash", *elements
299+
300+
keys = []
301+
values = []
302+
r.hscan_each("hash", novalues: true) do |field, value|
303+
keys << field
304+
values << value
305+
end
306+
307+
assert_equal count, keys.uniq.size
308+
assert_equal true, values.all?(&:nil?)
309+
end
310+
end
311+
273312
def test_zscan_with_encoding
274313
%i[ziplist skiplist].each do |enc|
275314
r.del "zset"

0 commit comments

Comments
 (0)