redis-namespace 1.9.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88bd88ddb249a9424c8bcc002b84f097a96b4de6450944bc66096e6524115431
4
- data.tar.gz: 1b9b4d59744b77a65ec523a77ea438de1f0923494a838c94a8c312893dce1fa6
3
+ metadata.gz: e003f4015162bfd465e79dd90e54b44ae46f0ec269118e10c08215d639166296
4
+ data.tar.gz: 16078b51e1bdab24977aa2b6fb7d0cd4761a7c41c340fcdacfb96dd32216c061
5
5
  SHA512:
6
- metadata.gz: 2007d2f5396aec757c50d77de437dc01630b10de02eaeb852f7858233729476582036cf8214ba6e893f3e26b574c22169530a44bf9fb24c39fa2f2d5958e7ee5
7
- data.tar.gz: af47dc4b2ce8357f8751c99ed71d05dc213a75a8092a3d54f016cef36b327967445b915bfaed32565639b0b2c16dbd02ef0026fbabcbf07c8965d3bb42b04f16
6
+ metadata.gz: fb965b575fe3ec2f2f45b99a71839f569f647681939b16576c053ab3e25bf85db1db030941bbe6eaeecc624eeeaf8c0497c58c53c4231440896e9e116bc189e3
7
+ data.tar.gz: 07b2b2e20c4a152b3e3a4cfbf6abad773f335e098067a9b213e29dd80cfc4519f3d27c43febe6cf8261ffe95e73184e23a1b9ff557007eb7a8308e43a398bbb1
@@ -2,6 +2,6 @@
2
2
 
3
3
  class Redis
4
4
  class Namespace
5
- VERSION = '1.9.0'
5
+ VERSION = '1.11.0'
6
6
  end
7
7
  end
@@ -72,6 +72,7 @@ class Redis
72
72
  "exists?" => [ :all ],
73
73
  "expire" => [ :first ],
74
74
  "expireat" => [ :first ],
75
+ "expiretime" => [ :first ],
75
76
  "eval" => [ :eval_style ],
76
77
  "evalsha" => [ :eval_style ],
77
78
  "get" => [ :first ],
@@ -122,6 +123,7 @@ class Redis
122
123
  "persist" => [ :first ],
123
124
  "pexpire" => [ :first ],
124
125
  "pexpireat" => [ :first ],
126
+ "pexpiretime" => [ :first ],
125
127
  "pfadd" => [ :first ],
126
128
  "pfcount" => [ :all ],
127
129
  "pfmerge" => [ :all ],
@@ -138,6 +140,7 @@ class Redis
138
140
  "rpush" => [ :first ],
139
141
  "rpushx" => [ :first ],
140
142
  "sadd" => [ :first ],
143
+ "sadd?" => [ :first ],
141
144
  "scard" => [ :first ],
142
145
  "scan" => [ :scan_style, :second ],
143
146
  "scan_each" => [ :scan_style, :all ],
@@ -158,6 +161,7 @@ class Redis
158
161
  "spop" => [ :first ],
159
162
  "srandmember" => [ :first ],
160
163
  "srem" => [ :first ],
164
+ "srem?" => [ :first ],
161
165
  "sscan" => [ :first ],
162
166
  "sscan_each" => [ :first ],
163
167
  "strlen" => [ :first ],
@@ -202,6 +206,7 @@ class Redis
202
206
  HELPER_COMMANDS = {
203
207
  "auth" => [],
204
208
  "disconnect!" => [],
209
+ "close" => [],
205
210
  "echo" => [],
206
211
  "ping" => [],
207
212
  "time" => [],
@@ -238,6 +243,16 @@ class Redis
238
243
  # Support 1.8.7 by providing a namespaced reference to Enumerable::Enumerator
239
244
  Enumerator = Enumerable::Enumerator unless defined?(::Enumerator)
240
245
 
246
+ # This is used by the Redis gem to determine whether or not to display that deprecation message.
247
+ @sadd_returns_boolean = true
248
+
249
+ # This is used by the Redis gem to determine whether or not to display that deprecation message.
250
+ @srem_returns_boolean = true
251
+
252
+ class << self
253
+ attr_accessor :sadd_returns_boolean, :srem_returns_boolean
254
+ end
255
+
241
256
  attr_writer :namespace
242
257
  attr_reader :redis
243
258
  attr_accessor :warning
@@ -329,6 +344,32 @@ class Redis
329
344
  end
330
345
  ruby2_keywords(:eval) if respond_to?(:ruby2_keywords, true)
331
346
 
347
+ # This operation can run for a very long time if the namespace contains lots of keys!
348
+ # It should be used in tests, or when the namespace is small enough
349
+ # and you are sure you know what you are doing.
350
+ def clear
351
+ if warning?
352
+ warn("This operation can run for a very long time if the namespace contains lots of keys! " +
353
+ "It should be used in tests, or when the namespace is small enough " +
354
+ "and you are sure you know what you are doing.")
355
+ end
356
+
357
+ batch_size = 1000
358
+
359
+ if supports_scan?
360
+ cursor = "0"
361
+ begin
362
+ cursor, keys = scan(cursor, count: batch_size)
363
+ del(*keys) unless keys.empty?
364
+ end until cursor == "0"
365
+ else
366
+ all_keys = keys("*")
367
+ all_keys.each_slice(batch_size) do |keys|
368
+ del(*keys)
369
+ end
370
+ end
371
+ end
372
+
332
373
  ADMINISTRATIVE_COMMANDS.keys.each do |command|
333
374
  define_method(command) do |*args, &block|
334
375
  raise NoMethodError if deprecations?
@@ -371,7 +412,8 @@ class Redis
371
412
  "passthrough has been deprecated and will be removed in " +
372
413
  "redis-namespace 2.0 (at #{call_site})")
