redis-store 1.5.0 → 1.9.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.
@@ -5,8 +5,16 @@ class Redis
5
5
  super(key)
6
6
  end
7
7
 
8
+ REDIS_SET_OPTIONS = %i(ex px nx xx keepttl).freeze
9
+ private_constant :REDIS_SET_OPTIONS
10
+
8
11
  def set(key, value, options = nil)
9
- super(key, value, options || {})
12
+ if options && REDIS_SET_OPTIONS.any? { |k| options.key?(k) }
13
+ kwargs = REDIS_SET_OPTIONS.each_with_object({}) { |key, h| h[key] = options[key] if options.key?(key) }
14
+ super(key, value, **kwargs)
15
+ else
16
+ super(key, value)
17
+ end
10
18
  end
11
19
 
12
20
  def setnx(key, value, options = nil)
@@ -3,28 +3,32 @@ class Redis
3
3
  module Namespace
4
4
  FLUSHDB_BATCH_SIZE = 1000
5
5
 
6
- def set(key, val, options = nil)
7
- namespace(key) { |k| super(k, val, options) }
6
+ def set(key, *args)
7
+ namespace(key) { |k| super(k, *args) }
8
8
  end
9
9
 
10
- def setex(key, ttl, val, options = nil)
11
- namespace(key) { |k| super(k, ttl, val, options) }
10
+ def setex(key, *args)
11
+ namespace(key) { |k| super(k, *args) }
12
12
  end
13
13
 
14
- def setnx(key, val, options = nil)
15
- namespace(key) { |k| super(k, val, options) }
14
+ def setnx(key, *args)
15
+ namespace(key) { |k| super(k, *args) }
16
16
  end
17
17
 
18
18
  def ttl(key, options = nil)
19
19
  namespace(key) { |k| super(k) }
20
20
  end
21
21
 
22
- def get(key, options = nil)
23
- namespace(key) { |k| super(k, options) }
22
+ def get(key, *args)
23
+ namespace(key) { |k| super(k, *args) }
24
24
  end
25
25
 
26
- def exists(key)
27
- namespace(key) { |k| super(k) }
26
+ def exists(*keys)
27
+ super(*keys.map { |key| interpolate(key) })
28
+ end
29
+
30
+ def exists?(*keys)
31
+ super(*keys.map { |key| interpolate(key) })
28
32
  end
29
33
 
30
34
  def incrby(key, increment)
@@ -36,15 +40,30 @@ class Redis
36
40
  end
37
41
 
38
42
  def keys(pattern = "*")
39
- namespace(pattern) { |p| super(p).map{|key| strip_namespace(key) } }
43
+ namespace(pattern) { |p| super(p).map { |key| strip_namespace(key) } }
44
+ end
45
+
46
+ def scan(cursor, match: nil, **kwargs)
47
+ if match
48
+ namespace(match) do |pattern|
49
+ cursor, keys = super(cursor, match: pattern, **kwargs)
50
+ [ cursor, keys.map{ |key| strip_namespace(key) } ]
51
+ end
52
+ else
53
+ super(cursor, **kwargs)
54
+ end
40
55
  end
41
56
 
42
57
  def del(*keys)
43
- super(*keys.map {|key| interpolate(key) }) if keys.any?
58
+ super(*keys.map { |key| interpolate(key) }) if keys.any?
59
+ end
60
+
61
+ def unlink(*keys)
62
+ super(*keys.map { |key| interpolate(key) }) if keys.any?
44
63
  end
45
64
 
46
65
  def watch(*keys)
47
- super(*keys.map {|key| interpolate(key) }) if keys.any?
66
+ super(*keys.map { |key| interpolate(key) }) if keys.any?
48
67
  end
49
68
 
50
69
  def mget(*keys, &blk)
@@ -52,15 +71,95 @@ class Redis
52
71
  if keys.any?
53
72
  # Serialization gets extended before Namespace does, so we need to pass options further
54
73
  if singleton_class.ancestors.include? Serialization
55
- super(*keys.map {|key| interpolate(key) }, options, &blk)
74
+ super(*keys.map { |key| interpolate(key) }, options, &blk)
56
75
  else
