redis-namespace 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88bd88ddb249a9424c8bcc002b84f097a96b4de6450944bc66096e6524115431
4
- data.tar.gz: 1b9b4d59744b77a65ec523a77ea438de1f0923494a838c94a8c312893dce1fa6
3
+ metadata.gz: 8c4fe7070f484a694ce41f97a0297e03d92cfa67746903d9fb74fa8439410494
4
+ data.tar.gz: 0cbfe04c2ca7b2d42ee603f0d67ba21c13cb938832cc99f89a2323842bb828a3
5
5
  SHA512:
6
- metadata.gz: 2007d2f5396aec757c50d77de437dc01630b10de02eaeb852f7858233729476582036cf8214ba6e893f3e26b574c22169530a44bf9fb24c39fa2f2d5958e7ee5
7
- data.tar.gz: af47dc4b2ce8357f8751c99ed71d05dc213a75a8092a3d54f016cef36b327967445b915bfaed32565639b0b2c16dbd02ef0026fbabcbf07c8965d3bb42b04f16
6
+ metadata.gz: ec085b7e9fba5241cb2e2ad4ccf22d4282001a0ee37731e408a2135ea5e5439747441046cc6c48a2a372afe99f2fb6a67401867a20c8605e41206954eca72078
7
+ data.tar.gz: 0eff5c268bba88cb8bd5e0ab8115a404fed3180e82ebc4297ab8675da6c73e13b3bb943e77ec0392de4460683488589bbc227d95515aa5dc70cdb4236b58801d
@@ -2,6 +2,6 @@
2
2
 
3
3
  class Redis
4
4
  class Namespace
5
- VERSION = '1.9.0'
5
+ VERSION = '1.10.0'
6
6
  end
7
7
  end
@@ -138,6 +138,7 @@ class Redis
138
138
  "rpush" => [ :first ],
139
139
  "rpushx" => [ :first ],
140
140
  "sadd" => [ :first ],
141
+ "sadd?" => [ :first ],
141
142
  "scard" => [ :first ],
142
143
  "scan" => [ :scan_style, :second ],
143
144
  "scan_each" => [ :scan_style, :all ],
@@ -202,6 +203,7 @@ class Redis
202
203
  HELPER_COMMANDS = {
203
204
  "auth" => [],
204
205
  "disconnect!" => [],
206
+ "close" => [],
205
207
  "echo" => [],
206
208
  "ping" => [],
207
209
  "time" => [],
@@ -238,6 +240,13 @@ class Redis
238
240
  # Support 1.8.7 by providing a namespaced reference to Enumerable::Enumerator
239
241
  Enumerator = Enumerable::Enumerator unless defined?(::Enumerator)
240
242
 
243
+ # This is used by the Redis gem to determine whether or not to display that deprecation message.
244
+ @sadd_returns_boolean = true
245
+
246
+ class << self
247
+ attr_accessor :sadd_returns_boolean
248
+ end
249
+
241
250
  attr_writer :namespace
242
251
  attr_reader :redis
243
252
  attr_accessor :warning
@@ -329,6 +338,32 @@ class Redis
329
338
  end
330
339
  ruby2_keywords(:eval) if respond_to?(:ruby2_keywords, true)
331
340
 
341
+ # This operation can run for a very long time if the namespace contains lots of keys!
342
+ # It should be used in tests, or when the namespace is small enough
343
+ # and you are sure you know what you are doing.
344
+ def clear
345
+ if warning?
346
+ warn("This operation can run for a very long time if the namespace contains lots of keys! " +
347
+ "It should be used in tests, or when the namespace is small enough " +
348
+ "and you are sure you know what you are doing.")
349
+ end
350
+
351
+ batch_size = 1000
352
+
353
+ if supports_scan?
354
+ cursor = "0"
355
+ begin
356
+ cursor, keys = scan(cursor, count: batch_size)
357
+ del(*keys) unless keys.empty?
358
+ end until cursor == "0"
359
+ else
360
+ all_keys = keys("*")
361
+ all_keys.each_slice(batch_size) do |keys|
362
+ del(*keys)
363
+ end
364
+ end
365
+ end
366
+
332
367
  ADMINISTRATIVE_COMMANDS.keys.each do |command|
333
368
  define_method(command) do |*args, &block|
334
369
  raise NoMethodError if deprecations?
@@ -371,7 +406,8 @@ class Redis
371
406
  "passthrough has been deprecated and will be removed in " +
372
407
  "redis-namespace 2.0 (at #{call_site})")
373
408
  end
374
- @redis.send(command, *args, &block)
409
+
410
+ wrapped_send(@redis, command, args, &block)
375
411
  else
376
412
  super
377
413
  end
@@ -476,7 +512,7 @@ class Redis
476
512
  end
477
513
 
478
514
  # Dispatch the command to Redis and store the result.
479
- result = @redis.send(command, *args, &block)
515
+ result = wrapped_send(@redis, command, args, &block)
480
516
 
481
517
  # Don't try to remove namespace from a Redis::Future, you can't.
482
518
  return result if result.is_a?(Redis::Future)