373
414
  end
374
- @redis.send(command, *args, &block)
415
+
416
+ wrapped_send(@redis, command, args, &block)
375
417
  else
376
418
  super
377
419
  end
@@ -476,7 +518,7 @@ class Redis
476
518
  end
477
519
 
478
520
  # Dispatch the command to Redis and store the result.
479
- result = @redis.send(command, *args, &block)
521
+ result = wrapped_send(@redis, command, args, &block)
480
522
 
481
523
  # Don't try to remove namespace from a Redis::Future, you can't.
482
524
  return result if result.is_a?(Redis::Future)
@@ -513,6 +555,16 @@ class Redis
513
555
  end
514
556
  end
515
557
 
558
+ def wrapped_send(redis_client, command, args = [], &block)
559
+ if redis_client.class.name == "ConnectionPool"
560
+ redis_client.with do |pool_connection|
561
+ pool_connection.send(command, *args, &block)
562
+ end
563
+ else
564
+ redis_client.send(command, *args, &block)
565
+ end
566
+ end
567
+
516
568
  # Avoid modifying the caller's (pass-by-reference) arguments.
517
569
  def clone_args(arg)
518
570
  if arg.is_a?(Array)
@@ -530,13 +582,10 @@ class Redis
530
582
 
531
583
  def namespaced_block(command, &block)
532
584
  if block.arity == 0
533
- redis.send(command, &block)
585
+ wrapped_send(redis, command, &block)
534
586
  else
535
- redis.send(command) do |r|
536
- copy = dup
537
- copy.redis = r
538
- yield copy
539
- end
587
+ outer_block = proc { |r| copy = dup; copy.redis = r; yield copy }
588
+ wrapped_send(redis, command, &outer_block)
540
589
  end
541
590
  end
542
591
 
@@ -582,5 +631,10 @@ class Redis
582
631
  Enumerator.new(&block)
583
632
  end
584
633
  end
634
+
635
+ def supports_scan?
636
+ redis_version = @redis.info["redis_version"]
637
+ Gem::Version.new(redis_version) >= Gem::Version.new("2.8.0")
638
+ end
585
639
  end
586
640
  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,17 @@ 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
+
366
+ it "should remove members" do
367
+ @namespaced.sadd('foo', 1)
368
+ expect(@namespaced.srem?('foo', 1)).to eq(true)
369
+ expect(@namespaced.srem?('foo', 1)).to eq(false)
370
+ end
371
+
342
372
  it "should add namespace to sort" do
343
373
  @namespaced.sadd('foo', 1)
344
374
  @namespaced.sadd('foo', 2)
@@ -376,6 +406,26 @@ describe "redis" do
376
406
  expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
377
407
  end
378
408
 
409
+ it "should utilize connection_pool while adding namepsace to multi blocks" do
410
+ memo = @namespaced
411
+ connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
412
+ @namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
413
+
414
+ expect(connection_pool).to receive(:with).and_call_original do |arg|
415
+ expect(arg).to be(an_instance_of(Redis))
416
+ end.at_least(:once)
417
+
418
+ @namespaced.mapped_hmset "foo", {"key" => "value"}
419
+ @namespaced.multi do |r|
420
+ r.del "foo"
421
+ r.mapped_hmset "foo", {"key1" => "value1"}
422
+ end
423
+ expect(@redis.get("foo")).to eq("bar")
424
+ expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
425
+
426
+ @namespaced = memo
427
+ end
428
+
379
429
  it "should pass through multi commands without block" do
380
430
  @namespaced.mapped_hmset "foo", {"key" => "value"}
381
431
 
@@ -387,6 +437,28 @@ describe "redis" do
387
437
  expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
388
438
  end
389
439
 
