redis-namespace 1.3.2 → 1.4.0.rc.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.
- data/lib/redis/namespace.rb +29 -1
- data/lib/redis/namespace/version.rb +1 -1
- data/spec/redis_spec.rb +255 -0
- metadata +5 -5
data/lib/redis/namespace.rb
CHANGED
@@ -42,6 +42,8 @@ class Redis
|
|
42
42
|
# a Hash; forces second arg's :get to be an Array if present.
|
43
43
|
# :eval_style
|
44
44
|
# Add namespace to each element in keys argument (via options hash or multi-args)
|
45
|
+
# :scan_style
|
46
|
+
# Add namespace to :match option, or supplies "#{namespace}:*" if not present.
|
45
47
|
#
|
46
48
|
# The second element in the value array describes how to modify
|
47
49
|
# the return value of the Redis call. It can be one of:
|
@@ -93,6 +95,8 @@ class Redis
|
|
93
95
|
"hexists" => [ :first ],
|
94
96
|
"hlen" => [ :first ],
|
95
97
|
"hkeys" => [ :first ],
|
98
|
+
"hscan" => [ :first ],
|
99
|
+
"hscan_each" => [ :first ],
|
96
100
|
"hvals" => [ :first ],
|
97
101
|
"hgetall" => [ :first ],
|
98
102
|
"incr" => [ :first ],
|
@@ -143,6 +147,8 @@ class Redis
|
|
143
147
|
"sadd" => [ :first ],
|
144
148
|
"save" => [],
|
145
149
|
"scard" => [ :first ],
|
150
|
+
"scan" => [ :scan_style, :second ],
|
151
|
+
"scan_each" => [ :scan_style, :all ],
|
146
152
|
"sdiff" => [ :all ],
|
147
153
|
"sdiffstore" => [ :all ],
|
148
154
|
"select" => [],
|
@@ -162,6 +168,8 @@ class Redis
|
|
162
168
|
"spop" => [ :first ],
|
163
169
|
"srandmember" => [ :first ],
|
164
170
|
"srem" => [ :first ],
|
171
|
+
"sscan" => [ :first ],
|
172
|
+
"sscan_each" => [ :first ],
|
165
173
|
"strlen" => [ :first ],
|
166
174
|
"subscribe" => [ :all ],
|
167
175
|
"sunion" => [ :all ],
|
@@ -184,12 +192,17 @@ class Redis
|
|
184
192
|
"zrevrange" => [ :first ],
|
185
193
|
"zrevrangebyscore" => [ :first ],
|
186
194
|
"zrevrank" => [ :first ],
|
195
|
+
"zscan" => [ :first ],
|
196
|
+
"zscan_each" => [ :first ],
|
187
197
|
"zscore" => [ :first ],
|
188
198
|
"zunionstore" => [ :exclude_options ],
|
189
199
|
"[]" => [ :first ],
|
190
200
|
"[]=" => [ :first ]
|
191
201
|
}
|
192
202
|
|
203
|
+
# Support 1.8.7 by providing a namespaced reference to Enumerable::Enumerator
|
204
|
+
Enumerator = Enumerable::Enumerator unless defined?(::Enumerator)
|
205
|
+
|
193
206
|
# support previous versions of redis gem
|
194
207
|
ALIASES = case
|
195
208
|
when defined? Redis::Client::ALIASES then Redis::Client::ALIASES
|
@@ -324,6 +337,15 @@ class Redis
|
|
324
337
|
else
|
325
338
|
args[1] = add_namespace(args[1])
|
326
339
|
end
|
340
|
+
when :scan_style
|
341
|
+
options = (args.last.kind_of?(Hash) ? args.pop : {})
|
342
|
+
options[:match] = add_namespace(options.fetch(:match, '*'))
|
343
|
+
args << options
|
344
|
+
|
345
|
+
if block
|
346
|
+
original_block = block
|
347
|
+
block = proc { |key| original_block.call rem_namespace(key) }
|
348
|
+
end
|
327
349
|
end
|
328
350
|
|
329
351
|
# Dispatch the command to Redis and store the result.
|
@@ -338,6 +360,8 @@ class Redis
|
|
338
360
|
result = rem_namespace(result)
|
339
361
|
when :first
|
340
362
|
result[0] = rem_namespace(result[0]) if result
|
363
|
+
when :second
|
364
|
+
result[1] = rem_namespace(result[1]) if result
|
341
365
|
end
|
342
366
|
|
343
367
|
result
|
@@ -376,8 +400,12 @@ class Redis
|
|
376
400
|
key.map {|k| rem_namespace k}
|
377
401
|
when Hash
|
378
402
|
Hash[*key.map {|k, v| [ rem_namespace(k), v ]}.flatten]
|
403
|
+
when Enumerator
|
404
|
+
Enumerator.new do |yielder|
|
405
|
+
key.each { |k| yielder << rem_namespace(k) }
|
406
|
+
end
|
379
407
|
else
|
380
|
-
key.to_s.
|
408
|
+
key.to_s.sub(/\A#{@namespace}:/, '')
|
381
409
|
end
|
382
410
|
end
|
383
411
|
end
|
data/spec/redis_spec.rb
CHANGED
@@ -458,6 +458,261 @@ describe "redis" do
|
|
458
458
|
end
|
459
459
|
end
|
460
460
|
|
461
|
+
# Redis 2.8 RC reports its version as 2.7.
|
462
|
+
if @redis_version >= Gem::Version.new("2.7.105")
|
463
|
+
describe "redis 2.8 commands" do
|
464
|
+
context 'keyspace scan methods' do
|
465
|
+
let(:keys) do
|
466
|
+
%w(alpha ns:beta gamma ns:delta ns:epsilon ns:zeta:one ns:zeta:two ns:theta)
|
467
|
+
end
|
468
|
+
let(:namespaced_keys) do
|
469
|
+
keys.map{|k| k.dup.sub!(/\Ans:/,'') }.compact.sort
|
470
|
+
end
|
471
|
+
before(:each) do
|
472
|
+
keys.each do |key|
|
473
|
+
@redis.set(key, key)
|
474
|
+
end
|
475
|
+
end
|
476
|
+
let(:matching_namespaced_keys) do
|
477
|
+
namespaced_keys.select{|k| k[/\Azeta:/] }.compact.sort
|
478
|
+
end
|
479
|
+
|
480
|
+
context '#scan' do
|
481
|
+
context 'when :match supplied' do
|
482
|
+
it 'should retrieve the proper keys' do
|
483
|
+
_, result = @namespaced.scan(0, :match => 'zeta:*', :count => 1000)
|
484
|
+
result.should =~ matching_namespaced_keys
|
485
|
+
end
|
486
|
+
end
|
487
|
+
context 'without :match supplied' do
|
488
|
+
it 'should retrieve the proper keys' do
|
489
|
+
_, result = @namespaced.scan(0, :count => 1000)
|
490
|
+
result.should =~ namespaced_keys
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end if Redis.current.respond_to?(:scan)
|
494
|
+
|
495
|
+
context '#scan_each' do
|
496
|
+
context 'when :match supplied' do
|
497
|
+
context 'when given a block' do
|
498
|
+
it 'should yield unnamespaced' do
|
499
|
+
results = []
|
500
|
+
@namespaced.scan_each(:match => 'zeta:*', :count => 1000) {|k| results << k }
|
501
|
+
results.should =~ matching_namespaced_keys
|
502
|
+
end
|
503
|
+
end
|
504
|
+
context 'without a block' do
|
505
|
+
it 'should return an Enumerator that un-namespaces' do
|
506
|
+
enum = @namespaced.scan_each(:match => 'zeta:*', :count => 1000)
|
507
|
+
enum.to_a.should =~ matching_namespaced_keys
|
508
|
+
end
|
509
|
+
end
|
510
|
+
end
|
511
|
+
context 'without :match supplied' do
|
512
|
+
context 'when given a block' do
|
513
|
+
it 'should yield unnamespaced' do
|
514
|
+
results = []
|
515
|
+
@namespaced.scan_each(:count => 1000){ |k| results << k }
|
516
|
+
results.should =~ namespaced_keys
|
517
|
+
end
|
518
|
+
end
|
519
|
+
context 'without a block' do
|
520
|
+
it 'should return an Enumerator that un-namespaces' do
|
521
|
+
enum = @namespaced.scan_each(:count => 1000)
|
522
|
+
enum.to_a.should =~ namespaced_keys
|
523
|
+
end
|
524
|
+
end
|
525
|
+
end
|
526
|
+
end if Redis.current.respond_to?(:scan_each)
|
527
|
+
end
|
528
|
+
|
529
|
+
context 'hash scan methods' do
|
530
|
+
before(:each) do
|
531
|
+
@redis.mapped_hmset('hsh', {'zeta:wrong:one' => 'WRONG', 'wrong:two' => 'WRONG'})
|
532
|
+
@redis.mapped_hmset('ns:hsh', hash)
|
533
|
+
end
|
534
|
+
let(:hash) do
|
535
|
+
{'zeta:one' => 'OK', 'zeta:two' => 'OK', 'three' => 'OKAY'}
|
536
|
+
end
|
537
|
+
let(:hash_matching_subset) do
|
538
|
+
# select is not consistent from 1.8.7 -> 1.9.2 :(
|
539
|
+
hash.reject {|k,v| !k[/\Azeta:/] }
|
540
|
+
end
|
541
|
+
context '#hscan' do
|
542
|
+
context 'when supplied :match' do
|
543
|
+
it 'should retrieve the proper keys' do
|
544
|
+
_, results = @namespaced.hscan('hsh', 0, :match => 'zeta:*')
|
545
|
+
results.should =~ hash_matching_subset.to_a
|
546
|
+
end
|
547
|
+
end
|
548
|
+
context 'without :match supplied' do
|
549
|
+
it 'should retrieve all hash keys' do
|
550
|
+
_, results = @namespaced.hscan('hsh', 0)
|
551
|
+
results.should =~ @redis.hgetall('ns:hsh').to_a
|
552
|
+
end
|
553
|
+
end
|
554
|
+
end if Redis.current.respond_to?(:hscan)
|
555
|
+
|
556
|
+
context '#hscan_each' do
|
557
|
+
context 'when :match supplied' do
|
558
|
+
context 'when given a block' do
|
559
|
+
it 'should yield the correct hash keys unchanged' do
|
560
|
+
results = []
|
561
|
+
@namespaced.hscan_each('hsh', :match => 'zeta:*', :count => 1000) { |kv| results << kv}
|
562
|
+
results.should =~ hash_matching_subset.to_a
|
563
|
+
end
|
564
|
+
end
|
565
|
+
context 'without a block' do
|
566
|
+
it 'should return an Enumerator that yields the correct hash keys unchanged' do
|
567
|
+
enum = @namespaced.hscan_each('hsh', :match => 'zeta:*', :count => 1000)
|
568
|
+
enum.to_a.should =~ hash_matching_subset.to_a
|
569
|
+
end
|
570
|
+
end
|
571
|
+
end
|
572
|
+
context 'without :match supplied' do
|
573
|
+
context 'when given a block' do
|
574
|
+
it 'should yield all hash keys unchanged' do
|
575
|
+
results = []
|
576
|
+
@namespaced.hscan_each('hsh', :count => 1000){ |k| results << k }
|
577
|
+
results.should =~ hash.to_a
|
578
|
+
end
|
579
|
+
end
|
580
|
+
context 'without a block' do
|
581
|
+
it 'should return an Enumerator that yields all keys unchanged' do
|
582
|
+
enum = @namespaced.hscan_each('hsh', :count => 1000)
|
583
|
+
enum.to_a.should =~ hash.to_a
|
584
|
+
end
|
585
|
+
end
|
586
|
+
end
|
587
|
+
end if Redis.current.respond_to?(:hscan_each)
|
588
|
+
end
|
589
|
+
|
590
|
+
context 'set scan methods' do
|
591
|
+
before(:each) do
|
592
|
+
set.each { |elem| @namespaced.sadd('set', elem) }
|
593
|
+
@redis.sadd('set', 'WRONG')
|
594
|
+
end
|
595
|
+
let(:set) do
|
596
|
+
%w(zeta:one zeta:two three)
|
597
|
+
end
|
598
|
+
let(:matching_subset) do
|
599
|
+
set.select { |e| e[/\Azeta:/] }
|
600
|
+
end
|
601
|
+
|
602
|
+
context '#sscan' do
|
603
|
+
context 'when supplied :match' do
|
604
|
+
it 'should retrieve the matching set members from the proper set' do
|
605
|
+
_, results = @namespaced.sscan('set', 0, :match => 'zeta:*', :count => 1000)
|
606
|
+
results.should =~ matching_subset
|
607
|
+
end
|
608
|
+
end
|
609
|
+
context 'without :match supplied' do
|
610
|
+
it 'should retrieve all set members from the proper set' do
|
611
|
+
_, results = @namespaced.sscan('set', 0, :count => 1000)
|
612
|
+
results.should =~ set
|
613
|
+
end
|
614
|
+
end
|
615
|
+
end if Redis.current.respond_to?(:sscan)
|
616
|
+
|
617
|
+
context '#sscan_each' do
|
618
|
+
context 'when :match supplied' do
|
619
|
+
context 'when given a block' do
|
620
|
+
it 'should yield the correct hset elements unchanged' do
|
621
|
+
results = []
|
622
|
+
@namespaced.sscan_each('set', :match => 'zeta:*', :count => 1000) { |kv| results << kv}
|
623
|
+
results.should =~ matching_subset
|
624
|
+
end
|
625
|
+
end
|
626
|
+
context 'without a block' do
|
627
|
+
it 'should return an Enumerator that yields the correct set elements unchanged' do
|
628
|
+
enum = @namespaced.sscan_each('set', :match => 'zeta:*', :count => 1000)
|
629
|
+
enum.to_a.should =~ matching_subset
|
630
|
+
end
|
631
|
+
end
|
632
|
+
end
|
633
|
+
context 'without :match supplied' do
|
634
|
+
context 'when given a block' do
|
635
|
+
it 'should yield all set elements unchanged' do
|
636
|
+
results = []
|
637
|
+
@namespaced.sscan_each('set', :count => 1000){ |k| results << k }
|
638
|
+
results.should =~ set
|
639
|
+
end
|
640
|
+
end
|
641
|
+
context 'without a block' do
|
642
|
+
it 'should return an Enumerator that yields all set elements unchanged' do
|
643
|
+
enum = @namespaced.sscan_each('set', :count => 1000)
|
644
|
+
enum.to_a.should =~ set
|
645
|
+
end
|
646
|
+
end
|
647
|
+
end
|
648
|
+
end if Redis.current.respond_to?(:sscan_each)
|
649
|
+
end
|
650
|
+
|
651
|
+
context 'zset scan methods' do
|
652
|
+
before(:each) do
|
653
|
+
hash.each {|member, score| @namespaced.zadd('zset', score, member)}
|
654
|
+
@redis.zadd('zset', 123.45, 'WRONG')
|
655
|
+
end
|
656
|
+
let(:hash) do
|
657
|
+
{'zeta:one' => 1, 'zeta:two' => 2, 'three' => 3}
|
658
|
+
end
|
659
|
+
let(:hash_matching_subset) do
|
660
|
+
# select is not consistent from 1.8.7 -> 1.9.2 :(
|
661
|
+
hash.reject {|k,v| !k[/\Azeta:/] }
|
662
|
+
end
|
663
|
+
context '#zscan' do
|
664
|
+
context 'when supplied :match' do
|
665
|
+
it 'should retrieve the matching set elements and their scores' do
|
666
|
+
results = []
|
667
|
+
@namespaced.zscan_each('zset', :match => 'zeta:*', :count => 1000) { |ms| results << ms }
|
668
|
+
results.should =~ hash_matching_subset.to_a
|
669
|
+
end
|
670
|
+
end
|
671
|
+
context 'without :match supplied' do
|
672
|
+
it 'should retrieve all set elements and their scores' do
|
673
|
+
results = []
|
674
|
+
@namespaced.zscan_each('zset', :count => 1000) { |ms| results << ms }
|
675
|
+
results.should =~ hash.to_a
|
676
|
+
end
|
677
|
+
end
|
678
|
+
end if Redis.current.respond_to?(:zscan)
|
679
|
+
|
680
|
+
context '#zscan_each' do
|
681
|
+
context 'when :match supplied' do
|
682
|
+
context 'when given a block' do
|
683
|
+
it 'should yield the correct set elements and scores unchanged' do
|
684
|
+
results = []
|
685
|
+
@namespaced.zscan_each('zset', :match => 'zeta:*', :count => 1000) { |ms| results << ms}
|
686
|
+
results.should =~ hash_matching_subset.to_a
|
687
|
+
end
|
688
|
+
end
|
689
|
+
context 'without a block' do
|
690
|
+
it 'should return an Enumerator that yields the correct set elements and scoresunchanged' do
|
691
|
+
enum = @namespaced.zscan_each('zset', :match => 'zeta:*', :count => 1000)
|
692
|
+
enum.to_a.should =~ hash_matching_subset.to_a
|
693
|
+
end
|
694
|
+
end
|
695
|
+
end
|
696
|
+
context 'without :match supplied' do
|
697
|
+
context 'when given a block' do
|
698
|
+
it 'should yield all set elements and scores unchanged' do
|
699
|
+
results = []
|
700
|
+
@namespaced.zscan_each('zset', :count => 1000){ |ms| results << ms }
|
701
|
+
results.should =~ hash.to_a
|
702
|
+
end
|
703
|
+
end
|
704
|
+
context 'without a block' do
|
705
|
+
it 'should return an Enumerator that yields all set elements and scores unchanged' do
|
706
|
+
enum = @namespaced.zscan_each('zset', :count => 1000)
|
707
|
+
enum.to_a.should =~ hash.to_a
|
708
|
+
end
|
709
|
+
end
|
710
|
+
end
|
711
|
+
end if Redis.current.respond_to?(:zscan_each)
|
712
|
+
end
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
461
716
|
# Only test aliasing functionality for Redis clients that support aliases.
|
462
717
|
unless Redis::Namespace::ALIASES.empty?
|
463
718
|
it "should support command aliases (delete)" do
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-namespace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.4.0.rc.0
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Chris Wanstrath
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-11-
|
14
|
+
date: 2013-11-16 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: redis
|
@@ -99,9 +99,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
100
|
none: false
|
101
101
|
requirements:
|
102
|
-
- - ! '
|
102
|
+
- - ! '>'
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
104
|
+
version: 1.3.1
|
105
105
|
requirements: []
|
106
106
|
rubyforge_project:
|
107
107
|
rubygems_version: 1.8.24
|