@@ -513,6 +549,16 @@ class Redis
513
549
  end
514
550
  end
515
551
 
552
+ def wrapped_send(redis_client, command, args = [], &block)
553
+ if redis_client.class.name == "ConnectionPool"
554
+ redis_client.with do |pool_connection|
555
+ pool_connection.send(command, *args, &block)
556
+ end
557
+ else
558
+ redis_client.send(command, *args, &block)
559
+ end
560
+ end
561
+
516
562
  # Avoid modifying the caller's (pass-by-reference) arguments.
517
563
  def clone_args(arg)
518
564
  if arg.is_a?(Array)
@@ -530,13 +576,10 @@ class Redis
530
576
 
531
577
  def namespaced_block(command, &block)
532
578
  if block.arity == 0
533
- redis.send(command, &block)
579
+ wrapped_send(redis, command, &block)
534
580
  else
535
- redis.send(command) do |r|
536
- copy = dup
537
- copy.redis = r
538
- yield copy
539
- end
581
+ outer_block = proc { |r| copy = dup; copy.redis = r; yield copy }
582
+ wrapped_send(redis, command, &outer_block)
540
583
  end
541
584
  end
542
585
 
@@ -582,5 +625,10 @@ class Redis
582
625
  Enumerator.new(&block)
583
626
  end
584
627
  end
628
+
629
+ def supports_scan?
630
+ redis_version = @redis.info["redis_version"]
631
+ Gem::Version.new(redis_version) >= Gem::Version.new("2.8.0")
632
+ end
585
633
  end
586
634
  end
@@ -31,7 +31,7 @@ describe Redis::Namespace do
31
31
  end
32
32
 
33
33
  before(:each) do
34
- allow(redis).to receive(:unhandled) do |*args|
34
+ allow(redis).to receive(:unhandled) do |*args|
35
35
  "unhandled(#{args.inspect})"
36
36
  end
37
37
  allow(redis).to receive(:flushdb).and_return("OK")
data/spec/redis_spec.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require File.dirname(__FILE__) + '/spec_helper'
4
+ require 'connection_pool'
4
5
 
5
6
  describe "redis" do
6
7
  @redis_version = Gem::Version.new(Redis.new.info["redis_version"])
@@ -184,6 +185,24 @@ describe "redis" do
184
185
  expect(@namespaced.mapped_mget('foo', 'baz', 'bar')).to eq({'foo'=>'1000', 'bar'=>'2000', 'baz' => nil})
185
186
  end
186
187
 
188
+ it "should utilize connection_pool while using a namespace with mget" do
189
+ memo = @namespaced
190
+ connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
191
+ @namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
192
+
193
+ expect(connection_pool).to receive(:with).and_call_original do |arg|
194
+ expect(arg).to be(an_instance_of(Redis))
195
+ end.at_least(:once)
196
+
197
+ @namespaced.set('foo', 1000)
198
+ @namespaced.set('bar', 2000)
199
+ expect(@namespaced.mapped_mget('foo', 'bar')).to eq({ 'foo' => '1000', 'bar' => '2000' })
200
+ expect(@namespaced.mapped_mget('foo', 'baz', 'bar')).to eq({'foo'=>'1000', 'bar'=>'2000', 'baz' => nil})
201
+ @redis.get('foo').should eq('bar')
202
+
203
+ @namespaced = memo
204
+ end
205
+
187
206
  it "should be able to use a namespace with mset" do
188
207
  @namespaced.mset('foo', '1000', 'bar', '2000')
189
208
  expect(@namespaced.mapped_mget('foo', 'bar')).to eq({ 'foo' => '1000', 'bar' => '2000' })
@@ -339,6 +358,11 @@ describe "redis" do
339
358
  expect(values).to match_array(['banana', 'eggplant'])
340
359
  end
341
360
 
361
+ it "should add a new member" do
362
+ expect(@namespaced.sadd?('foo', 1)).to eq(true)
363
+ expect(@namespaced.sadd?('foo', 1)).to eq(false)
364
+ end
365
+
342
366
  it "should add namespace to sort" do
343
367
  @namespaced.sadd('foo', 1)
344
368
  @namespaced.sadd('foo', 2)
@@ -376,6 +400,26 @@ describe "redis" do
376
400
  expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
377
401
  end
378
402
 
403
+ it "should utilize connection_pool while adding namepsace to multi blocks" do
404
+ memo = @namespaced
405
+ connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
406
+ @namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
407
+
408
+ expect(connection_pool).to receive(:with).and_call_original do |arg|
409
+ expect(arg).to be(an_instance_of(Redis))
410
+ end.at_least(:once)
411
+
412
+ @namespaced.mapped_hmset "foo", {"key" => "value"}
413
+ @namespaced.multi do |r|
414
+ r.del "foo"
415
+ r.mapped_hmset "foo", {"key1" => "value1"}
416
+ end
417
+ expect(@redis.get("foo")).to eq("bar")
418
+ expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
419
+
420
+ @namespaced = memo
421
+ end
422
+
379
423
  it "should pass through multi commands without block" do