440
+ it "should utilize connection_pool while passing through multi commands without block" do
441
+ memo = @namespaced
442
+ connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
443
+ @namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
444
+
445
+ expect(connection_pool).to receive(:with).and_call_original do |arg|
446
+ expect(arg).to be(an_instance_of(Redis))
447
+ end.at_least(:once)
448
+
449
+ @namespaced.mapped_hmset "foo", {"key" => "value"}
450
+
451
+ @namespaced.multi
452
+ @namespaced.del "foo"
453
+ @namespaced.mapped_hmset "foo", {"key1" => "value1"}
454
+ @namespaced.exec
455
+
456
+ expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
457
+ expect(@redis.get("foo")).to eq("bar")
458
+
459
+ @namespaced = memo
460
+ end
461
+
390
462
  it 'should return futures without attempting to remove namespaces' do
391
463
  @namespaced.multi do
392
464
  @future = @namespaced.keys('*')
@@ -403,6 +475,26 @@ describe "redis" do
403
475
  expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
404
476
  end
405
477
 
478
+ it "should utilize connection_pool while adding namespace to pipelined blocks" do
479
+ memo = @namespaced
480
+ connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
481
+ @namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
482
+
483
+ expect(connection_pool).to receive(:with).and_call_original do |arg|
484
+ expect(arg).to be(an_instance_of(Redis))
485
+ end.at_least(:once)
486
+
487
+ @namespaced.mapped_hmset "foo", {"key" => "value"}
488
+ @namespaced.pipelined do |r|
489
+ r.del "foo"
490
+ r.mapped_hmset "foo", {"key1" => "value1"}
491
+ end
492
+ expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
493
+ expect(@redis.get("foo")).to eq("bar")
494
+
495
+ @namespaced = memo
496
+ end
497
+
406
498
  it "should returned response array from pipelined block" do
407
499
  @namespaced.mset "foo", "bar", "key", "value"
408
500
  result = @namespaced.pipelined do |r|
@@ -574,6 +666,12 @@ describe "redis" do
574
666
  expect(@redis.ttl("ns:foo")).to satisfy {|v| (0..1).include?(v) }
575
667
  end
576
668
 
669
+ it "should namespace expiretime" do
670
+ @namespaced.set('mykey', 'Hello')
671
+ @namespaced.expireat('mykey', 2000000000)
672
+ expect(@namespaced.expiretime('mykey')).to eq(2000000000)
673
+ end
674
+
577
675
  it "should namespace hincrbyfloat" do
578
676
  @namespaced.hset('mykey', 'field', 10.50)
579
677
  expect(@namespaced.hincrbyfloat('mykey', 'field', 0.1)).to eq(10.6)
@@ -606,6 +704,12 @@ describe "redis" do
606
704
  expect(@namespaced.pexpire('mykey', 1555555555005)).to eq(true)
607
705
  end
608
706
 
707
+ it "should namespace pexpiretime" do
708
+ @namespaced.set('mykey', 'Hello')
709
+ @namespaced.pexpireat('mykey', 2000000000000)
710
+ expect(@namespaced.pexpiretime('mykey')).to eq(2000000000000)
711
+ end
712
+
609
713
  it "should namespace psetex" do
610
714
  expect(@namespaced.psetex('mykey', 10000, 'Hello')).to eq('OK')
611
715
  expect(@namespaced.get('mykey')).to eq('Hello')
@@ -967,4 +1071,30 @@ describe "redis" do
967
1071
  expect(sub_sub_namespaced.full_namespace).to eql("ns:sub1:sub2")
968
1072
  end
969
1073
  end
1074
+
1075
+ describe :clear do
1076
+ it "warns with helpful output" do
1077
+ expect { @namespaced.clear }.to output(/can run for a very long time/).to_stderr
1078
+ end
1079
+
1080
+ it "should delete all the keys" do
1081
+ @redis.set("foo", "bar")
1082
+ @namespaced.mset("foo1", "bar", "foo2", "bar")
1083
+ capture_stderr { @namespaced.clear }
1084
+
1085
+ expect(@redis.keys).to eq ["foo"]
1086
+ expect(@namespaced.keys).to be_empty
1087
+ end
1088
+
1089
+ it "should delete all the keys in older redis" do
1090
+ allow(@redis).to receive(:info).and_return({ "redis_version" => "2.7.0" })
1091
+
1092
+ @redis.set("foo", "bar")
1093
+ @namespaced.mset("foo1", "bar", "foo2", "bar")
1094
+ capture_stderr { @namespaced.clear }
1095
+
1096
+ expect(@redis.keys).to eq ["foo"]
1097
+ expect(@namespaced.keys).to be_empty
1098
+ end
1099
+ end
970
1100
  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.11.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: 2023-06-08 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.11.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.4.1
121
134
  signing_key:
122
135
  specification_version: 4
123
136
  summary: Namespaces Redis commands.