57
- super(*keys.map {|key| interpolate(key) }, &blk)
76
+ super(*keys.map { |key| interpolate(key) }, &blk)
58
77
  end
59
78
  end
60
79
  end
61
80
 
62
81
  def expire(key, ttl)
63
- namespace(key) { |k| super(k, ttl) }
82
+ namespace(key) { |k| super(k, ttl) }
83
+ end
84
+
85
+ def hdel(key, *fields)
86
+ namespace(key) { |k| super(k, *fields) }
87
+ end
88
+
89
+ def hget(key, field)
90
+ namespace(key) { |k| super(k, field) }
91
+ end
92
+
93
+ def hgetall(key)
94
+ namespace(key) { |k| super(k) }
95
+ end
96
+
97
+ def hexists(key, field)
98
+ namespace(key) { |k| super(k, field) }
99
+ end
100
+
101
+ def hincrby(key, field, increment)
102
+ namespace(key) { |k| super(k, field, increment) }
103
+ end
104
+
105
+ def hincrbyfloat(key, field, increment)
106
+ namespace(key) { |k| super(k, field, increment) }
107
+ end
108
+
109
+ def hkeys(key)
110
+ namespace(key) { |k| super(k) }
111
+ end
112
+
113
+ def hlen(key)
114
+ namespace(key) { |k| super(k) }
115
+ end
116
+
117
+ def hmget(key, *fields, &blk)
118
+ namespace(key) { |k| super(k, *fields, &blk) }
119
+ end
120
+
121
+ def hmset(key, *attrs)
122
+ namespace(key) { |k| super(k, *attrs) }
123
+ end
124
+
125
+ def hset(key, *args)
126
+ namespace(key) { |k| super(k, *args) }
127
+ end
128
+
129
+ def hsetnx(key, field, val)
130
+ namespace(key) { |k| super(k, field, val) }
131
+ end
132
+
133
+ def hvals(key)
134
+ namespace(key) { |k| super(k) }
135
+ end
136
+
137
+ def hscan(key, *args)
138
+ namespace(key) { |k| super(k, *args) }
139
+ end
140
+
141
+ def hscan_each(key, *args)
142
+ namespace(key) { |k| super(k, *args) }
143
+ end
144
+
145
+ def zincrby(key, increment, member)
146
+ namespace(key) { |k| super(k, increment, member) }
147
+ end
148
+
149
+ def zscore(key, member)
150
+ namespace(key) { |k| super(k, member) }
151
+ end
152
+
153
+ def zadd(key, *args)
154
+ namespace(key) { |k| super(k, *args) }
155
+ end
156
+
157
+ def zrem(key, member)
158
+ namespace(key) { |k| super(k, member) }
159
+ end
160
+
161
+ if respond_to?(:ruby2_keywords, true)
162
+ ruby2_keywords :set, :setex, :setnx, :hscan, :hscan_each
64
163
  end
65
164
 
66
165
  def to_s
@@ -11,4 +11,3 @@ class Redis
11
11
  end
12
12
  end
13
13
  end
14
-
@@ -34,7 +34,7 @@ class Redis
34
34
  end
35
35
 
36
36
  def with_multi_or_pipelined(options, &block)
37
- return pipelined(&block) if options[:avoid_multi_commands]
37
+ return pipelined(&block) if options.key?(:cluster) || options[:avoid_multi_commands]
38
38
  multi(&block)
39
39
  end
40
40
  end
@@ -1,5 +1,5 @@
1
1
  class Redis
2
2
  class Store < self
3
- VERSION = '1.5.0'
3
+ VERSION = '1.9.0'
4
4
  end
5
5
  end
@@ -1,4 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
+
2
3
  $:.push File.expand_path('../lib', __FILE__)
3
4
  require 'redis/store/version'
4
5
 
@@ -8,21 +9,19 @@ Gem::Specification.new do |s|
8
9
  s.authors = ['Luca Guidi']
9
10
  s.email = ['me@lucaguidi.com']
10
11
  s.homepage = 'http://redis-store.org/redis-store'
