redis-objects 1.1.0 → 1.2.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 +4 -4
- data/CHANGELOG.rdoc +12 -1
- data/lib/redis/base_object.rb +2 -13
- data/lib/redis/counter.rb +26 -18
- data/lib/redis/hash_key.rb +28 -23
- data/lib/redis/list.rb +14 -8
- data/lib/redis/lock.rb +18 -12
- data/lib/redis/objects/version.rb +1 -1
- data/lib/redis/set.rb +3 -4
- data/lib/redis/sorted_set.rb +28 -14
- data/lib/redis/value.rb +6 -6
- data/spec/redis_objects_active_record_spec.rb +4 -4
- data/spec/redis_objects_instance_spec.rb +179 -78
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4c3ed8e9d16f4beddbb3e7192845ba17a8367bdb
|
|
4
|
+
data.tar.gz: 834245d36db41b311e29d9c2cdce0a7ab02a14e1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 446c36a59eed213a54d2c73479096b1ffb1cb778cef1f40a1a42ce9bc7e773abe13251a78976b75b15387247f1f28cf8cb8708131608340b27e71e239aa4b191
|
|
7
|
+
data.tar.gz: 47626977f71544038bb1a9d3ef0261e126ca804a21c798c6efcca297d8d4b7d012f3ff9701f479d2339f2ceb4b4e5499553814b1d8bba4da0ce72aec030f6190
|
data/CHANGELOG.rdoc
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
= Changelog for Redis::Objects
|
|
2
2
|
|
|
3
|
+
== 1.2.0 (30 Apr 2015)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
* New expiration implementation to address edge cases and missing methods [Ross Kaffenberger]
|
|
7
|
+
|
|
8
|
+
* Add support for expiration/expireat on HashKey#update [Ross Kaffenberger]
|
|
9
|
+
|
|
10
|
+
* Make locks with 0 timeout possible Jean Boussier]
|
|
11
|
+
|
|
12
|
+
* Update hdel methods to support deleting multiple keys [Star]
|
|
13
|
+
|
|
3
14
|
== 1.1.0 (21 Jan 2015)
|
|
4
15
|
|
|
5
|
-
* Support connection_pool
|
|
16
|
+
* Support connection_pool usage via a proxy object [Jared Jenkins]
|
|
6
17
|
|
|
7
18
|
* Fix typo on :counter usage [Kevin Bongart]
|
|
8
19
|
|
data/lib/redis/base_object.rb
CHANGED
|
@@ -22,19 +22,8 @@ class Redis
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
names.each do |name|
|
|
28
|
-
# http://blog.jayfields.com/2006/12/ruby-alias-method-alternative.html
|
|
29
|
-
bind_method = instance_method(name)
|
|
30
|
-
|
|
31
|
-
define_method(name) do |*args, &block|
|
|
32
|
-
result = bind_method.bind(self).call(*args, &block)
|
|
33
|
-
set_expiration
|
|
34
|
-
result
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
25
|
+
def allow_expiration(&block)
|
|
26
|
+
block.call.tap { set_expiration }
|
|
38
27
|
end
|
|
39
28
|
end
|
|
40
29
|
end
|
data/lib/redis/counter.rb
CHANGED
|
@@ -25,8 +25,10 @@ class Redis
|
|
|
25
25
|
# with a parent and starting over (for example, restarting a game and
|
|
26
26
|
# disconnecting all players).
|
|
27
27
|
def reset(to=options[:start])
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
allow_expiration do
|
|
29
|
+
redis.set key, to.to_i
|
|
30
|
+
true # hack for redis-rb regression
|
|
31
|
+
end
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
# Reset the counter to its starting value, and return previous value.
|
|
@@ -47,10 +49,12 @@ class Redis
|
|
|
47
49
|
alias_method :get, :value
|
|
48
50
|
|
|
49
51
|
def value=(val)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
allow_expiration do
|
|
53
|
+
if val.nil?
|
|
54
|
+
delete
|
|
55
|
+
else
|
|
56
|
+
redis.set key, val
|
|
57
|
+
end
|
|
54
58
|
end
|
|
55
59
|
end
|
|
56
60
|
alias_method :set, :value=
|
|
@@ -66,8 +70,10 @@ class Redis
|
|
|
66
70
|
# counter will automatically be decremented to its previous value. This
|
|
67
71
|
# method is aliased as incr() for brevity.
|
|
68
72
|
def increment(by=1, &block)
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
allow_expiration do
|
|
74
|
+
val = redis.incrby(key, by).to_i
|
|
75
|
+
block_given? ? rewindable_block(:decrement, by, val, &block) : val
|
|
76
|
+
end
|
|
71
77
|
end
|
|
72
78
|
alias_method :incr, :increment
|
|
73
79
|
alias_method :incrby, :increment
|
|
@@ -78,8 +84,10 @@ class Redis
|
|
|
78
84
|
# counter will automatically be incremented to its previous value. This
|
|
79
85
|
# method is aliased as decr() for brevity.
|
|
80
86
|
def decrement(by=1, &block)
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
allow_expiration do
|
|
88
|
+
val = redis.decrby(key, by).to_i
|
|
89
|
+
block_given? ? rewindable_block(:increment, by, val, &block) : val
|
|
90
|
+
end
|
|
83
91
|
end
|
|
84
92
|
alias_method :decr, :decrement
|
|
85
93
|
alias_method :decrby, :decrement
|
|
@@ -87,15 +95,19 @@ class Redis
|
|
|
87
95
|
# Increment a floating point counter atomically.
|
|
88
96
|
# Redis uses separate API's to interact with integers vs floats.
|
|
89
97
|
def incrbyfloat(by=1.0, &block)
|
|
90
|
-
|
|
91
|
-
|
|
98
|
+
allow_expiration do
|
|
99
|
+
val = redis.incrbyfloat(key, by).to_f
|
|
100
|
+
block_given? ? rewindable_block(:decrbyfloat, by, val, &block) : val
|
|
101
|
+
end
|
|
92
102
|
end
|
|
93
103
|
|
|
94
104
|
# Decrement a floating point counter atomically.
|
|
95
105
|
# Redis uses separate API's to interact with integers vs floats.
|
|
96
106
|
def decrbyfloat(by=1.0, &block)
|
|
97
|
-
|
|
98
|
-
|
|
107
|
+
allow_expiration do
|
|
108
|
+
val = redis.incrbyfloat(key, -by).to_f
|
|
109
|
+
block_given? ? rewindable_block(:incrbyfloat, -by, val, &block) : val
|
|
110
|
+
end
|
|
99
111
|
end
|
|
100
112
|
|
|
101
113
|
##
|
|
@@ -113,10 +125,6 @@ class Redis
|
|
|
113
125
|
EndOverload
|
|
114
126
|
end
|
|
115
127
|
|
|
116
|
-
expiration_filter :increment, :incr, :incrby, :incrbyfloat,
|
|
117
|
-
:decrement, :decr, :decrby, :decrbyfloat,
|
|
118
|
-
:value=, :set, :reset
|
|
119
|
-
|
|
120
128
|
private
|
|
121
129
|
|
|
122
130
|
# Implements atomic increment/decrement blocks
|
data/lib/redis/hash_key.rb
CHANGED
|
@@ -18,7 +18,9 @@ class Redis
|
|
|
18
18
|
|
|
19
19
|
# Redis: HSET
|
|
20
20
|
def store(field, value)
|
|
21
|
-
|
|
21
|
+
allow_expiration do
|
|
22
|
+
redis.hset(key, field, marshal(value, options[:marshal_keys][field]))
|
|
23
|
+
end
|
|
22
24
|
end
|
|
23
25
|
alias_method :[]=, :store
|
|
24
26
|
|
|
@@ -37,8 +39,8 @@ class Redis
|
|
|
37
39
|
alias_method :key?, :has_key?
|
|
38
40
|
alias_method :member?, :has_key?
|
|
39
41
|
|
|
40
|
-
# Delete
|
|
41
|
-
def delete(field)
|
|
42
|
+
# Delete fields. Redis: HDEL
|
|
43
|
+
def delete(*field)
|
|
42
44
|
redis.hdel(key, field)
|
|
43
45
|
end
|
|
44
46
|
|
|
@@ -106,17 +108,21 @@ class Redis
|
|
|
106
108
|
# Set keys in bulk, takes a hash of field/values {'field1' => 'val1'}. Redis: HMSET
|
|
107
109
|
def bulk_set(*args)
|
|
108
110
|
raise ArgumentError, "Argument to bulk_set must be hash of key/value pairs" unless args.last.is_a?(::Hash)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
allow_expiration do
|
|
112
|
+
redis.hmset(key, *args.last.inject([]){ |arr,kv|
|
|
113
|
+
arr + [kv[0], marshal(kv[1], options[:marshal_keys][kv[0]])]
|
|
114
|
+
})
|
|
115
|
+
end
|
|
112
116
|
end
|
|
113
117
|
alias_method :update, :bulk_set
|
|
114
118
|
|
|
115
119
|
# Set keys in bulk if they do not exist. Takes a hash of field/values {'field1' => 'val1'}. Redis: HSETNX
|
|
116
120
|
def fill(pairs={})
|
|
117
121
|
raise ArgumentError, "Arugment to fill must be a hash of key/value pairs" unless pairs.is_a?(::Hash)
|
|
118
|
-
|
|
119
|
-
|
|
122
|
+
allow_expiration do
|
|
123
|
+
pairs.each do |field, value|
|
|
124
|
+
redis.hsetnx(key, field, marshal(value, options[:marshal_keys][field]))
|
|
125
|
+
end
|
|
120
126
|
end
|
|
121
127
|
end
|
|
122
128
|
|
|
@@ -139,11 +145,13 @@ class Redis
|
|
|
139
145
|
|
|
140
146
|
# Increment value by integer at field. Redis: HINCRBY
|
|
141
147
|
def incrby(field, by=1)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
ret.
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
allow_expiration do
|
|
149
|
+
ret = redis.hincrby(key, field, by)
|
|
150
|
+
unless ret.is_a? Array
|
|
151
|
+
ret.to_i
|
|
152
|
+
else
|
|
153
|
+
nil
|
|
154
|
+
end
|
|
147
155
|
end
|
|
148
156
|
end
|
|
149
157
|
alias_method :incr, :incrby
|
|
@@ -156,11 +164,13 @@ class Redis
|
|
|
156
164
|
|
|
157
165
|
# Increment value by float at field. Redis: HINCRBYFLOAT
|
|
158
166
|
def incrbyfloat(field, by=1.0)
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
ret.
|
|
162
|
-
|
|
163
|
-
|
|
167
|
+
allow_expiration do
|
|
168
|
+
ret = redis.hincrbyfloat(key, field, by)
|
|
169
|
+
unless ret.is_a? Array
|
|
170
|
+
ret.to_f
|
|
171
|
+
else
|
|
172
|
+
nil
|
|
173
|
+
end
|
|
164
174
|
end
|
|
165
175
|
end
|
|
166
176
|
|
|
@@ -168,10 +178,5 @@ class Redis
|
|
|
168
178
|
def decrbyfloat(field, by=1.0)
|
|
169
179
|
incrbyfloat(field, -by)
|
|
170
180
|
end
|
|
171
|
-
|
|
172
|
-
expiration_filter :[]=, :store, :bulk_set, :fill,
|
|
173
|
-
:incrby, :incr, :incrbyfloat,
|
|
174
|
-
:decrby, :decr, :decrbyfloat
|
|
175
181
|
end
|
|
176
182
|
end
|
|
177
|
-
|
data/lib/redis/list.rb
CHANGED
|
@@ -21,13 +21,17 @@ class Redis
|
|
|
21
21
|
|
|
22
22
|
# Add a member before or after pivot in the list. Redis: LINSERT
|
|
23
23
|
def insert(where,pivot,value)
|
|
24
|
-
|
|
24
|
+
allow_expiration do
|
|
25
|
+
redis.linsert(key,where,marshal(pivot),marshal(value))
|
|
26
|
+
end
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
# Add a member to the end of the list. Redis: RPUSH
|
|
28
30
|
def push(*values)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
allow_expiration do
|
|
32
|
+
redis.rpush(key, values.map{|v| marshal(v) })
|
|
33
|
+
redis.ltrim(key, -options[:maxlength], -1) if options[:maxlength]
|
|
34
|
+
end
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
# Remove a member from the end of the list. Redis: RPOP
|
|
@@ -49,8 +53,10 @@ class Redis
|
|
|
49
53
|
|
|
50
54
|
# Add a member to the start of the list. Redis: LPUSH
|
|
51
55
|
def unshift(*values)
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
allow_expiration do
|
|
57
|
+
redis.lpush(key, values.map{|v| marshal(v) })
|
|
58
|
+
redis.ltrim(key, 0, options[:maxlength] - 1) if options[:maxlength]
|
|
59
|
+
end
|
|
54
60
|
end
|
|
55
61
|
|
|
56
62
|
# Remove a member from the start of the list. Redis: LPOP
|
|
@@ -85,7 +91,9 @@ class Redis
|
|
|
85
91
|
|
|
86
92
|
# Same functionality as Ruby arrays.
|
|
87
93
|
def []=(index, value)
|
|
88
|
-
|
|
94
|
+
allow_expiration do
|
|
95
|
+
redis.lset(key, index, marshal(value))
|
|
96
|
+
end
|
|
89
97
|
end
|
|
90
98
|
|
|
91
99
|
# Delete the element(s) from the list that match name. If count is specified,
|
|
@@ -142,7 +150,5 @@ class Redis
|
|
|
142
150
|
def to_s
|
|
143
151
|
values.join(', ')
|
|
144
152
|
end
|
|
145
|
-
|
|
146
|
-
expiration_filter :[]=, :push, :<<, :insert, :unshift
|
|
147
153
|
end
|
|
148
154
|
end
|
data/lib/redis/lock.rb
CHANGED
|
@@ -30,14 +30,11 @@ class Redis
|
|
|
30
30
|
# (on any server) will spin waiting for the lock up to the :timeout
|
|
31
31
|
# that was specified when the lock was defined.
|
|
32
32
|
def lock(&block)
|
|
33
|
-
start = Time.now
|
|
34
|
-
gotit = false
|
|
35
33
|
expiration = nil
|
|
36
|
-
|
|
34
|
+
try_until_timeout do
|
|
37
35
|
expiration = generate_expiration
|
|
38
36
|
# Use the expiration as the value of the lock.
|
|
39
|
-
|
|
40
|
-
break if gotit
|
|
37
|
+
break if redis.setnx(key, expiration)
|
|
41
38
|
|
|
42
39
|
# Lock is being held. Now check to see if it's expired (if we're using
|
|
43
40
|
# lock expiration).
|
|
@@ -53,16 +50,10 @@ class Redis
|
|
|
53
50
|
# Since GETSET returns the old value of the lock, if the old expiration
|
|
54
51
|
# is still in the past, we know no one else has expired the locked
|
|
55
52
|
# and we now have it.
|
|
56
|
-
if old_expiration < Time.now.to_f
|
|
57
|
-
gotit = true
|
|
58
|
-
break
|
|
59
|
-
end
|
|
53
|
+
break if old_expiration < Time.now.to_f
|
|
60
54
|
end
|
|
61
55
|
end
|
|
62
|
-
|
|
63
|
-
sleep 0.1
|
|
64
56
|
end
|
|
65
|
-
raise LockTimeout, "Timeout on lock #{key} exceeded #{@options[:timeout]} sec" unless gotit
|
|
66
57
|
begin
|
|
67
58
|
yield
|
|
68
59
|
ensure
|
|
@@ -80,5 +71,20 @@ class Redis
|
|
|
80
71
|
def generate_expiration
|
|
81
72
|
@options[:expiration].nil? ? 1 : (Time.now + @options[:expiration].to_f + 1).to_f
|
|
82
73
|
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def try_until_timeout
|
|
78
|
+
if @options[:timeout] == 0
|
|
79
|
+
yield
|
|
80
|
+
else
|
|
81
|
+
start = Time.now
|
|
82
|
+
while Time.now - start < @options[:timeout]
|
|
83
|
+
yield
|
|
84
|
+
sleep 0.1
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
raise LockTimeout, "Timeout on lock #{key} exceeded #{@options[:timeout]} sec"
|
|
88
|
+
end
|
|
83
89
|
end
|
|
84
90
|
end
|
data/lib/redis/set.rb
CHANGED
|
@@ -21,7 +21,9 @@ class Redis
|
|
|
21
21
|
# Add the specified value to the set only if it does not exist already.
|
|
22
22
|
# Redis: SADD
|
|
23
23
|
def add(value)
|
|
24
|
-
|
|
24
|
+
allow_expiration do
|
|
25
|
+
redis.sadd(key, marshal(value)) if value.nil? || !Array(value).empty?
|
|
26
|
+
end
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
# Remove and return a random member. Redis: SPOP
|
|
@@ -180,14 +182,11 @@ class Redis
|
|
|
180
182
|
members.join(', ')
|
|
181
183
|
end
|
|
182
184
|
|
|
183
|
-
expiration_filter :add
|
|
184
|
-
|
|
185
185
|
private
|
|
186
186
|
|
|
187
187
|
def keys_from_objects(sets)
|
|
188
188
|
raise ArgumentError, "Must pass in one or more set names" if sets.empty?
|
|
189
189
|
sets.collect{|set| set.is_a?(Redis::Set) ? set.key : set}
|
|
190
190
|
end
|
|
191
|
-
|
|
192
191
|
end
|
|
193
192
|
end
|
data/lib/redis/sorted_set.rb
CHANGED
|
@@ -23,7 +23,9 @@ class Redis
|
|
|
23
23
|
# arguments to this are flipped; the member comes first rather than
|
|
24
24
|
# the score, since the member is the unique item (not the score).
|
|
25
25
|
def add(member, score)
|
|
26
|
-
|
|
26
|
+
allow_expiration do
|
|
27
|
+
redis.zadd(key, score, marshal(member))
|
|
28
|
+
end
|
|
27
29
|
end
|
|
28
30
|
|
|
29
31
|
# Add a list of members and their corresponding value (or a hash mapping
|
|
@@ -31,8 +33,10 @@ class Redis
|
|
|
31
33
|
# the member comes first rather than the score, since the member is the unique
|
|
32
34
|
# item (not the score).
|
|
33
35
|
def merge(values)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
allow_expiration do
|
|
37
|
+
vals = values.map{|v,s| [s, marshal(v)] }
|
|
38
|
+
redis.zadd(key, vals)
|
|
39
|
+
end
|
|
36
40
|
end
|
|
37
41
|
alias_method :add_all, :merge
|
|
38
42
|
|
|
@@ -155,7 +159,9 @@ class Redis
|
|
|
155
159
|
|
|
156
160
|
# Delete the value from the set. Redis: ZREM
|
|
157
161
|
def delete(value)
|
|
158
|
-
|
|
162
|
+
allow_expiration do
|
|
163
|
+
redis.zrem(key, marshal(value))
|
|
164
|
+
end
|
|
159
165
|
end
|
|
160
166
|
|
|
161
167
|
# Delete element if it matches block
|
|
@@ -173,14 +179,18 @@ class Redis
|
|
|
173
179
|
# Increment the rank of that member atomically and return the new value. This
|
|
174
180
|
# method is aliased as incr() for brevity. Redis: ZINCRBY
|
|
175
181
|
def increment(member, by=1)
|
|
176
|
-
|
|
182
|
+
allow_expiration do
|
|
183
|
+
zincrby(member, by)
|
|
184
|
+
end
|
|
177
185
|
end
|
|
178
186
|
alias_method :incr, :increment
|
|
179
187
|
alias_method :incrby, :increment
|
|
180
188
|
|
|
181
189
|
# Convenience to calling increment() with a negative number.
|
|
182
190
|
def decrement(member, by=1)
|
|
183
|
-
|
|
191
|
+
allow_expiration do
|
|
192
|
+
zincrby(member, -by)
|
|
193
|
+
end
|
|
184
194
|
end
|
|
185
195
|
alias_method :decr, :decrement
|
|
186
196
|
alias_method :decrby, :decrement
|
|
@@ -206,8 +216,10 @@ class Redis
|
|
|
206
216
|
# Calculate the intersection and store it in Redis as +name+. Returns the number
|
|
207
217
|
# of elements in the stored intersection. Redis: SUNIONSTORE
|
|
208
218
|
def interstore(name, *sets)
|
|
209
|
-
|
|
210
|
-
|
|
219
|
+
allow_expiration do
|
|
220
|
+
opts = sets.last.is_a?(Hash) ? sets.pop : {}
|
|
221
|
+
redis.zinterstore(key_from_object(name), keys_from_objects([self] + sets), opts)
|
|
222
|
+
end
|
|
211
223
|
end
|
|
212
224
|
|
|
213
225
|
# Return the union with another set. Can pass it either another set
|
|
@@ -230,8 +242,10 @@ class Redis
|
|
|
230
242
|
# Calculate the union and store it in Redis as +name+. Returns the number
|
|
231
243
|
# of elements in the stored union. Redis: SUNIONSTORE
|
|
232
244
|
def unionstore(name, *sets)
|
|
233
|
-
|
|
234
|
-
|
|
245
|
+
allow_expiration do
|
|
246
|
+
opts = sets.last.is_a?(Hash) ? sets.pop : {}
|
|
247
|
+
redis.zunionstore(key_from_object(name), keys_from_objects([self] + sets), opts)
|
|
248
|
+
end
|
|
235
249
|
end
|
|
236
250
|
|
|
237
251
|
# Return the difference vs another set. Can pass it either another set
|
|
@@ -304,10 +318,6 @@ class Redis
|
|
|
304
318
|
!redis.zscore(key, marshal(value)).nil?
|
|
305
319
|
end
|
|
306
320
|
|
|
307
|
-
expiration_filter :[]=, :add, :merge, :delete,
|
|
308
|
-
:increment, :incr, :incrby, :decrement, :decr, :decrby,
|
|
309
|
-
:intersection, :interstore, :unionstore, :diffstore
|
|
310
|
-
|
|
311
321
|
private
|
|
312
322
|
def key_from_object(set)
|
|
313
323
|
set.is_a?(Redis::SortedSet) ? set.key : set
|
|
@@ -317,5 +327,9 @@ class Redis
|
|
|
317
327
|
raise ArgumentError, "Must pass in one or more set names" if sets.empty?
|
|
318
328
|
sets.collect{|set| set.is_a?(Redis::SortedSet) || set.is_a?(Redis::Set) ? set.key : set}
|
|
319
329
|
end
|
|
330
|
+
|
|
331
|
+
def zincrby(member, by)
|
|
332
|
+
redis.zincrby(key, by, marshal(member)).to_i
|
|
333
|
+
end
|
|
320
334
|
end
|
|
321
335
|
end
|
data/lib/redis/value.rb
CHANGED
|
@@ -15,10 +15,12 @@ class Redis
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def value=(val)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
allow_expiration do
|
|
19
|
+
if val.nil?
|
|
20
|
+
delete
|
|
21
|
+
else
|
|
22
|
+
redis.set key, marshal(val)
|
|
23
|
+
end
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
alias_method :set, :value=
|
|
@@ -40,7 +42,5 @@ class Redis
|
|
|
40
42
|
def method_missing(*args)
|
|
41
43
|
self.value.send *args
|
|
42
44
|
end
|
|
43
|
-
|
|
44
|
-
expiration_filter :value=
|
|
45
45
|
end
|
|
46
46
|
end
|
|
@@ -16,7 +16,7 @@ begin
|
|
|
16
16
|
create_table :blogs do |t|
|
|
17
17
|
t.string :name
|
|
18
18
|
t.integer :posts_count, :default => 0
|
|
19
|
-
t.timestamps
|
|
19
|
+
t.timestamps null: true
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -37,7 +37,7 @@ begin
|
|
|
37
37
|
t.string :description, :length => 200
|
|
38
38
|
t.integer :total
|
|
39
39
|
t.integer :blog_id
|
|
40
|
-
t.timestamps
|
|
40
|
+
t.timestamps null: true
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -58,11 +58,11 @@ begin
|
|
|
58
58
|
create_table :comments do |t|
|
|
59
59
|
t.string :body
|
|
60
60
|
t.integer :post_id
|
|
61
|
-
t.timestamps
|
|
61
|
+
t.timestamps null: true
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
def self.down
|
|
66
66
|
drop_table :comments
|
|
67
67
|
end
|
|
68
68
|
end
|
|
@@ -18,7 +18,7 @@ describe Redis::Value do
|
|
|
18
18
|
@value = Redis::Value.new('spec/value', :default => false, :marshal => true)
|
|
19
19
|
@value.value.should == false
|
|
20
20
|
end
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
it "should handle simple values" do
|
|
23
23
|
@value.should == nil
|
|
24
24
|
@value.value = 'Trevor Hoffman'
|
|
@@ -109,17 +109,21 @@ describe Redis::Value do
|
|
|
109
109
|
@value.nil?.should == true
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
112
|
+
describe "with expiration" do
|
|
113
|
+
[:value=, :set].each do |meth|
|
|
114
|
+
it "#{meth} should set time to live in seconds when expiration option assigned" do
|
|
115
|
+
@value = Redis::Value.new('spec/value', :expiration => 10)
|
|
116
|
+
@value.send(meth, 'monkey')
|
|
117
|
+
@value.ttl.should > 0
|
|
118
|
+
@value.ttl.should <= 10
|
|
119
|
+
end
|
|
118
120
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
it "#{meth} should set expiration when expireat option assigned" do
|
|
122
|
+
@value = Redis::Value.new('spec/value', :expireat => Time.now + 10.seconds)
|
|
123
|
+
@value.send(meth, 'monkey')
|
|
124
|
+
@value.ttl.should > 0
|
|
125
|
+
end
|
|
126
|
+
end
|
|
123
127
|
end
|
|
124
128
|
|
|
125
129
|
after do
|
|
@@ -127,7 +131,6 @@ describe Redis::Value do
|
|
|
127
131
|
end
|
|
128
132
|
end
|
|
129
133
|
|
|
130
|
-
|
|
131
134
|
describe Redis::List do
|
|
132
135
|
describe "as a bounded list" do
|
|
133
136
|
before do
|
|
@@ -340,27 +343,59 @@ describe Redis::List do
|
|
|
340
343
|
end
|
|
341
344
|
|
|
342
345
|
describe 'with expiration' do
|
|
343
|
-
[:
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
it 'expireat: option' do
|
|
353
|
-
@list = Redis::List.new('spec/list_exp', :expireat => Time.now + 10.seconds)
|
|
354
|
-
@list << 'val'
|
|
355
|
-
@list.ttl.should > 0
|
|
356
|
-
@list.ttl.should <= 10
|
|
357
|
-
end
|
|
346
|
+
[:push, :<<, :unshift].each do |meth, args|
|
|
347
|
+
it "#{meth} expiration: option" do
|
|
348
|
+
@list = Redis::List.new('spec/list_exp', :expiration => 10)
|
|
349
|
+
@list.clear
|
|
350
|
+
@list.send(meth, 'val')
|
|
351
|
+
@list.ttl.should > 0
|
|
352
|
+
@list.ttl.should <= 10
|
|
358
353
|
end
|
|
359
354
|
|
|
360
|
-
|
|
355
|
+
it "#{meth} expireat: option" do
|
|
356
|
+
@list = Redis::List.new('spec/list_exp', :expireat => Time.now + 10.seconds)
|
|
361
357
|
@list.clear
|
|
358
|
+
@list.send(meth, 'val')
|
|
359
|
+
@list.ttl.should > 0
|
|
360
|
+
@list.ttl.should <= 10
|
|
362
361
|
end
|
|
363
362
|
end
|
|
363
|
+
|
|
364
|
+
it "[]= expiration: option" do
|
|
365
|
+
@list = Redis::List.new('spec/list_exp', :expiration => 10)
|
|
366
|
+
@list.clear
|
|
367
|
+
@list.redis.rpush(@list.key, 'hello')
|
|
368
|
+
@list[0] = 'world'
|
|
369
|
+
@list.ttl.should > 0
|
|
370
|
+
@list.ttl.should <= 10
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
it "[]= expireat: option" do
|
|
374
|
+
@list = Redis::List.new('spec/list_exp', :expireat => Time.now + 10.seconds)
|
|
375
|
+
@list.clear
|
|
376
|
+
@list.redis.rpush(@list.key, 'hello')
|
|
377
|
+
@list[0] = 'world'
|
|
378
|
+
@list.ttl.should > 0
|
|
379
|
+
@list.ttl.should <= 10
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
it "insert expiration: option" do
|
|
383
|
+
@list = Redis::List.new('spec/list_exp', :expiration => 10)
|
|
384
|
+
@list.clear
|
|
385
|
+
@list.redis.rpush(@list.key, 'hello')
|
|
386
|
+
@list.insert 'BEFORE', 'hello', 'world'
|
|
387
|
+
@list.ttl.should > 0
|
|
388
|
+
@list.ttl.should <= 10
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
it "insert expireat: option" do
|
|
392
|
+
@list = Redis::List.new('spec/list_exp', :expireat => Time.now + 10.seconds)
|
|
393
|
+
@list.clear
|
|
394
|
+
@list.redis.rpush(@list.key, 'hello')
|
|
395
|
+
@list.insert 'BEFORE', 'hello', 'world'
|
|
396
|
+
@list.ttl.should > 0
|
|
397
|
+
@list.ttl.should <= 10
|
|
398
|
+
end
|
|
364
399
|
end
|
|
365
400
|
|
|
366
401
|
end
|
|
@@ -440,7 +475,7 @@ describe Redis::Counter do
|
|
|
440
475
|
@counter.ttl.should <= 10
|
|
441
476
|
end
|
|
442
477
|
|
|
443
|
-
[:increment, :incr, :incrby, :incrbyfloat,
|
|
478
|
+
[:increment, :incr, :incrby, :incrbyfloat,
|
|
444
479
|
:decrement, :decr, :decrby, :decrbyfloat, :reset].each do |meth|
|
|
445
480
|
describe meth do
|
|
446
481
|
it "expiration: option" do
|
|
@@ -574,7 +609,6 @@ describe Redis::Lock do
|
|
|
574
609
|
end
|
|
575
610
|
end
|
|
576
611
|
|
|
577
|
-
|
|
578
612
|
describe Redis::HashKey do
|
|
579
613
|
describe "With Marshal" do
|
|
580
614
|
before do
|
|
@@ -794,28 +828,37 @@ describe Redis::HashKey do
|
|
|
794
828
|
block.should == "oops: missing_key"
|
|
795
829
|
end
|
|
796
830
|
|
|
797
|
-
#[:[]=, :store, :bulk_set, :fill,
|
|
798
831
|
describe 'with expiration' do
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
832
|
+
{
|
|
833
|
+
:incrby => 'somekey',
|
|
834
|
+
:incr => 'somekey',
|
|
835
|
+
:incrbyfloat => 'somekey',
|
|
836
|
+
:decrby => 'somekey',
|
|
837
|
+
:decr => 'somekey',
|
|
838
|
+
:decrbyfloat => 'somekey',
|
|
839
|
+
:store => ['somekey', 'somevalue'],
|
|
840
|
+
:[]= => ['somekey', 'somevalue'],
|
|
841
|
+
:bulk_set => [{ 'somekey' => 'somevalue' }],
|
|
842
|
+
:update => [{ 'somekey' => 'somevalue' }],
|
|
843
|
+
:fill => [{ 'somekey' => 'somevalue' }]
|
|
844
|
+
}.each do |meth, args|
|
|
845
|
+
it "#{meth} expiration: option" do
|
|
846
|
+
@hash = Redis::HashKey.new('spec/hash_expiration', :expiration => 10)
|
|
847
|
+
@hash.clear
|
|
848
|
+
@hash.send(meth, *args)
|
|
849
|
+
@hash.ttl.should > 0
|
|
850
|
+
@hash.ttl.should <= 10
|
|
816
851
|
end
|
|
817
|
-
|
|
818
|
-
|
|
852
|
+
|
|
853
|
+
it "#{meth} expireat: option" do
|
|
854
|
+
@hash = Redis::HashKey.new('spec/hash_expireat', :expireat => Time.now + 10.seconds)
|
|
855
|
+
@hash.clear
|
|
856
|
+
@hash.send(meth, *args)
|
|
857
|
+
@hash.ttl.should > 0
|
|
858
|
+
@hash.ttl.should <= 10
|
|
859
|
+
end
|
|
860
|
+
end
|
|
861
|
+
end
|
|
819
862
|
|
|
820
863
|
after do
|
|
821
864
|
@hash.clear
|
|
@@ -991,18 +1034,22 @@ describe Redis::Set do
|
|
|
991
1034
|
@set_1.redis.del SORT_STORE[:store]
|
|
992
1035
|
end
|
|
993
1036
|
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1037
|
+
describe "with expiration" do
|
|
1038
|
+
[:<<, :add].each do |meth|
|
|
1039
|
+
it "should set time to live in seconds when expiration option assigned" do
|
|
1040
|
+
@set = Redis::Set.new('spec/set', :expiration => 10)
|
|
1041
|
+
@set.send(meth, 'val')
|
|
1042
|
+
@set.ttl.should > 0
|
|
1043
|
+
@set.ttl.should <= 10
|
|
1044
|
+
end
|
|
1000
1045
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1046
|
+
it "should set expiration when expireat option assigned" do
|
|
1047
|
+
@set = Redis::Set.new('spec/set', :expireat => Time.now + 10.seconds)
|
|
1048
|
+
@set.send(meth, 'val')
|
|
1049
|
+
@set.ttl.should > 0
|
|
1050
|
+
@set.ttl.should <= 10
|
|
1051
|
+
end
|
|
1052
|
+
end
|
|
1006
1053
|
end
|
|
1007
1054
|
|
|
1008
1055
|
after do
|
|
@@ -1257,25 +1304,79 @@ describe Redis::SortedSet do
|
|
|
1257
1304
|
|
|
1258
1305
|
describe "with expiration" do
|
|
1259
1306
|
[:[]=, :add, :increment, :incr, :incrby, :decrement, :decr, :decrby].each do |meth|
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1307
|
+
it "#{meth} expiration: option" do
|
|
1308
|
+
@set = Redis::SortedSet.new('spec/zset_exp', :expiration => 10)
|
|
1309
|
+
@set.clear
|
|
1310
|
+
@set.send(meth, 'somekey', 12)
|
|
1311
|
+
@set.ttl.should > 0
|
|
1312
|
+
@set.ttl.should <= 10
|
|
1313
|
+
end
|
|
1314
|
+
it "#{meth} expireat: option" do
|
|
1315
|
+
@set = Redis::SortedSet.new('spec/zset_exp', :expireat => Time.now + 10.seconds)
|
|
1316
|
+
@set.clear
|
|
1317
|
+
@set.send(meth, 'somekey', 12)
|
|
1318
|
+
@set.ttl.should > 0
|
|
1319
|
+
@set.ttl.should <= 10
|
|
1320
|
+
end
|
|
1321
|
+
end
|
|
1322
|
+
|
|
1323
|
+
[:merge, :add_all].each do |meth|
|
|
1324
|
+
it "#{meth} expiration: option" do
|
|
1325
|
+
@set = Redis::SortedSet.new('spec/zset_exp', :expiration => 10)
|
|
1326
|
+
@set.clear
|
|
1327
|
+
@set.send(meth, 'somekey' => 12)
|
|
1328
|
+
@set.ttl.should > 0
|
|
1329
|
+
@set.ttl.should <= 10
|
|
1330
|
+
end
|
|
1331
|
+
it "#{meth} expireat: option" do
|
|
1332
|
+
@set = Redis::SortedSet.new('spec/zset_exp', :expireat => Time.now + 10.seconds)
|
|
1333
|
+
@set.clear
|
|
1334
|
+
@set.send(meth, 'somekey' => 12)
|
|
1335
|
+
@set.ttl.should > 0
|
|
1336
|
+
@set.ttl.should <= 10
|
|
1337
|
+
end
|
|
1338
|
+
end
|
|
1339
|
+
|
|
1340
|
+
[:unionstore, :interstore].each do |meth|
|
|
1341
|
+
it "#{meth} expiration: option" do
|
|
1342
|
+
@set = Redis::SortedSet.new('spec/zset_exp', :expiration => 10)
|
|
1343
|
+
@set.clear
|
|
1344
|
+
@set.redis.zadd(@set.key, 1, "1")
|
|
1345
|
+
@set.send(meth, 'sets', Redis::SortedSet.new('other'))
|
|
1346
|
+
@set.ttl.should > 0
|
|
1347
|
+
@set.ttl.should <= 10
|
|
1348
|
+
end
|
|
1349
|
+
|
|
1350
|
+
it "#{meth} expireat: option" do
|
|
1351
|
+
@set = Redis::SortedSet.new('spec/zset_exp', :expireat => Time.now + 10.seconds)
|
|
1352
|
+
@set.clear
|
|
1353
|
+
@set.redis.zadd(@set.key, 1, "1")
|
|
1354
|
+
@set.send(meth, 'sets', Redis::SortedSet.new('other'))
|
|
1355
|
+
@set.ttl.should > 0
|
|
1356
|
+
@set.ttl.should <= 10
|
|
1276
1357
|
end
|
|
1277
1358
|
end
|
|
1278
|
-
|
|
1359
|
+
|
|
1360
|
+
it "delete expiration: option" do
|
|
1361
|
+
@set = Redis::SortedSet.new('spec/zset_exp', :expiration => 10)
|
|
1362
|
+
@set.clear
|
|
1363
|
+
@set.redis.zadd(@set.key, 1, "1")
|
|
1364
|
+
@set.redis.zadd(@set.key, 2, "2")
|
|
1365
|
+
@set.delete("2")
|
|
1366
|
+
@set.ttl.should > 0
|
|
1367
|
+
@set.ttl.should <= 10
|
|
1368
|
+
end
|
|
1369
|
+
|
|
1370
|
+
it "delete expireat: option" do
|
|
1371
|
+
@set = Redis::SortedSet.new('spec/zset_exp', :expireat => Time.now + 10.seconds)
|
|
1372
|
+
@set.clear
|
|
1373
|
+
@set.redis.zadd(@set.key, 1, "1")
|
|
1374
|
+
@set.redis.zadd(@set.key, 2, "2")
|
|
1375
|
+
@set.delete("2")
|
|
1376
|
+
@set.ttl.should > 0
|
|
1377
|
+
@set.ttl.should <= 10
|
|
1378
|
+
end
|
|
1379
|
+
end
|
|
1279
1380
|
|
|
1280
1381
|
after do
|
|
1281
1382
|
@set.clear
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: redis-objects
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nate Wiger
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-01
|
|
11
|
+
date: 2015-05-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: redis
|