redis-objects 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|