redis-objects 1.3.1 → 1.5.1
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 +5 -5
- data/.travis.yml +2 -4
- data/CHANGELOG.rdoc +99 -0
- data/README.md +50 -8
- data/lib/redis/base_object.rb +6 -0
- data/lib/redis/counter.rb +2 -6
- data/lib/redis/enumerable_object.rb +28 -0
- data/lib/redis/hash_key.rb +2 -22
- data/lib/redis/helpers/core_commands.rb +12 -11
- data/lib/redis/list.rb +6 -21
- data/lib/redis/lock.rb +23 -28
- data/lib/redis/objects.rb +9 -4
- data/lib/redis/objects/connection_pool_proxy.rb +1 -0
- data/lib/redis/objects/hashes.rb +9 -0
- data/lib/redis/objects/lists.rb +9 -0
- data/lib/redis/objects/sets.rb +9 -0
- data/lib/redis/objects/version.rb +1 -1
- data/lib/redis/set.rb +5 -22
- data/lib/redis/sorted_set.rb +30 -41
- data/lib/redis/value.rb +25 -5
- data/spec/redis_objects_custom_serializer.rb +198 -0
- data/spec/redis_objects_instance_spec.rb +127 -36
- data/spec/redis_objects_model_spec.rb +32 -3
- metadata +11 -9
data/lib/redis/lock.rb
CHANGED
@@ -11,7 +11,6 @@ class Redis
|
|
11
11
|
class Lock < BaseObject
|
12
12
|
class LockTimeout < StandardError; end #:nodoc:
|
13
13
|
|
14
|
-
attr_reader :key, :options
|
15
14
|
def initialize(key, *args)
|
16
15
|
super(key, *args)
|
17
16
|
@options[:timeout] ||= 5
|
@@ -19,13 +18,6 @@ class Redis
|
|
19
18
|
redis.setnx(key, @options[:start]) unless @options[:start] == 0 || @options[:init] === false
|
20
19
|
end
|
21
20
|
|
22
|
-
# Clear the lock. Should only be needed if there's a server crash
|
23
|
-
# or some other event that gets locks in a stuck state.
|
24
|
-
def clear
|
25
|
-
redis.del(key)
|
26
|
-
end
|
27
|
-
alias_method :delete, :clear
|
28
|
-
|
29
21
|
def value
|
30
22
|
nil
|
31
23
|
end
|
@@ -33,28 +25,30 @@ class Redis
|
|
33
25
|
# Get the lock and execute the code block. Any other code that needs the lock
|
34
26
|
# (on any server) will spin waiting for the lock up to the :timeout
|
35
27
|
# that was specified when the lock was defined.
|
36
|
-
def lock
|
37
|
-
|
28
|
+
def lock
|
29
|
+
raise ArgumentError, 'Block not given' unless block_given?
|
30
|
+
expiration_ms = generate_expiration
|
31
|
+
expiration_s = expiration_ms / 1000.0
|
32
|
+
end_time = nil
|
38
33
|
try_until_timeout do
|
39
|
-
|
40
|
-
#
|
41
|
-
|
34
|
+
end_time = Time.now.to_i + expiration_s
|
35
|
+
# Set a NX record and use the Redis expiration mechanism.
|
36
|
+
# Empty value because the presence of it is enough to lock
|
37
|
+
# `px` only except an Integer in millisecond
|
38
|
+
break if redis.set(key, nil, px: expiration_ms, nx: true)
|
42
39
|
|
43
|
-
#
|
44
|
-
#
|
45
|
-
|
46
|
-
if !@options[:expiration].nil?
|
40
|
+
# Backward compatibility code
|
41
|
+
# TODO: remove at the next major release for performance
|
42
|
+
unless @options[:expiration].nil?
|
47
43
|
old_expiration = redis.get(key).to_f
|
48
44
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
# and we now have it.
|
57
|
-
break if old_expiration < Time.now.to_f
|
45
|
+
# Check it was not an empty string with `zero?` and
|
46
|
+
# the expiration time is passed.
|
47
|
+
if !old_expiration.zero? && old_expiration < Time.now.to_f
|
48
|
+
expiration_ms = generate_expiration
|
49
|
+
expiration_s = expiration_ms / 1000.0
|
50
|
+
end_time = Time.now.to_i + expiration_s
|
51
|
+
break if redis.set(key, nil, px: expiration_ms)
|
58
52
|
end
|
59
53
|
end
|
60
54
|
end
|
@@ -66,14 +60,15 @@ class Redis
|
|
66
60
|
# it's not safe for us to remove it. Check how much time has passed since we
|
67
61
|
# wrote the lock key and only delete it if it hasn't expired (or we're not using
|
68
62
|
# lock expiration)
|
69
|
-
if @options[:expiration].nil? ||
|
63
|
+
if @options[:expiration].nil? || end_time > Time.now.to_f
|
70
64
|
redis.del(key)
|
71
65
|
end
|
72
66
|
end
|
73
67
|
end
|
74
68
|
|
69
|
+
# Return expiration in milliseconds
|
75
70
|
def generate_expiration
|
76
|
-
@options[:expiration].nil? ? 1 :
|
71
|
+
((@options[:expiration].nil? ? 1 : @options[:expiration].to_f) * 1000).to_i
|
77
72
|
end
|
78
73
|
|
79
74
|
private
|
data/lib/redis/objects.rb
CHANGED
@@ -46,8 +46,6 @@ class Redis
|
|
46
46
|
#
|
47
47
|
#
|
48
48
|
module Objects
|
49
|
-
dir = File.expand_path(__FILE__.sub(/\.rb$/,''))
|
50
|
-
|
51
49
|
autoload :Counters, 'redis/objects/counters'
|
52
50
|
autoload :Lists, 'redis/objects/lists'
|
53
51
|
autoload :Locks, 'redis/objects/locks'
|
@@ -173,8 +171,15 @@ class Redis
|
|
173
171
|
def redis() self.class.redis end
|
174
172
|
def redis_objects() self.class.redis_objects end
|
175
173
|
|
176
|
-
def
|
177
|
-
redis.del(
|
174
|
+
def redis_delete_objects
|
175
|
+
redis.del(redis_instance_keys)
|
176
|
+
end
|
177
|
+
|
178
|
+
def redis_instance_keys
|
179
|
+
redis_objects
|
180
|
+
.reject { |_, value| value[:global] }
|
181
|
+
.keys
|
182
|
+
.collect { |name| redis_field_key(name) }
|
178
183
|
end
|
179
184
|
|
180
185
|
def redis_options(name) #:nodoc:
|
@@ -9,6 +9,7 @@ class Redis
|
|
9
9
|
def method_missing(name, *args, &block)
|
10
10
|
@pool.with { |x| x.send(name, *args, &block) }
|
11
11
|
end
|
12
|
+
ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
|
12
13
|
|
13
14
|
def respond_to_missing?(name, include_all = false)
|
14
15
|
@pool.with { |x| x.respond_to?(name, include_all) }
|
data/lib/redis/objects/hashes.rb
CHANGED
data/lib/redis/objects/lists.rb
CHANGED
data/lib/redis/objects/sets.rb
CHANGED
data/lib/redis/set.rb
CHANGED
@@ -1,17 +1,10 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/
|
1
|
+
require File.dirname(__FILE__) + '/enumerable_object'
|
2
2
|
|
3
3
|
class Redis
|
4
4
|
#
|
5
5
|
# Class representing a set.
|
6
6
|
#
|
7
|
-
class Set <
|
8
|
-
require 'enumerator'
|
9
|
-
include Enumerable
|
10
|
-
require 'redis/helpers/core_commands'
|
11
|
-
include Redis::Helpers::CoreCommands
|
12
|
-
|
13
|
-
attr_reader :key, :options
|
14
|
-
|
7
|
+
class Set < EnumerableObject
|
15
8
|
# Works like add. Can chain together: list << 'a' << 'b'
|
16
9
|
def <<(value)
|
17
10
|
add(value)
|
@@ -27,8 +20,8 @@ class Redis
|
|
27
20
|
end
|
28
21
|
|
29
22
|
# Remove and return a random member. Redis: SPOP
|
30
|
-
def pop
|
31
|
-
unmarshal redis.spop(key)
|
23
|
+
def pop(count = nil)
|
24
|
+
unmarshal redis.spop(key, count)
|
32
25
|
end
|
33
26
|
|
34
27
|
# return a random member. Redis: SRANDMEMBER
|
@@ -74,12 +67,6 @@ class Redis
|
|
74
67
|
res
|
75
68
|
end
|
76
69
|
|
77
|
-
# Iterate through each member of the set. Redis::Objects mixes in Enumerable,
|
78
|
-
# so you can also use familiar methods like +collect+, +detect+, and so forth.
|
79
|
-
def each(&block)
|
80
|
-
members.each(&block)
|
81
|
-
end
|
82
|
-
|
83
70
|
# Return the intersection with another set. Can pass it either another set
|
84
71
|
# object or set name. Also available as & which is a bit cleaner:
|
85
72
|
#
|
@@ -165,7 +152,7 @@ class Redis
|
|
165
152
|
redis.smove(key, destination.is_a?(Redis::Set) ? destination.key : destination.to_s, value)
|
166
153
|
end
|
167
154
|
|
168
|
-
# The number of members in the set. Aliased as size. Redis: SCARD
|
155
|
+
# The number of members in the set. Aliased as size or count. Redis: SCARD
|
169
156
|
def length
|
170
157
|
redis.scard(key)
|
171
158
|
end
|
@@ -185,10 +172,6 @@ class Redis
|
|
185
172
|
members.join(', ')
|
186
173
|
end
|
187
174
|
|
188
|
-
def as_json(*)
|
189
|
-
to_hash
|
190
|
-
end
|
191
|
-
|
192
175
|
private
|
193
176
|
|
194
177
|
def keys_from_objects(sets)
|
data/lib/redis/sorted_set.rb
CHANGED
@@ -1,17 +1,10 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/
|
1
|
+
require File.dirname(__FILE__) + '/enumerable_object'
|
2
2
|
|
3
3
|
class Redis
|
4
4
|
#
|
5
5
|
# Class representing a sorted set.
|
6
6
|
#
|
7
|
-
class SortedSet <
|
8
|
-
# require 'enumerator'
|
9
|
-
# include Enumerable
|
10
|
-
require 'redis/helpers/core_commands'
|
11
|
-
include Redis::Helpers::CoreCommands
|
12
|
-
|
13
|
-
attr_reader :key, :options
|
14
|
-
|
7
|
+
class SortedSet < EnumerableObject
|
15
8
|
# How to add values using a sorted set. The key is the member, eg,
|
16
9
|
# "Peter", and the value is the score, eg, 163. So:
|
17
10
|
# num_posts['Peter'] = 163
|
@@ -124,7 +117,7 @@ class Redis
|
|
124
117
|
options[:offset] || options[:limit] || options[:count]
|
125
118
|
args[:with_scores] = true if options[:withscores] || options[:with_scores]
|
126
119
|
|
127
|
-
redis.zrangebyscore(key, min, max, args).map{|v| unmarshal(v) }
|
120
|
+
redis.zrangebyscore(key, min, max, **args).map{|v| unmarshal(v) }
|
128
121
|
end
|
129
122
|
|
130
123
|
# Returns all the elements in the sorted set at key with a score between max and min
|
@@ -140,7 +133,7 @@ class Redis
|
|
140
133
|
options[:offset] || options[:limit] || options[:count]
|
141
134
|
args[:with_scores] = true if options[:withscores] || options[:with_scores]
|
142
135
|
|
143
|
-
redis.zrevrangebyscore(key, max, min, args).map{|v| unmarshal(v) }
|
136
|
+
redis.zrevrangebyscore(key, max, min, **args).map{|v| unmarshal(v) }
|
144
137
|
end
|
145
138
|
|
146
139
|
# Remove all elements in the sorted set at key with rank between start and end. Start and end are
|
@@ -208,7 +201,17 @@ class Redis
|
|
208
201
|
#
|
209
202
|
# Redis: SINTER
|
210
203
|
def intersection(*sets)
|
211
|
-
|
204
|
+
result = nil
|
205
|
+
temp_key = :"#{key}:intersection:#{Time.current.to_i + rand}"
|
206
|
+
|
207
|
+
redis.multi do
|
208
|
+
interstore(temp_key, *sets)
|
209
|
+
redis.expire(temp_key, 1)
|
210
|
+
|
211
|
+
result = redis.zrange(temp_key, 0, -1)
|
212
|
+
end
|
213
|
+
|
214
|
+
result.value
|
212
215
|
end
|
213
216
|
alias_method :intersect, :intersection
|
214
217
|
alias_method :inter, :intersection
|
@@ -219,7 +222,7 @@ class Redis
|
|
219
222
|
def interstore(name, *sets)
|
220
223
|
allow_expiration do
|
221
224
|
opts = sets.last.is_a?(Hash) ? sets.pop : {}
|
222
|
-
redis.zinterstore(key_from_object(name), keys_from_objects([self] + sets), opts)
|
225
|
+
redis.zinterstore(key_from_object(name), keys_from_objects([self] + sets), **opts)
|
223
226
|
end
|
224
227
|
end
|
225
228
|
|
@@ -235,7 +238,17 @@ class Redis
|
|
235
238
|
#
|
236
239
|
# Redis: SUNION
|
237
240
|
def union(*sets)
|
238
|
-
|
241
|
+
result = nil
|
242
|
+
temp_key = :"#{key}:union:#{Time.current.to_i + rand}"
|
243
|
+
|
244
|
+
redis.multi do
|
245
|
+
unionstore(temp_key, *sets)
|
246
|
+
redis.expire(temp_key, 1)
|
247
|
+
|
248
|
+
result = redis.zrange(temp_key, 0, -1)
|
249
|
+
end
|
250
|
+
|
251
|
+
result.value
|
239
252
|
end
|
240
253
|
alias_method :|, :union
|
241
254
|
alias_method :+, :union
|
@@ -245,35 +258,10 @@ class Redis
|
|
245
258
|
def unionstore(name, *sets)
|
246
259
|
allow_expiration do
|
247
260
|
opts = sets.last.is_a?(Hash) ? sets.pop : {}
|
248
|
-
redis.zunionstore(key_from_object(name), keys_from_objects([self] + sets), opts)
|
261
|
+
redis.zunionstore(key_from_object(name), keys_from_objects([self] + sets), **opts)
|
249
262
|
end
|
250
263
|
end
|
251
264
|
|
252
|
-
# Return the difference vs another set. Can pass it either another set
|
253
|
-
# object or set name. Also available as ^ or - which is a bit cleaner:
|
254
|
-
#
|
255
|
-
# members_difference = set1 ^ set2
|
256
|
-
# members_difference = set1 - set2
|
257
|
-
#
|
258
|
-
# If you want to specify multiple sets, you must use +difference+:
|
259
|
-
#
|
260
|
-
# members_difference = set1.difference(set2, set3, set4)
|
261
|
-
# members_difference = set1.diff(set2, set3, set4)
|
262
|
-
#
|
263
|
-
# Redis: SDIFF
|
264
|
-
def difference(*sets)
|
265
|
-
redis.zdiff(key, *keys_from_objects(sets)).map{|v| unmarshal(v) }
|
266
|
-
end
|
267
|
-
alias_method :diff, :difference
|
268
|
-
alias_method :^, :difference
|
269
|
-
alias_method :-, :difference
|
270
|
-
|
271
|
-
# Calculate the diff and store it in Redis as +name+. Returns the number
|
272
|
-
# of elements in the stored union. Redis: SDIFFSTORE
|
273
|
-
def diffstore(name, *sets)
|
274
|
-
redis.zdiffstore(name, key, *keys_from_objects(sets))
|
275
|
-
end
|
276
|
-
|
277
265
|
# Returns true if the set has no members. Redis: SCARD == 0
|
278
266
|
def empty?
|
279
267
|
length == 0
|
@@ -303,11 +291,12 @@ class Redis
|
|
303
291
|
at(-1)
|
304
292
|
end
|
305
293
|
|
306
|
-
# The number of members in the set. Aliased as size. Redis: ZCARD
|
294
|
+
# The number of members in the set. Aliased as size or count. Redis: ZCARD
|
307
295
|
def length
|
308
296
|
redis.zcard(key)
|
309
297
|
end
|
310
298
|
alias_method :size, :length
|
299
|
+
alias_method :count, :length
|
311
300
|
|
312
301
|
# The number of members within a range of scores. Redis: ZCOUNT
|
313
302
|
def range_size(min, max)
|
data/lib/redis/value.rb
CHANGED
@@ -1,15 +1,11 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/base_object'
|
2
|
+
require 'zlib'
|
2
3
|
|
3
4
|
class Redis
|
4
5
|
#
|
5
6
|
# Class representing a simple value. You can use standard Ruby operations on it.
|
6
7
|
#
|
7
8
|
class Value < BaseObject
|
8
|
-
require 'redis/helpers/core_commands'
|
9
|
-
include Redis::Helpers::CoreCommands
|
10
|
-
|
11
|
-
attr_reader :key, :options
|
12
|
-
|
13
9
|
def value=(val)
|
14
10
|
allow_expiration do
|
15
11
|
if val.nil?
|
@@ -31,6 +27,30 @@ class Redis
|
|
31
27
|
end
|
32
28
|
alias_method :get, :value
|
33
29
|
|
30
|
+
def marshal(value, *args)
|
31
|
+
if !value.nil? && options[:compress]
|
32
|
+
compress(super)
|
33
|
+
else
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def unmarshal(value, *args)
|
39
|
+
if !value.nil? && options[:compress]
|
40
|
+
super(decompress(value), *args)
|
41
|
+
else
|
42
|
+
super
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def decompress(value)
|
47
|
+
Zlib::Inflate.inflate(value)
|
48
|
+
end
|
49
|
+
|
50
|
+
def compress(value)
|
51
|
+
Zlib::Deflate.deflate(value)
|
52
|
+
end
|
53
|
+
|
34
54
|
def inspect
|
35
55
|
"#<Redis::Value #{value.inspect}>"
|
36
56
|
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
|
+
|
4
|
+
require 'redis/objects'
|
5
|
+
|
6
|
+
class CustomSerializer
|
7
|
+
class << self
|
8
|
+
attr_accessor :dump_called, :load_called, :dump_args, :load_args
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.dump(value, *args, **kargs)
|
12
|
+
@dump_called = true
|
13
|
+
@dump_args = [args, kargs]
|
14
|
+
Marshal.dump(value)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.load(value, *args, **kargs)
|
18
|
+
@load_called = true
|
19
|
+
@load_args = [args, kargs]
|
20
|
+
Marshal.load(value)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.reset!
|
24
|
+
@dump_called = nil
|
25
|
+
@load_called = nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'with custom serialization' do
|
30
|
+
before do
|
31
|
+
CustomSerializer.reset!
|
32
|
+
end
|
33
|
+
|
34
|
+
describe Redis::Value do
|
35
|
+
before do
|
36
|
+
@value = Redis::Value.new(
|
37
|
+
'spec/value_custom_serializer',
|
38
|
+
marshal: true,
|
39
|
+
serializer: CustomSerializer
|
40
|
+
)
|
41
|
+
@value.clear
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'uses custom serializer' do
|
45
|
+
@value.value = { json: 'data' }
|
46
|
+
CustomSerializer.dump_called.should == true
|
47
|
+
CustomSerializer.load_called.should == nil
|
48
|
+
@value.value.should == { json: 'data' }
|
49
|
+
CustomSerializer.dump_called.should == true
|
50
|
+
CustomSerializer.load_called.should == true
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'passes extra arguments to dump' do
|
54
|
+
@value.options[:marshal_dump_args] = ['some', { extra: 'arguments' }]
|
55
|
+
@value.value = 1
|
56
|
+
CustomSerializer.dump_args.should == [['some'], { extra: 'arguments' }]
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'passes extra arguments to load' do
|
60
|
+
@value.options[:marshal_load_args] = ['some', { extra: 'arguments' }]
|
61
|
+
@value.value = 1
|
62
|
+
@value.value.should == 1
|
63
|
+
CustomSerializer.load_args.should == [['some'], { extra: 'arguments' }]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe Redis::List do
|
68
|
+
before do
|
69
|
+
@list = Redis::List.new(
|
70
|
+
'spec/list_custom_serializer',
|
71
|
+
marshal: true,
|
72
|
+
serializer: CustomSerializer
|
73
|
+
)
|
74
|
+
@list.clear
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'uses custom serializer' do
|
78
|
+
@list << { json: 'data' }
|
79
|
+
CustomSerializer.dump_called.should == true
|
80
|
+
CustomSerializer.load_called.should == nil
|
81
|
+
@list.should == [{ json: 'data' }]
|
82
|
+
CustomSerializer.dump_called.should == true
|
83
|
+
CustomSerializer.load_called.should == true
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'passes extra arguments to dump' do
|
87
|
+
@list.options[:marshal_dump_args] = ['some', { extra: 'arguments' }]
|
88
|
+
@list << 1
|
89
|
+
CustomSerializer.dump_args.should == [['some'], { extra: 'arguments' }]
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'passes extra arguments to load' do
|
93
|
+
@list.options[:marshal_load_args] = ['some', { extra: 'arguments' }]
|
94
|
+
@list << 1
|
95
|
+
@list.values.should == [1]
|
96
|
+
CustomSerializer.load_args.should == [['some'], { extra: 'arguments' }]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe Redis::HashKey do
|
101
|
+
before do
|
102
|
+
@hash = Redis::HashKey.new(
|
103
|
+
'spec/hash_custom_serializer',
|
104
|
+
marshal: true,
|
105
|
+
serializer: CustomSerializer
|
106
|
+
)
|
107
|
+
@hash.clear
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'uses custom serializer' do
|
111
|
+
@hash['a'] = 1
|
112
|
+
CustomSerializer.dump_called.should == true
|
113
|
+
CustomSerializer.load_called.should == nil
|
114
|
+
@hash.value.should == { 'a' => 1 }
|
115
|
+
CustomSerializer.dump_called.should == true
|
116
|
+
CustomSerializer.load_called.should == true
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'passes extra arguments to dump' do
|
120
|
+
@hash.options[:marshal_dump_args] = ['some', { extra: 'arguments' }]
|
121
|
+
@hash['a'] = 1
|
122
|
+
CustomSerializer.dump_args.should == [['some'], { extra: 'arguments' }]
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'passes extra arguments to load' do
|
126
|
+
@hash.options[:marshal_load_args] = ['some', { extra: 'arguments' }]
|
127
|
+
@hash['a'] = 1
|
128
|
+
@hash.value.should == { 'a' => 1 }
|
129
|
+
CustomSerializer.load_args.should == [['some'], { extra: 'arguments' }]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe Redis::Set do
|
134
|
+
before do
|
135
|
+
@set = Redis::Set.new(
|
136
|
+
'spec/set_custom_serializer',
|
137
|
+
marshal: true,
|
138
|
+
serializer: CustomSerializer
|
139
|
+
)
|
140
|
+
@set.clear
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'uses custom serializer' do
|
144
|
+
@set << 'a'
|
145
|
+
CustomSerializer.dump_called.should == true
|
146
|
+
CustomSerializer.load_called.should == nil
|
147
|
+
@set.members.should == ['a']
|
148
|
+
CustomSerializer.dump_called.should == true
|
149
|
+
CustomSerializer.load_called.should == true
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'passes extra arguments to dump' do
|
153
|
+
@set.options[:marshal_dump_args] = ['some', { extra: 'arguments' }]
|
154
|
+
@set << 'a'
|
155
|
+
CustomSerializer.dump_args.should == [['some'], { extra: 'arguments' }]
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'passes extra arguments to load' do
|
159
|
+
@set.options[:marshal_load_args] = ['some', { extra: 'arguments' }]
|
160
|
+
@set << 'a'
|
161
|
+
@set.members.should == ['a']
|
162
|
+
CustomSerializer.load_args.should == [['some'], { extra: 'arguments' }]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe Redis::SortedSet do
|
167
|
+
before do
|
168
|
+
@set = Redis::SortedSet.new(
|
169
|
+
'spec/zset_custom_serializer',
|
170
|
+
marshal: true,
|
171
|
+
serializer: CustomSerializer
|
172
|
+
)
|
173
|
+
@set.clear
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'uses custom serializer' do
|
177
|
+
@set['a'] = 1
|
178
|
+
CustomSerializer.dump_called.should == true
|
179
|
+
CustomSerializer.load_called.should == nil
|
180
|
+
@set.members.should == ['a']
|
181
|
+
CustomSerializer.dump_called.should == true
|
182
|
+
CustomSerializer.load_called.should == true
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'passes extra arguments to dump' do
|
186
|
+
@set.options[:marshal_dump_args] = ['some', { extra: 'arguments' }]
|
187
|
+
@set['a'] = 1
|
188
|
+
CustomSerializer.dump_args.should == [['some'], { extra: 'arguments' }]
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'passes extra arguments to load' do
|
192
|
+
@set.options[:marshal_load_args] = ['some', { extra: 'arguments' }]
|
193
|
+
@set['a'] = 1
|
194
|
+
@set.members.should == ['a']
|
195
|
+
CustomSerializer.load_args.should == [['some'], { extra: 'arguments' }]
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|