11
- s.summary = %q{Redis stores for Ruby frameworks}
12
- s.description = %q{Namespaced Rack::Session, Rack::Cache, I18n and cache Redis stores for Ruby web frameworks.}
13
-
14
- s.rubyforge_project = 'redis-store'
12
+ s.summary = 'Redis stores for Ruby frameworks'
13
+ s.description = 'Namespaced Rack::Session, Rack::Cache, I18n and cache Redis stores for Ruby web frameworks.'
15
14
 
16
15
  s.files = `git ls-files`.split("\n")
17
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
19
18
  s.require_paths = ["lib"]
20
19
  s.license = 'MIT'
21
20
 
22
- s.add_dependency 'redis', '>= 2.2', '< 5'
21
+ s.add_dependency 'redis', '>= 4', '< 5'
23
22
 
24
- s.add_development_dependency 'rake', '~> 10'
25
- s.add_development_dependency 'bundler', '~> 1.3'
23
+ s.add_development_dependency 'rake', '>= 12.3.3'
24
+ s.add_development_dependency 'bundler'
26
25
  s.add_development_dependency 'mocha', '~> 0.14.0'
27
26
  s.add_development_dependency 'minitest', '~> 5'
28
27
  s.add_development_dependency 'git', '~> 1.2'
@@ -30,4 +29,5 @@ Gem::Specification.new do |s|
30
29
  s.add_development_dependency 'pry', '~> 0.10.4'
31
30
  s.add_development_dependency 'redis-store-testing'
32
31
  s.add_development_dependency 'appraisal', '~> 2.0'
32
+ s.add_development_dependency 'rubocop', '~> 0.54'
33
33
  end
@@ -3,8 +3,8 @@ require 'test_helper'
3
3
  describe "Redis::DistributedStore" do
4
4
  def setup
5
5
  @dmr = Redis::DistributedStore.new [
6
- {:host => "localhost", :port => "6380", :db => 0},
7
- {:host => "localhost", :port => "6381", :db => 0}
6
+ { :host => "localhost", :port => "6380", :db => 0 },
7
+ { :host => "localhost", :port => "6381", :db => 0 }
8
8
  ]
9
9
  @rabbit = OpenStruct.new :name => "bunny"
10
10
  @white_rabbit = OpenStruct.new :color => "white"
@@ -67,8 +67,8 @@ describe "Redis::DistributedStore" do
67
67
 
68
68
  it "passes through ring replica options" do
69
69
  dmr = Redis::DistributedStore.new [
70
- {:host => "localhost", :port => "6380", :db => 0},
71
- {:host => "localhost", :port => "6381", :db => 0}
70
+ { :host => "localhost", :port => "6380", :db => 0 },
71
+ { :host => "localhost", :port => "6381", :db => 0 }
72
72
  ], replicas: 1024
73
73
  dmr.ring.replicas.must_equal 1024
74
74
  end
@@ -76,8 +76,8 @@ describe "Redis::DistributedStore" do
76
76
  it "uses a custom ring object" do
77
77
  my_ring = Redis::HashRing.new
78
78
  dmr = Redis::DistributedStore.new [
79
- {:host => "localhost", :port => "6380", :db => 0},
80
- {:host => "localhost", :port => "6381", :db => 0}
79
+ { :host => "localhost", :port => "6380", :db => 0 },
80
+ { :host => "localhost", :port => "6381", :db => 0 }
81
81
  ], ring: my_ring
82
82
  dmr.ring.must_equal my_ring
83
83
  dmr.ring.nodes.length.must_equal 2
@@ -100,8 +100,8 @@ describe "Redis::DistributedStore" do
100
100
  describe "namespace" do
101
101
  it "uses namespaced key" do
102
102
  @dmr = Redis::DistributedStore.new [
103
- {:host => "localhost", :port => "6380", :db => 0},
104
- {:host => "localhost", :port => "6381", :db => 0}
103
+ { :host => "localhost", :port => "6380", :db => 0 },
104
+ { :host => "localhost", :port => "6381", :db => 0 }
105
105
  ], :namespace => "theplaylist"
106
106
 
