redis-objects 0.3.0 → 0.3.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.
- data/CHANGELOG.rdoc +6 -5
- data/lib/redis/objects.rb +12 -6
- data/lib/redis/objects/counters.rb +2 -2
- data/lib/redis/objects/lists.rb +2 -2
- data/lib/redis/objects/locks.rb +15 -13
- data/lib/redis/objects/sets.rb +2 -2
- data/lib/redis/objects/sorted_sets.rb +2 -3
- data/lib/redis/objects/values.rb +2 -2
- data/lib/redis/set.rb +16 -4
- data/lib/redis/sorted_set.rb +1 -1
- data/spec/redis_objects_model_spec.rb +30 -2
- metadata +3 -3
data/CHANGELOG.rdoc
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
= Changelog for Redis::Objects
|
2
2
|
|
3
|
+
== 0.3.1 [Final] (1 June 2010)
|
4
|
+
|
5
|
+
* Integrated fixes for sorted_set deletions from capotej (Julio Capote)
|
6
|
+
|
3
7
|
== 0.3.0 [Final] (14 April 2010)
|
4
8
|
|
5
|
-
* Due to Ruby 1.9 bugs and performance considerations, marshaling of
|
6
|
-
data types is now OFF by default. You must say :marshal => true for
|
7
|
-
any objects that you want serialization enabled on. [Nate Wiger]
|
9
|
+
* Due to Ruby 1.9 bugs and performance considerations, marshaling of data types is now OFF by default. You must say :marshal => true for any objects that you want serialization enabled on. [Nate Wiger]
|
8
10
|
|
9
|
-
* Sorted Set class changed slightly due to feedback. You can now get
|
10
|
-
an individual element back via @set['item'] since it acts like a Hash.
|
11
|
+
* Sorted Set class changed slightly due to feedback. You can now get an individual element back via @set['item'] since it acts like a Hash.
|
11
12
|
|
12
13
|
== 0.2.4 [Final] (9 April 2010)*
|
13
14
|
|
data/lib/redis/objects.rb
CHANGED
@@ -13,7 +13,7 @@ class Redis
|
|
13
13
|
# include Redis::Objects
|
14
14
|
#
|
15
15
|
# counter :joined_players
|
16
|
-
# counter :active_players
|
16
|
+
# counter :active_players, :key => 'game:#{id}:act_plyr'
|
17
17
|
# lock :archive_game
|
18
18
|
# set :player_ids
|
19
19
|
# end
|
@@ -83,18 +83,24 @@ class Redis
|
|
83
83
|
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
84
84
|
downcase
|
85
85
|
end
|
86
|
-
|
87
|
-
def field_key(name, id) #:nodoc:
|
88
|
-
"#{prefix}:#{id}:#{name}"
|
89
|
-
end
|
90
86
|
|
87
|
+
def field_key(name, id='') #:nodoc:
|
88
|
+
# This can never ever ever ever change or upgrades will corrupt all data
|
89
|
+
@redis_objects[name.to_sym][:key] || "#{prefix}:#{id}:#{name}"
|
90
|
+
end
|
91
91
|
end
|
92
92
|
|
93
93
|
# Instance methods that appear in your class when you include Redis::Objects.
|
94
94
|
module InstanceMethods
|
95
95
|
def redis() self.class.redis end
|
96
96
|
def field_key(name) #:nodoc:
|
97
|
-
|
97
|
+
# This can never ever ever ever change or upgrades will corrupt all data
|
98
|
+
if key = self.class.redis_objects[name.to_sym][:key]
|
99
|
+
eval "%(#{key})"
|
100
|
+
else
|
101
|
+
# don't try to refactor into class field_key because fucks up eval context
|
102
|
+
"#{self.class.prefix}:#{id}:#{name}"
|
103
|
+
end
|
98
104
|
end
|
99
105
|
end
|
100
106
|
end
|
@@ -22,11 +22,11 @@ class Redis
|
|
22
22
|
def counter(name, options={})
|
23
23
|
options[:start] ||= 0
|
24
24
|
options[:type] ||= options[:start] == 0 ? :increment : :decrement
|
25
|
-
@redis_objects[name] = options.merge(:type => :counter)
|
25
|
+
@redis_objects[name.to_sym] = options.merge(:type => :counter)
|
26
26
|
if options[:global]
|
27
27
|
instance_eval <<-EndMethods
|
28
28
|
def #{name}
|
29
|
-
@#{name} ||= Redis::Counter.new(field_key(:#{name}
|
29
|
+
@#{name} ||= Redis::Counter.new(field_key(:#{name}), redis, @redis_objects[:#{name}])
|
30
30
|
end
|
31
31
|
EndMethods
|
32
32
|
class_eval <<-EndMethods
|
data/lib/redis/objects/lists.rb
CHANGED
@@ -14,11 +14,11 @@ class Redis
|
|
14
14
|
# Define a new list. It will function like a regular instance
|
15
15
|
# method, so it can be used alongside ActiveRecord, DataMapper, etc.
|
16
16
|
def list(name, options={})
|
17
|
-
@redis_objects[name] = options.merge(:type => :list)
|
17
|
+
@redis_objects[name.to_sym] = options.merge(:type => :list)
|
18
18
|
if options[:global]
|
19
19
|
instance_eval <<-EndMethods
|
20
20
|
def #{name}
|
21
|
-
@#{name} ||= Redis::List.new(field_key(:#{name}
|
21
|
+
@#{name} ||= Redis::List.new(field_key(:#{name}), redis, @redis_objects[:#{name}])
|
22
22
|
end
|
23
23
|
EndMethods
|
24
24
|
class_eval <<-EndMethods
|
data/lib/redis/objects/locks.rb
CHANGED
@@ -16,22 +16,23 @@ class Redis
|
|
16
16
|
# so it can be used alongside ActiveRecord/DataMapper, etc.
|
17
17
|
def lock(name, options={})
|
18
18
|
options[:timeout] ||= 5 # seconds
|
19
|
-
|
19
|
+
lock_name = "#{name}_lock"
|
20
|
+
@redis_objects[lock_name.to_sym] = options.merge(:type => :lock)
|
20
21
|
if options[:global]
|
21
22
|
instance_eval <<-EndMethods
|
22
|
-
def #{
|
23
|
-
@#{
|
23
|
+
def #{lock_name}(&block)
|
24
|
+
@#{lock_name} ||= Redis::Lock.new(field_key(:#{lock_name}), redis, @redis_objects[:#{lock_name}])
|
24
25
|
end
|
25
26
|
EndMethods
|
26
27
|
class_eval <<-EndMethods
|
27
|
-
def #{
|
28
|
-
self.class.#{
|
28
|
+
def #{lock_name}(&block)
|
29
|
+
self.class.#{lock_name}(block)
|
29
30
|
end
|
30
31
|
EndMethods
|
31
32
|
else
|
32
33
|
class_eval <<-EndMethods
|
33
|
-
def #{
|
34
|
-
@#{
|
34
|
+
def #{lock_name}(&block)
|
35
|
+
@#{lock_name} ||= Redis::Lock.new(field_key(:#{lock_name}), redis, self.class.redis_objects[:#{lock_name}])
|
35
36
|
end
|
36
37
|
EndMethods
|
37
38
|
end
|
@@ -43,22 +44,23 @@ class Redis
|
|
43
44
|
def obtain_lock(name, id, &block)
|
44
45
|
verify_lock_defined!(name)
|
45
46
|
raise ArgumentError, "Missing block to #{self.name}.obtain_lock" unless block_given?
|
46
|
-
lock_name =
|
47
|
-
Redis::Lock.new(lock_name, redis,
|
47
|
+
lock_name = "#{name}_lock"
|
48
|
+
Redis::Lock.new(field_key(lock_name, id), redis, @redis_objects[lock_name.to_sym]).lock(&block)
|
48
49
|
end
|
49
50
|
|
50
51
|
# Clear the lock. Use with care - usually only in an Admin page to clear
|
51
52
|
# stale locks (a stale lock should only happen if a server crashes.)
|
52
53
|
def clear_lock(name, id)
|
53
54
|
verify_lock_defined!(name)
|
54
|
-
|
55
|
-
redis.del(lock_name)
|
55
|
+
redis.del(field_key("#{name}_lock", id))
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
private
|
59
59
|
|
60
60
|
def verify_lock_defined!(name)
|
61
|
-
|
61
|
+
unless @redis_objects.has_key?("#{name}_lock".to_sym)
|
62
|
+
raise Redis::Objects::UndefinedLock, "Undefined lock :#{name} for class #{self.name}"
|
63
|
+
end
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
data/lib/redis/objects/sets.rb
CHANGED
@@ -14,11 +14,11 @@ class Redis
|
|
14
14
|
# Define a new list. It will function like a regular instance
|
15
15
|
# method, so it can be used alongside ActiveRecord, DataMapper, etc.
|
16
16
|
def set(name, options={})
|
17
|
-
@redis_objects[name] = options.merge(:type => :set)
|
17
|
+
@redis_objects[name.to_sym] = options.merge(:type => :set)
|
18
18
|
if options[:global]
|
19
19
|
instance_eval <<-EndMethods
|
20
20
|
def #{name}
|
21
|
-
@#{name} ||= Redis::Set.new(field_key(:#{name}
|
21
|
+
@#{name} ||= Redis::Set.new(field_key(:#{name}), redis, @redis_objects[:#{name}])
|
22
22
|
end
|
23
23
|
EndMethods
|
24
24
|
class_eval <<-EndMethods
|
@@ -14,11 +14,11 @@ class Redis
|
|
14
14
|
# Define a new list. It will function like a regular instance
|
15
15
|
# method, so it can be used alongside ActiveRecord, DataMapper, etc.
|
16
16
|
def sorted_set(name, options={})
|
17
|
-
@redis_objects[name] = options.merge(:type => :sorted_set)
|
17
|
+
@redis_objects[name.to_sym] = options.merge(:type => :sorted_set)
|
18
18
|
if options[:global]
|
19
19
|
instance_eval <<-EndMethods
|
20
20
|
def #{name}
|
21
|
-
@#{name} ||= Redis::SortedSet.new(field_key(:#{name}
|
21
|
+
@#{name} ||= Redis::SortedSet.new(field_key(:#{name}), redis, @redis_objects[:#{name}])
|
22
22
|
end
|
23
23
|
EndMethods
|
24
24
|
class_eval <<-EndMethods
|
@@ -33,7 +33,6 @@ class Redis
|
|
33
33
|
end
|
34
34
|
EndMethods
|
35
35
|
end
|
36
|
-
|
37
36
|
end
|
38
37
|
end
|
39
38
|
|
data/lib/redis/objects/values.rb
CHANGED
@@ -14,11 +14,11 @@ class Redis
|
|
14
14
|
# Define a new simple value. It will function like a regular instance
|
15
15
|
# method, so it can be used alongside ActiveRecord, DataMapper, etc.
|
16
16
|
def value(name, options={})
|
17
|
-
@redis_objects[name] = options.merge(:type => :value)
|
17
|
+
@redis_objects[name.to_sym] = options.merge(:type => :value)
|
18
18
|
if options[:global]
|
19
19
|
instance_eval <<-EndMethods
|
20
20
|
def #{name}
|
21
|
-
@#{name} ||= Redis::Value.new(field_key(:#{name}
|
21
|
+
@#{name} ||= Redis::Value.new(field_key(:#{name}), redis, @redis_objects[:#{name}])
|
22
22
|
end
|
23
23
|
def #{name}=(value)
|
24
24
|
#{name}.value = value
|
data/lib/redis/set.rb
CHANGED
@@ -42,12 +42,23 @@ class Redis
|
|
42
42
|
redis.sismember(key, to_redis(value))
|
43
43
|
end
|
44
44
|
alias_method :include?, :member?
|
45
|
-
|
45
|
+
|
46
46
|
# Delete the value from the set. Redis: SREM
|
47
47
|
def delete(value)
|
48
|
-
redis.srem(key, value)
|
48
|
+
redis.srem(key, to_redis(value))
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
|
+
# Delete if matches block
|
52
|
+
def delete_if(&blk)
|
53
|
+
res = false
|
54
|
+
redis.smembers(key).each do |m|
|
55
|
+
if blk.call(from_redis(m))
|
56
|
+
res = redis.srem(key, m)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
res
|
60
|
+
end
|
61
|
+
|
51
62
|
# Iterate through each member of the set. Redis::Objects mixes in Enumerable,
|
52
63
|
# so you can also use familiar methods like +collect+, +detect+, and so forth.
|
53
64
|
def each(&block)
|
@@ -131,6 +142,7 @@ class Redis
|
|
131
142
|
redis.scard(key)
|
132
143
|
end
|
133
144
|
alias_method :size, :length
|
145
|
+
alias_method :count, :length
|
134
146
|
|
135
147
|
# Returns true if the set has no members. Redis: SCARD == 0
|
136
148
|
def empty?
|
@@ -153,4 +165,4 @@ class Redis
|
|
153
165
|
end
|
154
166
|
|
155
167
|
end
|
156
|
-
end
|
168
|
+
end
|
data/lib/redis/sorted_set.rb
CHANGED
@@ -19,9 +19,17 @@ class Roster
|
|
19
19
|
list :all_player_stats, :global => true
|
20
20
|
set :all_players_online, :global => true
|
21
21
|
value :last_player, :global => true
|
22
|
+
|
23
|
+
# custom keys
|
24
|
+
counter :player_totals, :key => 'players/#{username}/total'
|
25
|
+
list :all_player_stats, :key => 'players:all_stats'
|
26
|
+
set :total_wins, :key => 'players:#{id}:all_stats'
|
27
|
+
value :my_rank, :key => 'players:my_rank:#{username}'
|
28
|
+
value :weird_key, :key => 'players:weird_key:#{raise}', :global => true
|
22
29
|
|
23
30
|
def initialize(id=1) @id = id end
|
24
31
|
def id; @id; end
|
32
|
+
def username; "user#{id}"; end
|
25
33
|
def max_pitchers; 3; end
|
26
34
|
end
|
27
35
|
|
@@ -49,17 +57,38 @@ describe Redis::Objects do
|
|
49
57
|
@roster.redis.del(UNIONSTORE_KEY)
|
50
58
|
@roster.redis.del(INTERSTORE_KEY)
|
51
59
|
@roster.redis.del(DIFFSTORE_KEY)
|
52
|
-
|
60
|
+
|
53
61
|
Roster.total_players_online.reset
|
54
62
|
Roster.all_player_stats.clear
|
55
63
|
Roster.all_players_online.clear
|
56
64
|
Roster.last_player.delete
|
65
|
+
Roster.weird_key.clear
|
66
|
+
|
67
|
+
@roster.player_totals.clear
|
68
|
+
@roster.all_player_stats.clear
|
69
|
+
@roster.total_wins.clear
|
70
|
+
@roster.my_rank.clear
|
57
71
|
end
|
58
72
|
|
59
73
|
it "should provide a connection method" do
|
60
74
|
Roster.redis.should == Redis::Objects.redis
|
61
75
|
# Roster.redis.should be_kind_of(Redis)
|
62
76
|
end
|
77
|
+
|
78
|
+
it "should support custom key names" do
|
79
|
+
@roster.player_totals.incr
|
80
|
+
@roster.redis.get('players/user1/total').should == '1'
|
81
|
+
@roster.redis.get('players/#{username}/total').should be_nil
|
82
|
+
@roster.all_player_stats << 'a'
|
83
|
+
@roster.redis.lindex('players:all_stats', 0).should == 'a'
|
84
|
+
@roster.total_wins << 'a'
|
85
|
+
@roster.redis.smembers('players:1:all_stats').should == ['a']
|
86
|
+
@roster.redis.smembers('players:#{id}:all_stats').should == []
|
87
|
+
@roster.my_rank = 'a'
|
88
|
+
@roster.redis.get('players:my_rank:user1').should == 'a'
|
89
|
+
Roster.weird_key = 'tuka'
|
90
|
+
Roster.redis.get('players:weird_key:#{raise}').should == 'tuka'
|
91
|
+
end
|
63
92
|
|
64
93
|
it "should create counter accessors" do
|
65
94
|
[:available_slots, :pitchers, :basic].each do |m|
|
@@ -648,5 +677,4 @@ describe Redis::Objects do
|
|
648
677
|
error.should_not be_nil
|
649
678
|
error.should be_kind_of(Redis::Lock::LockTimeout)
|
650
679
|
end
|
651
|
-
|
652
680
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Nate Wiger
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-06-01 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|