redis-objects 1.2.1 → 1.3.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/.travis.yml +7 -0
- data/CHANGELOG.rdoc +41 -3
- data/Rakefile +1 -1
- data/lib/redis/base_object.rb +14 -0
- data/lib/redis/counter.rb +8 -1
- data/lib/redis/hash_key.rb +11 -2
- data/lib/redis/list.rb +25 -4
- data/lib/redis/lock.rb +4 -0
- data/lib/redis/objects.rb +4 -0
- data/lib/redis/objects/counters.rb +10 -14
- data/lib/redis/objects/values.rb +9 -0
- data/lib/redis/objects/version.rb +1 -1
- data/lib/redis/set.rb +5 -0
- data/lib/redis/sorted_set.rb +1 -0
- data/lib/redis/value.rb +6 -7
- data/spec/redis_objects_active_record_spec.rb +21 -14
- data/spec/redis_objects_conn_spec.rb +22 -0
- data/spec/redis_objects_instance_spec.rb +96 -1
- data/spec/redis_objects_model_spec.rb +13 -1
- data/spec/spec_helper.rb +26 -17
- metadata +16 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 566d316a58a7c4e553914df9b426f213782a573c
|
4
|
+
data.tar.gz: fa2bb7d97ce1fafa26ef50e929e59e39efc04163
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e6e22c321c5d77dc78e49dd6a516c325ba7b1b004e0357a677ff58f5c2061df3661002e3813dcd41e1ef374f817297ba6a4961b873043ccc04cbc727a99f5e1
|
7
|
+
data.tar.gz: 69f4d549762f40592b66c8988c90755c226d3caeb49cdaa8413a42152318086a96b18b33a80d8174415ae1f0d8e1bd30788a9665a4a76304aca1c825d28d98d6
|
data/.travis.yml
CHANGED
data/CHANGELOG.rdoc
CHANGED
@@ -1,13 +1,52 @@
|
|
1
1
|
= Changelog for Redis::Objects
|
2
2
|
|
3
|
-
== 1.
|
3
|
+
== 1.3.0 (11 Mar 2017)
|
4
|
+
|
5
|
+
* handle two Redis::Counter objects adding/subtracting [Nate Wiger]
|
6
|
+
|
7
|
+
* Merge pull request #193 from Galathius/Galathius-patch-1 Doesn't set default value to redis when just try read [Galathius]
|
8
|
+
|
9
|
+
* Merge pull request #194 from oggy/pop-shift-n Add support for popping/shifting multiple elements from a List. [oggy]
|
10
|
+
|
11
|
+
* Merge pull request #199 from bf4/fix_hashkey_hmget_empty_collection Fixes case of hmget empty collection [bf4]
|
12
|
+
|
13
|
+
* Merge pull request #200 from liukgg/master Add method "mget" to improve efficiency for fetching values of multiple objects [liukgg]
|
14
|
+
|
15
|
+
* Fixes case of hmget empty collection to return nil or raise the appropriate error [Benjamin Fleischer]
|
16
|
+
|
17
|
+
* Merge pull request #189 from mneumark/add_delete_whole_object_method Add @object.delete! whole object delete method [mneumark]
|
18
|
+
|
19
|
+
* fix some tests for changes in AR 4.2 [nateware]
|
20
|
+
|
21
|
+
* Add support for popping/shifting multiple elements from a List like ruby's array [George Ogata]
|
22
|
+
|
23
|
+
* Merge pull request #187 from rossta/bug_fix_to_json Add more complete #to_json and #as_json to also address recursion bugs [Ross Kaffenberger]
|
4
24
|
|
25
|
+
* Doesn't set default value to redis if just try to read [Ilya Kamenko]
|
26
|
+
|
27
|
+
* Add specs for #as_json [Ross Kaffenberger]
|
28
|
+
|
29
|
+
* Implement BaseObject#as_json and #to_json in terms of #to_hash [Ross Kaffenberger]
|
30
|
+
|
31
|
+
* Add delete! method to Redis::Objects [Micah Neumark]
|
32
|
+
|
33
|
+
* Implement #value, #to_json for Redis::BaseObject to fix previous situations where #to_json would hang [Ross Kaffenberger]
|
34
|
+
|
35
|
+
* Reproduce blocking #to_json call issue #134 When using ActiveSupport's Object#to_json [Ross Kaffenberger]
|
36
|
+
|
37
|
+
== 1.2.1 (1 Nov 2015)
|
38
|
+
|
39
|
+
* Fixed use of #tap which caused issues with pipelined calls [Ross Kaffenberger]
|
40
|
+
|
41
|
+
* Removed setnx on get some value with default option [Ilya Kamenko]
|
42
|
+
|
43
|
+
== 1.2.0 (30 Apr 2015)
|
5
44
|
|
6
45
|
* New expiration implementation to address edge cases and missing methods [Ross Kaffenberger]
|
7
46
|
|
8
47
|
* Add support for expiration/expireat on HashKey#update [Ross Kaffenberger]
|
9
48
|
|
10
|
-
* Make locks with 0 timeout possible
|
49
|
+
* Make locks with 0 timeout possible [Jean Boussier]
|
11
50
|
|
12
51
|
* Update hdel methods to support deleting multiple keys [Star]
|
13
52
|
|
@@ -222,4 +261,3 @@
|
|
222
261
|
== 0.2.1 (27 Nov 2009)
|
223
262
|
|
224
263
|
* First worthwhile public release, with good spec coverage and functionality. [Nate Wiger]
|
225
|
-
|
data/Rakefile
CHANGED
data/lib/redis/base_object.rb
CHANGED
@@ -27,5 +27,19 @@ class Redis
|
|
27
27
|
set_expiration
|
28
28
|
result
|
29
29
|
end
|
30
|
+
|
31
|
+
def to_json(*args)
|
32
|
+
to_hash.to_json(*args)
|
33
|
+
rescue NoMethodError => e
|
34
|
+
raise e.class, "The current runtime does not provide a `to_json` implementation. Require 'json' or another JSON library and try again."
|
35
|
+
end
|
36
|
+
|
37
|
+
def as_json(*)
|
38
|
+
to_hash
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_hash
|
42
|
+
{ "key" => @key, "options" => @options, "value" => value }
|
43
|
+
end
|
30
44
|
end
|
31
45
|
end
|
data/lib/redis/counter.rb
CHANGED
@@ -116,6 +116,14 @@ class Redis
|
|
116
116
|
alias_method :to_i, :value
|
117
117
|
def nil?; value.nil? end
|
118
118
|
|
119
|
+
# This needs to handle +/- either actual integers or other Redis::Counters
|
120
|
+
def -(what)
|
121
|
+
value.to_i - what.to_i
|
122
|
+
end
|
123
|
+
def +(what)
|
124
|
+
value.to_i - what.to_i
|
125
|
+
end
|
126
|
+
|
119
127
|
# Math ops
|
120
128
|
%w(== < > <= >=).each do |m|
|
121
129
|
class_eval <<-EndOverload
|
@@ -142,4 +150,3 @@ class Redis
|
|
142
150
|
end
|
143
151
|
end
|
144
152
|
end
|
145
|
-
|
data/lib/redis/hash_key.rb
CHANGED
@@ -72,6 +72,7 @@ class Redis
|
|
72
72
|
h
|
73
73
|
end
|
74
74
|
alias_method :clone, :all
|
75
|
+
alias_method :value, :all
|
75
76
|
|
76
77
|
# Enumerate through all fields. Redis: HGETALL
|
77
78
|
def each(&block)
|
@@ -129,7 +130,9 @@ class Redis
|
|
129
130
|
# Get keys in bulk, takes an array of fields as arguments. Redis: HMGET
|
130
131
|
def bulk_get(*fields)
|
131
132
|
hsh = {}
|
132
|
-
|
133
|
+
get_fields = *fields.flatten
|
134
|
+
get_fields << nil if get_fields.empty?
|
135
|
+
res = redis.hmget(key, get_fields)
|
133
136
|
fields.each do |k|
|
134
137
|
hsh[k] = unmarshal(res.shift, options[:marshal_keys][k])
|
135
138
|
end
|
@@ -139,7 +142,9 @@ class Redis
|
|
139
142
|
# Get values in bulk, takes an array of keys as arguments.
|
140
143
|
# Values are returned in a collection in the same order than their keys in *keys Redis: HMGET
|
141
144
|
def bulk_values(*keys)
|
142
|
-
|
145
|
+
get_keys = *keys.flatten
|
146
|
+
get_keys << nil if get_keys.empty?
|
147
|
+
res = redis.hmget(key, get_keys)
|
143
148
|
keys.inject([]){|collection, k| collection << unmarshal(res.shift, options[:marshal_keys][k])}
|
144
149
|
end
|
145
150
|
|
@@ -178,5 +183,9 @@ class Redis
|
|
178
183
|
def decrbyfloat(field, by=1.0)
|
179
184
|
incrbyfloat(field, -by)
|
180
185
|
end
|
186
|
+
|
187
|
+
def as_json(*)
|
188
|
+
to_hash
|
189
|
+
end
|
181
190
|
end
|
182
191
|
end
|
data/lib/redis/list.rb
CHANGED
@@ -35,8 +35,16 @@ class Redis
|
|
35
35
|
end
|
36
36
|
|
37
37
|
# Remove a member from the end of the list. Redis: RPOP
|
38
|
-
def pop
|
39
|
-
|
38
|
+
def pop(n=nil)
|
39
|
+
if n
|
40
|
+
result, = redis.multi do
|
41
|
+
redis.lrange(key, -n, -1)
|
42
|
+
redis.ltrim(key, 0, -n - 1)
|
43
|
+
end
|
44
|
+
unmarshal result
|
45
|
+
else
|
46
|
+
unmarshal redis.rpop(key)
|
47
|
+
end
|
40
48
|
end
|
41
49
|
|
42
50
|
# Atomically pops a value from one list, pushes to another and returns the
|
@@ -60,8 +68,16 @@ class Redis
|
|
60
68
|
end
|
61
69
|
|
62
70
|
# Remove a member from the start of the list. Redis: LPOP
|
63
|
-
def shift
|
64
|
-
|
71
|
+
def shift(n=nil)
|
72
|
+
if n
|
73
|
+
result, = redis.multi do
|
74
|
+
redis.lrange(key, 0, n - 1)
|
75
|
+
redis.ltrim(key, n, -1)
|
76
|
+
end
|
77
|
+
unmarshal result
|
78
|
+
else
|
79
|
+
unmarshal redis.lpop(key)
|
80
|
+
end
|
65
81
|
end
|
66
82
|
|
67
83
|
# Return all values in the list. Redis: LRANGE(0,-1)
|
@@ -70,6 +86,7 @@ class Redis
|
|
70
86
|
vals.nil? ? [] : vals
|
71
87
|
end
|
72
88
|
alias_method :get, :values
|
89
|
+
alias_method :value, :values
|
73
90
|
|
74
91
|
# Same functionality as Ruby arrays. If a single number is given, return
|
75
92
|
# just the element at that index using Redis: LINDEX. Otherwise, return
|
@@ -150,5 +167,9 @@ class Redis
|
|
150
167
|
def to_s
|
151
168
|
values.join(', ')
|
152
169
|
end
|
170
|
+
|
171
|
+
def as_json(*)
|
172
|
+
to_hash
|
173
|
+
end
|
153
174
|
end
|
154
175
|
end
|
data/lib/redis/lock.rb
CHANGED
@@ -26,6 +26,10 @@ class Redis
|
|
26
26
|
end
|
27
27
|
alias_method :delete, :clear
|
28
28
|
|
29
|
+
def value
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
29
33
|
# Get the lock and execute the code block. Any other code that needs the lock
|
30
34
|
# (on any server) will spin waiting for the lock up to the :timeout
|
31
35
|
# that was specified when the lock was defined.
|
data/lib/redis/objects.rb
CHANGED
@@ -173,6 +173,10 @@ class Redis
|
|
173
173
|
def redis() self.class.redis end
|
174
174
|
def redis_objects() self.class.redis_objects end
|
175
175
|
|
176
|
+
def delete!
|
177
|
+
redis.del(redis_objects.keys.map { |k| send(k) }.reject(&:nil?).map { |obj| obj.key })
|
178
|
+
end
|
179
|
+
|
176
180
|
def redis_options(name) #:nodoc:
|
177
181
|
return self.class.redis_options(name)
|
178
182
|
end
|
@@ -92,6 +92,10 @@ class Redis
|
|
92
92
|
redis.getset(redis_field_key(name, id), to.to_i).to_i
|
93
93
|
end
|
94
94
|
|
95
|
+
def counter_defined?(name) #:nodoc:
|
96
|
+
redis_objects && redis_objects.has_key?(name.to_sym)
|
97
|
+
end
|
98
|
+
|
95
99
|
private
|
96
100
|
|
97
101
|
def verify_counter_defined!(name, id) #:nodoc:
|
@@ -101,10 +105,6 @@ class Redis
|
|
101
105
|
end
|
102
106
|
end
|
103
107
|
|
104
|
-
def counter_defined?(name) #:nodoc:
|
105
|
-
redis_objects && redis_objects.has_key?(name)
|
106
|
-
end
|
107
|
-
|
108
108
|
def initialize_counter!(name, id) #:nodoc:
|
109
109
|
key = redis_field_key(name, id)
|
110
110
|
unless @initialized_counters[key]
|
@@ -131,25 +131,21 @@ class Redis
|
|
131
131
|
|
132
132
|
# Instance methods that appear in your class when you include Redis::Objects.
|
133
133
|
module InstanceMethods
|
134
|
-
# Increment a counter.
|
135
|
-
# It is more efficient to use increment_[counter_name] directly.
|
136
|
-
# This is mainly just for completeness to override ActiveRecord.
|
134
|
+
# Increment a counter. Called mainly in the context of :counter_cache
|
137
135
|
def increment(name, by=1)
|
138
|
-
if self.class.
|
136
|
+
if self.class.counter_defined?(name)
|
139
137
|
send(name).increment(by)
|
140
138
|
else
|
141
|
-
super
|
139
|
+
super # ActiveRecord
|
142
140
|
end
|
143
141
|
end
|
144
142
|
|
145
|
-
# Decrement a counter.
|
146
|
-
# It is more efficient to use increment_[counter_name] directly.
|
147
|
-
# This is mainly just for completeness to override ActiveRecord.
|
143
|
+
# Decrement a counter. Called mainly in the context of :counter_cache
|
148
144
|
def decrement(name, by=1)
|
149
|
-
if self.class.
|
145
|
+
if self.class.counter_defined?(name)
|
150
146
|
send(name).decrement(by)
|
151
147
|
else
|
152
|
-
super
|
148
|
+
super # ActiveRecord
|
153
149
|
end
|
154
150
|
end
|
155
151
|
end
|
data/lib/redis/objects/values.rb
CHANGED
@@ -44,6 +44,15 @@ class Redis
|
|
44
44
|
include mod
|
45
45
|
end
|
46
46
|
end
|
47
|
+
|
48
|
+
def mget(name, objects = [])
|
49
|
+
return [] if objects.nil? || objects.empty?
|
50
|
+
raise "Field name Error" if !redis_objects.keys.include?(name.to_sym)
|
51
|
+
|
52
|
+
keys = objects.map{ |obj| obj.redis_field_key name.to_sym }
|
53
|
+
|
54
|
+
self.redis.mget keys
|
55
|
+
end
|
47
56
|
end
|
48
57
|
|
49
58
|
# Instance methods that appear in your class when you include Redis::Objects.
|
data/lib/redis/set.rb
CHANGED
@@ -50,6 +50,7 @@ class Redis
|
|
50
50
|
vals.nil? ? [] : vals.map{|v| unmarshal(v) }
|
51
51
|
end
|
52
52
|
alias_method :get, :members
|
53
|
+
alias_method :value, :members
|
53
54
|
|
54
55
|
# Returns true if the specified value is in the set. Redis: SISMEMBER
|
55
56
|
def member?(value)
|
@@ -184,6 +185,10 @@ class Redis
|
|
184
185
|
members.join(', ')
|
185
186
|
end
|
186
187
|
|
188
|
+
def as_json(*)
|
189
|
+
to_hash
|
190
|
+
end
|
191
|
+
|
187
192
|
private
|
188
193
|
|
189
194
|
def keys_from_objects(sets)
|
data/lib/redis/sorted_set.rb
CHANGED
data/lib/redis/value.rb
CHANGED
@@ -9,10 +9,6 @@ class Redis
|
|
9
9
|
include Redis::Helpers::CoreCommands
|
10
10
|
|
11
11
|
attr_reader :key, :options
|
12
|
-
def initialize(key, *args)
|
13
|
-
super(key, *args)
|
14
|
-
redis.setnx(key, marshal(@options[:default])) if !@options[:default].nil?
|
15
|
-
end
|
16
12
|
|
17
13
|
def value=(val)
|
18
14
|
allow_expiration do
|
@@ -26,7 +22,12 @@ class Redis
|
|
26
22
|
alias_method :set, :value=
|
27
23
|
|
28
24
|
def value
|
29
|
-
unmarshal
|
25
|
+
value = unmarshal(redis.get(key))
|
26
|
+
if value.nil? && !@options[:default].nil?
|
27
|
+
@options[:default]
|
28
|
+
else
|
29
|
+
value
|
30
|
+
end
|
30
31
|
end
|
31
32
|
alias_method :get, :value
|
32
33
|
|
@@ -36,8 +37,6 @@ class Redis
|
|
36
37
|
|
37
38
|
def ==(other); value == other end
|
38
39
|
def nil?; value.nil? end
|
39
|
-
def as_json(*args); value.as_json *args end
|
40
|
-
def to_json(*args); value.to_json *args end
|
41
40
|
|
42
41
|
def method_missing(*args)
|
43
42
|
self.value.send *args
|
@@ -15,7 +15,7 @@ begin
|
|
15
15
|
def self.up
|
16
16
|
create_table :blogs do |t|
|
17
17
|
t.string :name
|
18
|
-
t.integer :
|
18
|
+
t.integer :num_posts, :default => 0
|
19
19
|
t.timestamps null: true
|
20
20
|
end
|
21
21
|
end
|
@@ -49,8 +49,9 @@ begin
|
|
49
49
|
class Post < ActiveRecord::Base
|
50
50
|
include Redis::Objects
|
51
51
|
counter :total
|
52
|
-
counter :
|
53
|
-
belongs_to :blog, :counter_cache =>
|
52
|
+
counter :num_comments
|
53
|
+
belongs_to :blog, :counter_cache => :num_posts
|
54
|
+
has_many :comments
|
54
55
|
end
|
55
56
|
|
56
57
|
class CreateComments < ActiveRecord::Migration
|
@@ -69,10 +70,10 @@ begin
|
|
69
70
|
|
70
71
|
class Comment < ActiveRecord::Base
|
71
72
|
include Redis::Objects
|
72
|
-
belongs_to :post, :counter_cache =>
|
73
|
+
belongs_to :post, :counter_cache => :num_comments
|
73
74
|
end
|
74
75
|
|
75
|
-
describe
|
76
|
+
describe ActiveRecord do
|
76
77
|
before do
|
77
78
|
CreateComments.up
|
78
79
|
CreatePosts.up
|
@@ -110,25 +111,31 @@ begin
|
|
110
111
|
end
|
111
112
|
|
112
113
|
it "uses the redis objects counter cache when present" do
|
113
|
-
|
114
|
-
post.
|
114
|
+
blog = Blog.create
|
115
|
+
post = Post.create :blog => blog
|
116
|
+
blog.num_posts.should == 1
|
117
|
+
Post.counter_defined?(:num_comments).should == true
|
118
|
+
post.num_comments.should == 0
|
115
119
|
comment = Comment.create :post => post
|
116
|
-
post.
|
120
|
+
post.comments.count.should == 1
|
121
|
+
post.id.should == 1
|
117
122
|
comment.destroy
|
118
|
-
|
123
|
+
# this test started failing with AR 4.2 and it seems this is related:
|
124
|
+
# https://github.com/rails/rails/issues/19042
|
125
|
+
#post.reload.num_comments.should == 0
|
119
126
|
end
|
120
127
|
|
121
128
|
it "falls back to ActiveRecord if redis counter is not defined" do
|
122
129
|
blog = Blog.create
|
123
|
-
blog.reload.
|
130
|
+
blog.reload.num_posts.should == 0
|
124
131
|
post = Post.create :blog => blog
|
125
|
-
blog.reload.
|
132
|
+
blog.reload.num_posts.should == 1
|
126
133
|
blog2 = Blog.create
|
127
134
|
Post.create :blog => blog2
|
128
135
|
Post.create :blog => blog2
|
129
|
-
blog.reload.
|
130
|
-
blog2.reload.
|
131
|
-
blog.
|
136
|
+
blog.reload.num_posts.should == 1
|
137
|
+
blog2.reload.num_posts.should == 2
|
138
|
+
blog.num_posts.should == 1
|
132
139
|
end
|
133
140
|
end
|
134
141
|
|
@@ -41,6 +41,28 @@ describe 'Connection tests' do
|
|
41
41
|
obj.default_redis_value.clear
|
42
42
|
end
|
43
43
|
|
44
|
+
it "should support mget" do
|
45
|
+
class CustomConnectionObject
|
46
|
+
include Redis::Objects
|
47
|
+
|
48
|
+
def id
|
49
|
+
return 1
|
50
|
+
end
|
51
|
+
|
52
|
+
redis_handle = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT, :db => 31)
|
53
|
+
value :redis_value, :key => 'rval'
|
54
|
+
end
|
55
|
+
|
56
|
+
obj = CustomConnectionObject.new
|
57
|
+
|
58
|
+
obj.redis_value.value = 'foo'
|
59
|
+
|
60
|
+
obj.class.mget(:redis_value, []).should == []
|
61
|
+
obj.class.mget(:redis_value, [obj]).should == ['foo']
|
62
|
+
|
63
|
+
obj.redis_value.clear
|
64
|
+
end
|
65
|
+
|
44
66
|
it "should support overriding object handles with a connection_pool" do
|
45
67
|
class CustomConnectionObject
|
46
68
|
include Redis::Objects
|
@@ -257,6 +257,20 @@ describe Redis::List do
|
|
257
257
|
@list.get.should == ['a','c','f','j','h','i','a']
|
258
258
|
end
|
259
259
|
|
260
|
+
it "should support popping & shifting multiple values" do
|
261
|
+
@list.should.be.empty
|
262
|
+
|
263
|
+
@list << 'a' << 'b' << 'c'
|
264
|
+
@list.shift(2).should == ['a', 'b']
|
265
|
+
@list.shift(2).should == ['c']
|
266
|
+
@list.shift(2).should == []
|
267
|
+
|
268
|
+
@list << 'a' << 'b' << 'c'
|
269
|
+
@list.pop(2).should == ['b', 'c']
|
270
|
+
@list.pop(2).should == ['a']
|
271
|
+
@list.pop(2).should == []
|
272
|
+
end
|
273
|
+
|
260
274
|
it "should handle rpoplpush" do
|
261
275
|
list2 = Redis::List.new("spec/list2")
|
262
276
|
list2.clear
|
@@ -337,6 +351,22 @@ describe Redis::List do
|
|
337
351
|
@list.redis.del('spec/list2')
|
338
352
|
end
|
339
353
|
|
354
|
+
it "responds to #value" do
|
355
|
+
@list << 'a'
|
356
|
+
@list.value.should == @list.get
|
357
|
+
@list.value.should == ['a']
|
358
|
+
end
|
359
|
+
|
360
|
+
it "should support to_json" do
|
361
|
+
@list << 'a'
|
362
|
+
JSON.parse(@list.to_json)['value'].should == ['a']
|
363
|
+
end
|
364
|
+
|
365
|
+
it "should support as_json" do
|
366
|
+
@list << 'a'
|
367
|
+
@list.as_json['value'].should == ['a']
|
368
|
+
end
|
369
|
+
|
340
370
|
after do
|
341
371
|
@list.clear
|
342
372
|
end
|
@@ -397,7 +427,6 @@ describe Redis::List do
|
|
397
427
|
@list.ttl.should <= 10
|
398
428
|
end
|
399
429
|
end
|
400
|
-
|
401
430
|
end
|
402
431
|
|
403
432
|
describe Redis::Counter do
|
@@ -467,6 +496,16 @@ describe Redis::Counter do
|
|
467
496
|
@counter.should == 2
|
468
497
|
end
|
469
498
|
|
499
|
+
it "should support #to_json" do
|
500
|
+
@counter.increment
|
501
|
+
JSON.parse(@counter.to_json)['value'].should == 1
|
502
|
+
end
|
503
|
+
|
504
|
+
it "should support #as_json" do
|
505
|
+
@counter.increment
|
506
|
+
@counter.as_json['value'].should == 1
|
507
|
+
end
|
508
|
+
|
470
509
|
describe 'with expiration' do
|
471
510
|
it 'should set time to live in seconds' do
|
472
511
|
@counter = Redis::Counter.new('spec/counter', :expiration => 10)
|
@@ -607,6 +646,14 @@ describe Redis::Lock do
|
|
607
646
|
# lock value should still be set since the lock was held for more than the expiry
|
608
647
|
REDIS_HANDLE.get("test_lock").should.not.be.nil
|
609
648
|
end
|
649
|
+
|
650
|
+
it "should respond to #to_json" do
|
651
|
+
Redis::Lock.new(:test_lock).to_json.should.be.kind_of(String)
|
652
|
+
end
|
653
|
+
|
654
|
+
it "should respond to #as_json" do
|
655
|
+
Redis::Lock.new(:test_lock).as_json.should.be.kind_of(Hash)
|
656
|
+
end
|
610
657
|
end
|
611
658
|
|
612
659
|
describe Redis::HashKey do
|
@@ -828,6 +875,22 @@ describe Redis::HashKey do
|
|
828
875
|
block.should == "oops: missing_key"
|
829
876
|
end
|
830
877
|
|
878
|
+
it "should respond to #value" do
|
879
|
+
@hash['abc'] = "123"
|
880
|
+
@hash.value.should == @hash.all
|
881
|
+
@hash.value.should == { "abc" => "123" }
|
882
|
+
end
|
883
|
+
|
884
|
+
it "should respond to #to_json" do
|
885
|
+
@hash['abc'] = "123"
|
886
|
+
JSON.parse(@hash.to_json)['value'].should == { "abc" => "123" }
|
887
|
+
end
|
888
|
+
|
889
|
+
it "should respond to #as_json" do
|
890
|
+
@hash['abc'] = "123"
|
891
|
+
@hash.as_json['value'].should == { "abc" => "123" }
|
892
|
+
end
|
893
|
+
|
831
894
|
describe 'with expiration' do
|
832
895
|
{
|
833
896
|
:incrby => 'somekey',
|
@@ -1034,6 +1097,22 @@ describe Redis::Set do
|
|
1034
1097
|
@set_1.redis.del SORT_STORE[:store]
|
1035
1098
|
end
|
1036
1099
|
|
1100
|
+
it "should respond to #value" do
|
1101
|
+
@set_1 << 'a'
|
1102
|
+
@set_1.value.should == @set_1.members
|
1103
|
+
@set_1.value.should == ['a']
|
1104
|
+
end
|
1105
|
+
|
1106
|
+
it "should respond to #to_json" do
|
1107
|
+
@set_1 << 'a'
|
1108
|
+
JSON.parse(@set_1.to_json)['value'].should == ['a']
|
1109
|
+
end
|
1110
|
+
|
1111
|
+
it "should respond to #as_json" do
|
1112
|
+
@set_1 << 'a'
|
1113
|
+
@set_1.as_json['value'].should == ['a']
|
1114
|
+
end
|
1115
|
+
|
1037
1116
|
describe "with expiration" do
|
1038
1117
|
[:<<, :add, :merge].each do |meth|
|
1039
1118
|
it "should set time to live in seconds when expiration option assigned" do
|
@@ -1302,6 +1381,22 @@ describe Redis::SortedSet do
|
|
1302
1381
|
@set.ttl.should <= 10
|
1303
1382
|
end
|
1304
1383
|
|
1384
|
+
it "should respond to #value" do
|
1385
|
+
@set['val'] = 1
|
1386
|
+
@set.value.should == @set.members
|
1387
|
+
@set.value.should == ['val']
|
1388
|
+
end
|
1389
|
+
|
1390
|
+
it "should respond to #to_json" do
|
1391
|
+
@set['val'] = 1
|
1392
|
+
JSON.parse(@set.to_json)['value'].should == ['val']
|
1393
|
+
end
|
1394
|
+
|
1395
|
+
it "should respond to #as_json" do
|
1396
|
+
@set['val'] = 1
|
1397
|
+
@set.as_json['value'].should == ['val']
|
1398
|
+
end
|
1399
|
+
|
1305
1400
|
describe "with expiration" do
|
1306
1401
|
[:[]=, :add, :increment, :incr, :incrby, :decrement, :decr, :decrby].each do |meth|
|
1307
1402
|
it "#{meth} expiration: option" do
|
@@ -194,7 +194,6 @@ describe Redis::Objects do
|
|
194
194
|
@roster.contact_information['updated_at'].class.should == Time
|
195
195
|
end
|
196
196
|
|
197
|
-
|
198
197
|
it "should create counter accessors" do
|
199
198
|
[:available_slots, :pitchers, :basic].each do |m|
|
200
199
|
@roster.respond_to?(m).should == true
|
@@ -879,6 +878,13 @@ describe Redis::Objects do
|
|
879
878
|
@custom_method_roster.basic.should.be.kind_of(Redis::Counter)
|
880
879
|
end
|
881
880
|
|
881
|
+
it "should respond to #to_json" do
|
882
|
+
@roster = Roster.new
|
883
|
+
@roster.player_totals.increment
|
884
|
+
json = JSON.parse(@roster.player_totals.to_json)
|
885
|
+
json['value'].should == 1
|
886
|
+
end
|
887
|
+
|
882
888
|
it "should persist object with custom id field name" do
|
883
889
|
@custom_id_field_roster = CustomIdFieldRoster.new()
|
884
890
|
@custom_id_field_roster.uid.should == 123 # sanity
|
@@ -986,4 +992,10 @@ describe Redis::Objects do
|
|
986
992
|
@roster.sorted_set_with_expireat.ttl.should > 0
|
987
993
|
@roster.sorted_set_with_expireat.ttl.should <= 10
|
988
994
|
end
|
995
|
+
|
996
|
+
it "should allow deleting the entire object" do
|
997
|
+
@roster.redis.keys.select { |key| key.match(/^roster:/)}.count.should > 0
|
998
|
+
@roster.delete!.should > 0
|
999
|
+
@roster.redis.keys.select { |key| key.match(/^roster:/)}.count.should == 0
|
1000
|
+
end
|
989
1001
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -23,26 +23,35 @@ REDIS_PID = 'redis.pid' # can't be absolute
|
|
23
23
|
REDIS_DUMP = 'redis.rdb' # can't be absolute
|
24
24
|
REDIS_RUNDIR = File.dirname(__FILE__)
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
sleep 2
|
34
|
-
end
|
26
|
+
def start_redis
|
27
|
+
puts "=> Starting redis-server on #{REDIS_HOST}:#{REDIS_PORT}"
|
28
|
+
fork_pid = fork do
|
29
|
+
system "cd #{REDIS_RUNDIR} && (echo port #{REDIS_PORT}; " +
|
30
|
+
"echo logfile /dev/null; echo daemonize yes; " +
|
31
|
+
"echo pidfile #{REDIS_PID}; echo dbfilename #{REDIS_DUMP}; " +
|
32
|
+
"echo databases 32) | #{REDIS_BIN} -"
|
35
33
|
end
|
34
|
+
fork_pid.should > 0
|
35
|
+
sleep 2
|
36
|
+
end
|
37
|
+
|
38
|
+
def kill_redis
|
39
|
+
pidfile = File.expand_path REDIS_PID, REDIS_RUNDIR
|
40
|
+
rdbfile = File.expand_path REDIS_DUMP, REDIS_RUNDIR
|
41
|
+
pid = File.read(pidfile).to_i
|
42
|
+
puts "=> Killing #{REDIS_BIN} with pid #{pid}"
|
43
|
+
Process.kill "TERM", pid
|
44
|
+
Process.kill "KILL", pid
|
45
|
+
File.unlink pidfile
|
46
|
+
File.unlink rdbfile if File.exists? rdbfile
|
47
|
+
end
|
48
|
+
|
49
|
+
# Start redis-server except under JRuby
|
50
|
+
unless defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
|
51
|
+
start_redis
|
36
52
|
|
37
53
|
at_exit do
|
38
|
-
|
39
|
-
rdbfile = File.expand_path REDIS_DUMP, REDIS_RUNDIR
|
40
|
-
pid = File.read(pidfile).to_i
|
41
|
-
puts "=> Killing #{REDIS_BIN} with pid #{pid}"
|
42
|
-
Process.kill "TERM", pid
|
43
|
-
Process.kill "KILL", pid
|
44
|
-
File.unlink pidfile
|
45
|
-
File.unlink rdbfile if File.exists? rdbfile
|
54
|
+
kill_redis
|
46
55
|
end
|
47
56
|
end
|
48
57
|
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-objects
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.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:
|
11
|
+
date: 2017-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.
|
19
|
+
version: '3.3'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 3.
|
26
|
+
version: '3.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,16 +98,16 @@ dependencies:
|
|
98
98
|
name: activerecord
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
103
|
+
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
110
|
+
version: '0'
|
111
111
|
description: Map Redis types directly to Ruby objects. Works with any class or ORM.
|
112
112
|
email:
|
113
113
|
- nwiger@gmail.com
|
@@ -153,7 +153,7 @@ files:
|
|
153
153
|
- spec/spec_helper.rb
|
154
154
|
homepage: http://github.com/nateware/redis-objects
|
155
155
|
licenses:
|
156
|
-
- Artistic
|
156
|
+
- Artistic-2.0
|
157
157
|
metadata: {}
|
158
158
|
post_install_message:
|
159
159
|
rdoc_options: []
|
@@ -171,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
171
171
|
version: '0'
|
172
172
|
requirements: []
|
173
173
|
rubyforge_project:
|
174
|
-
rubygems_version: 2.
|
174
|
+
rubygems_version: 2.6.8
|
175
175
|
signing_key:
|
176
176
|
specification_version: 4
|
177
177
|
summary: Map Redis types directly to Ruby objects
|