107
107
  @dmr.expects(:node_for).with("theplaylist:rabbit").returns(@dmr.nodes.first)
@@ -22,6 +22,11 @@ describe "Redis::Store::Factory" do
22
22
  store.to_s.must_equal("Redis Client connected to localhost:6380 against DB 0")
23
23
  end
24
24
 
25
+ it "uses specified scheme" do
26
+ store = Redis::Store::Factory.create :scheme => "rediss"
27
+ store.instance_variable_get(:@client).scheme.must_equal('rediss')
28
+ end
29
+
25
30
  it "uses specified path" do
26
31
  store = Redis::Store::Factory.create :path => "/var/run/redis.sock"
27
32
  store.to_s.must_equal("Redis Client connected to /var/run/redis.sock against DB 0")
@@ -69,6 +74,23 @@ describe "Redis::Store::Factory" do
69
74
  store.instance_variable_get(:@options)[:raw].must_equal(false)
70
75
  end
71
76
 
77
+ describe "defaults" do
78
+ it "defaults to localhost if no host specified" do
79
+ store = Redis::Store::Factory.create
80
+ store.instance_variable_get(:@client).host.must_equal('127.0.0.1')
81
+ end
82
+
83
+ it "defaults to 6379 if no port specified" do
84
+ store = Redis::Store::Factory.create
85
+ store.instance_variable_get(:@client).port.must_equal(6379)
86
+ end
87
+
88
+ it "defaults to redis:// if no scheme specified" do
89
+ store = Redis::Store::Factory.create
90
+ store.instance_variable_get(:@client).scheme.must_equal('redis')
91
+ end
92
+ end
93
+
72
94
  describe 'with stdout disabled' do
73
95
  before do
74
96
  @original_stderr = $stderr
@@ -98,11 +120,11 @@ describe "Redis::Store::Factory" do
98
120
 
99
121
  it "should instantiate a Redis::DistributedStore store" do
100
122
  store = Redis::Store::Factory.create(
101
- {:host => "localhost", :port => 6379},
102
- {:host => "localhost", :port => 6380}
123
+ { :host => "localhost", :port => 6379 },
124
+ { :host => "localhost", :port => 6380 }
103
125
  )
104
126
  store.must_be_kind_of(Redis::DistributedStore)