380
424
  @namespaced.mapped_hmset "foo", {"key" => "value"}
381
425
 
@@ -387,6 +431,28 @@ describe "redis" do
387
431
  expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
388
432
  end
389
433
 
434
+ it "should utilize connection_pool while passing through multi commands without block" do
435
+ memo = @namespaced
436
+ connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
437
+ @namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
438
+
439
+ expect(connection_pool).to receive(:with).and_call_original do |arg|
440
+ expect(arg).to be(an_instance_of(Redis))
441
+ end.at_least(:once)
442
+
443
+ @namespaced.mapped_hmset "foo", {"key" => "value"}
444
+
445
+ @namespaced.multi
446
+ @namespaced.del "foo"
447
+ @namespaced.mapped_hmset "foo", {"key1" => "value1"}
448
+ @namespaced.exec
449
+
450
+ expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
451
+ expect(@redis.get("foo")).to eq("bar")
452
+
453
+ @namespaced = memo
454
+ end
455
+
390
456
  it 'should return futures without attempting to remove namespaces' do
391
457
  @namespaced.multi do
392
458
  @future = @namespaced.keys('*')
@@ -403,6 +469,26 @@ describe "redis" do
403
469
  expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
404
470
  end
405
471
 
472
+ it "should utilize connection_pool while adding namespace to pipelined blocks" do
473
+ memo = @namespaced
474
+ connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
475
+ @namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
476
+
477
+ expect(connection_pool).to receive(:with).and_call_original do |arg|
478
+ expect(arg).to be(an_instance_of(Redis))
479
+ end.at_least(:once)
480
+
481
+ @namespaced.mapped_hmset "foo", {"key" => "value"}
482
+ @namespaced.pipelined do |r|
483
+ r.del "foo"
484
+ r.mapped_hmset "foo", {"key1" => "value1"}
485
+ end
486
+ expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
487
+ expect(@redis.get("foo")).to eq("bar")
488
+
489
+ @namespaced = memo
490
+ end
491
+
406
492
  it "should returned response array from pipelined block" do
407
493
  @namespaced.mset "foo", "bar", "key", "value"
408
494
  result = @namespaced.pipelined do |r|
@@ -967,4 +1053,30 @@ describe "redis" do
967
1053
  expect(sub_sub_namespaced.full_namespace).to eql("ns:sub1:sub2")
968
1054
  end
969
1055
  end
1056
+
1057
+ describe :clear do
1058
+ it "warns with helpful output" do
1059
+ expect { @namespaced.clear }.to output(/can run for a very long time/).to_stderr
1060
+ end
1061
+
1062
+ it "should delete all the keys" do
1063
+ @redis.set("foo", "bar")
1064
+ @namespaced.mset("foo1", "bar", "foo2", "bar")
1065
+ capture_stderr { @namespaced.clear }
1066
+
1067
+ expect(@redis.keys).to eq ["foo"]
1068
+ expect(@namespaced.keys).to be_empty
1069
+ end
1070
+
1071
+ it "should delete all the keys in older redis" do
1072
+ allow(@redis).to receive(:info).and_return({ "redis_version" => "2.7.0" })
1073
+
1074
+ @redis.set("foo", "bar")
1075
+ @namespaced.mset("foo1", "bar", "foo2", "bar")
1076
+ capture_stderr { @namespaced.clear }
1077
+
1078
+ expect(@redis.keys).to eq ["foo"]
1079
+ expect(@namespaced.keys).to be_empty
1080
+ end
1081
+ end
970
1082
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-namespace
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wanstrath
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2022-08-13 00:00:00.000000000 Z
15
+ date: 2022-12-20 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: redis
@@ -70,6 +70,20 @@ dependencies:
70
70
  - - ">="
71
71
  - !ruby/object:Gem::Version
72
72
  version: '0'
73
+ - !ruby/object:Gem::Dependency
74
+ name: connection_pool
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
73
87
  description: |
74
88
  Adds a Redis::Namespace class which can be used to namespace calls
75
89
  to Redis. This is useful when using a single instance of Redis with
@@ -99,8 +113,7 @@ licenses:
99
113
  metadata:
100
114
  bug_tracker_uri: https://github.com/resque/redis-namespace/issues
101
115
  changelog_uri: https://github.com/resque/redis-namespace/blob/master/CHANGELOG.md
102
- documentation_uri: https://www.rubydoc.info/gems/redis-namespace/1.9.0
103
- source_code_uri: https://github.com/resque/redis-namespace/tree/v1.9.0
116
+ documentation_uri: https://www.rubydoc.info/gems/redis-namespace/1.10.0
104
117
  rubygems_mfa_required: 'true'
105
118
  post_install_message:
106
119
  rdoc_options: []
@@ -117,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
130
  - !ruby/object:Gem::Version
118
131
  version: '0'
119
132
  requirements: []
120
- rubygems_version: 3.1.6
133
+ rubygems_version: 3.3.15
121
134
  signing_key:
122
135
  specification_version: 4
123
136
  summary: Namespaces Redis commands.