105
- store.nodes.map {|node| node.to_s }.must_equal([
127
+ store.nodes.map { |node| node.to_s }.must_equal([
106
128
  "Redis Client connected to localhost:6379 against DB 0",
107
129
  "Redis Client connected to localhost:6380 against DB 0",
108
130
  ])
@@ -120,6 +142,16 @@ describe "Redis::Store::Factory" do
120
142
  store.to_s.must_equal("Redis Client connected to 127.0.0.1:6380 against DB 0")
121
143
  end
122
144
 
145
+ it "uses specified scheme" do
146
+ store = Redis::Store::Factory.create "rediss://127.0.0.1:6380"
147
+ store.instance_variable_get(:@client).scheme.must_equal('rediss')
148
+ end
149
+
150
+ it "correctly defaults to redis:// when relative scheme specified" do
151
+ store = Redis::Store::Factory.create "//127.0.0.1:6379"
152
+ store.instance_variable_get(:@client).scheme.must_equal('redis')
153
+ end
154
+
123
155
  it "uses specified path" do
124
156
  store = Redis::Store::Factory.create "unix:///var/run/redis.sock"
125
157
  store.to_s.must_equal("Redis Client connected to /var/run/redis.sock against DB 0")
@@ -174,50 +206,50 @@ describe "Redis::Store::Factory" do
174
206
  it "instantiates Redis::DistributedStore" do
175
207
  store = Redis::Store::Factory.create "redis://127.0.0.1:6379", "redis://127.0.0.1:6380"
176
208
  store.must_be_kind_of(Redis::DistributedStore)
177
- store.nodes.map {|node| node.to_s }.must_equal([
209
+ store.nodes.map { |node| node.to_s }.must_equal([
178
210
  "Redis Client connected to 127.0.0.1:6379 against DB 0",
179
211
  "Redis Client connected to 127.0.0.1:6380 against DB 0",
180
212
  ])
181
213
  end
182
214
  end
183
215
 
184
- describe 'when given host Hash and options Hash' do
216
+ describe 'when given host Hash and options Hash' do
185
217
  it 'instantiates Redis::Store and merges options' do
186
218
  store = Redis::Store::Factory.create(
187
- { :host => '127.0.0.1', :port => '6379' },
219
+ { :host => '127.0.0.1', :port => '6379' },
188
220
  { :namespace => 'theplaylist' }
189
221
  )
190
222
  end
191
223
 
192
- it 'instantiates Redis::DistributedStore and merges options' do
224
+ it 'instantiates Redis::DistributedStore and merges options' do
193
225
  store = Redis::Store::Factory.create(
194
- { :host => '127.0.0.1', :port => '6379' },
195
- { :host => '127.0.0.1', :port => '6380' },
226
+ { :host => '127.0.0.1', :port => '6379' },
227
+ { :host => '127.0.0.1', :port => '6380' },
196
228
  { :namespace => 'theplaylist' }
197
229
  )
198
- store.nodes.map {|node| node.to_s }.must_equal([
230
+ store.nodes.map { |node| node.to_s }.must_equal([
199
231
  "Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist",
200
232
  "Redis Client connected to 127.0.0.1:6380 against DB 0 with namespace theplaylist"
201
233
  ])
202
234
  end
203
235
  end
204
236
 
205
- describe 'when given host String and options Hash' do
206
- it 'instantiates Redis::Store and merges options' do
207
- store = Redis::Store::Factory.create "redis://127.0.0.1", { :namespace => 'theplaylist' }
237
+ describe 'when given host String and options Hash' do
238
+ it 'instantiates Redis::Store and merges options' do
239
+ store = Redis::Store::Factory.create "redis://127.0.0.1", :namespace => 'theplaylist'
208
240
  store.to_s.must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
209
241
  end
210
242
 
211
- it 'instantiates Redis::DistributedStore and merges options' do
212
- store = Redis::Store::Factory.create "redis://127.0.0.1:6379", "redis://127.0.0.1:6380", { :namespace => 'theplaylist' }
213
- store.nodes.map {|node| node.to_s }.must_equal([
243
+ it 'instantiates Redis::DistributedStore and merges options' do
244
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379", "redis://127.0.0.1:6380", :namespace => 'theplaylist'
245
+ store.nodes.map { |node| node.to_s }.must_equal([
214
246
  "Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist",
215
247
  "Redis Client connected to 127.0.0.1:6380 against DB 0 with namespace theplaylist",
216
248
  ])
217
249
  end
218
250
 
219
251
  it 'instantiates Redis::Store and sets namespace from String' do
220
- store = Redis::Store::Factory.create "redis://127.0.0.1:6379/0/theplaylist", { :expire_after => 5 }
252
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379/0/theplaylist", :expire_after => 5
221
253
  store.to_s.must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
222
254
  end
223
255
  end
@@ -10,18 +10,18 @@ describe Redis::Store::Interface do
10
10
  end
11
11
 
12
12
  it "should get an element" do
13
- lambda { @r.get("key", :option => true) } #.wont_raise ArgumentError
13
+ lambda { @r.get("key", :option => true) } # .wont_raise ArgumentError
14
14
  end
15
15
 
16
16
  it "should set an element" do
17
- lambda { @r.set("key", "value", :option => true) } #.wont_raise ArgumentError
17
+ lambda { @r.set("key", "value", :option => true) } # .wont_raise ArgumentError
18
18
  end
19
19
 
20
20
  it "should setnx an element" do
21
- lambda { @r.setnx("key", "value", :option => true) } #.wont_raise ArgumentError
21
+ lambda { @r.setnx("key", "value", :option => true) } # .wont_raise ArgumentError
22
22
  end
23
23
 
24
24
  it "should setex an element" do
25
- lambda { @r.setex("key", 1, "value", :option => true) } #.wont_raise ArgumentError
25
+ lambda { @r.setex("key", 1, "value", :option => true) } # .wont_raise ArgumentError
26
26
  end
27
27
  end