redis-objects 0.6.0 → 0.7.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.
- data/CHANGELOG.rdoc +28 -12
- data/Gemfile +6 -4
- data/{README.rdoc → README.md} +128 -100
- data/Rakefile +4 -4
- data/VERSION +1 -1
- data/lib/redis/base_object.rb +6 -1
- data/lib/redis/counter.rb +8 -8
- data/lib/redis/hash_key.rb +1 -2
- data/lib/redis/helpers/core_commands.rb +1 -1
- data/lib/redis/helpers/serialize.rb +13 -1
- data/lib/redis/list.rb +5 -5
- data/lib/redis/lock.rb +2 -2
- data/lib/redis/objects/counters.rb +11 -11
- data/lib/redis/objects/hashes.rb +1 -1
- data/lib/redis/objects/lists.rb +2 -2
- data/lib/redis/objects/locks.rb +4 -4
- data/lib/redis/objects/sets.rb +3 -3
- data/lib/redis/objects/sorted_sets.rb +2 -2
- data/lib/redis/objects/values.rb +4 -4
- data/lib/redis/objects.rb +35 -15
- data/lib/redis/set.rb +1 -1
- data/lib/redis/sorted_set.rb +1 -1
- data/lib/redis/value.rb +2 -2
- data/lib/redis-objects.rb +1 -0
- data/redis-objects.gemspec +8 -22
- data/spec/redis_autoload_objects_spec.rb +46 -0
- data/spec/redis_namespace_compat_spec.rb +2 -2
- data/spec/redis_objects_active_record_spec.rb +1 -1
- data/spec/redis_objects_conn_spec.rb +104 -0
- data/spec/redis_objects_instance_spec.rb +15 -21
- data/spec/redis_objects_model_spec.rb +103 -23
- data/spec/spec_helper.rb +26 -6
- metadata +9 -91
- data/Gemfile.lock +0 -43
data/lib/redis/list.rb
CHANGED
|
@@ -13,7 +13,7 @@ class Redis
|
|
|
13
13
|
require 'redis/helpers/serialize'
|
|
14
14
|
include Redis::Helpers::Serialize
|
|
15
15
|
|
|
16
|
-
attr_reader :key, :options
|
|
16
|
+
attr_reader :key, :options
|
|
17
17
|
|
|
18
18
|
# Works like push. Can chain together: list << 'a' << 'b'
|
|
19
19
|
def <<(value)
|
|
@@ -21,10 +21,10 @@ class Redis
|
|
|
21
21
|
self # for << 'a' << 'b'
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
# Add a member before or after pivot in the list. Redis: LINSERT
|
|
25
|
+
def insert(where,pivot,value)
|
|
26
|
+
redis.linsert(key,where,to_redis(pivot),to_redis(value))
|
|
27
|
+
end
|
|
28
28
|
|
|
29
29
|
# Add a member to the end of the list. Redis: RPUSH
|
|
30
30
|
def push(value)
|
data/lib/redis/lock.rb
CHANGED
|
@@ -11,12 +11,12 @@ class Redis
|
|
|
11
11
|
class Lock < BaseObject
|
|
12
12
|
class LockTimeout < StandardError; end #:nodoc:
|
|
13
13
|
|
|
14
|
-
attr_reader :key, :options
|
|
14
|
+
attr_reader :key, :options
|
|
15
15
|
def initialize(key, *args)
|
|
16
16
|
super(key, *args)
|
|
17
17
|
@options[:timeout] ||= 5
|
|
18
18
|
@options[:init] = false if @options[:init].nil? # default :init to false
|
|
19
|
-
|
|
19
|
+
redis.setnx(key, @options[:start]) unless @options[:start] == 0 || @options[:init] === false
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
# Clear the lock. Should only be needed if there's a server crash
|
|
@@ -22,7 +22,7 @@ class Redis
|
|
|
22
22
|
def counter(name, options={})
|
|
23
23
|
options[:start] ||= 0
|
|
24
24
|
options[:type] ||= options[:start] == 0 ? :increment : :decrement
|
|
25
|
-
|
|
25
|
+
redis_objects[name.to_sym] = options.merge(:type => :counter)
|
|
26
26
|
klass_name = '::' + self.name
|
|
27
27
|
if options[:global]
|
|
28
28
|
instance_eval <<-EndMethods
|
|
@@ -60,7 +60,7 @@ class Redis
|
|
|
60
60
|
verify_counter_defined!(name, id)
|
|
61
61
|
initialize_counter!(name, id)
|
|
62
62
|
value = redis.incrby(redis_field_key(name, id), by).to_i
|
|
63
|
-
block_given? ? rewindable_block(:decrement_counter, name, id, value, &block) : value
|
|
63
|
+
block_given? ? rewindable_block(:decrement_counter, name, id, by, value, &block) : value
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
# Decrement a counter with the specified name and id. Accepts a block
|
|
@@ -71,13 +71,13 @@ class Redis
|
|
|
71
71
|
verify_counter_defined!(name, id)
|
|
72
72
|
initialize_counter!(name, id)
|
|
73
73
|
value = redis.decrby(redis_field_key(name, id), by).to_i
|
|
74
|
-
block_given? ? rewindable_block(:increment_counter, name, id, value, &block) : value
|
|
74
|
+
block_given? ? rewindable_block(:increment_counter, name, id, by, value, &block) : value
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
# Reset a counter to its starting value.
|
|
78
78
|
def reset_counter(name, id=nil, to=nil)
|
|
79
79
|
verify_counter_defined!(name, id)
|
|
80
|
-
to =
|
|
80
|
+
to = redis_objects[name][:start] if to.nil?
|
|
81
81
|
redis.set(redis_field_key(name, id), to.to_i)
|
|
82
82
|
true
|
|
83
83
|
end
|
|
@@ -85,7 +85,7 @@ class Redis
|
|
|
85
85
|
# Set a counter to its starting value and return the old value.
|
|
86
86
|
def getset_counter(name, id=nil, to=nil)
|
|
87
87
|
verify_counter_defined!(name, id)
|
|
88
|
-
to =
|
|
88
|
+
to = redis_objects[name][:start] if to.nil?
|
|
89
89
|
redis.getset(redis_field_key(name, id), to.to_i).to_i
|
|
90
90
|
end
|
|
91
91
|
|
|
@@ -93,35 +93,35 @@ class Redis
|
|
|
93
93
|
|
|
94
94
|
def verify_counter_defined!(name, id) #:nodoc:
|
|
95
95
|
raise NoMethodError, "Undefined counter :#{name} for class #{self.name}" unless counter_defined?(name)
|
|
96
|
-
if id.nil? and
|
|
96
|
+
if id.nil? and !redis_objects[name][:global]
|
|
97
97
|
raise Redis::Objects::MissingID, "Missing ID for non-global counter #{self.name}##{name}"
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
def counter_defined?(name) #:nodoc:
|
|
102
|
-
|
|
102
|
+
redis_objects && redis_objects.has_key?(name)
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def initialize_counter!(name, id) #:nodoc:
|
|
106
106
|
key = redis_field_key(name, id)
|
|
107
107
|
unless @initialized_counters[key]
|
|
108
|
-
redis.setnx(key,
|
|
108
|
+
redis.setnx(key, redis_objects[name][:start])
|
|
109
109
|
end
|
|
110
110
|
@initialized_counters[key] = true
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
# Implements increment/decrement blocks on a class level
|
|
114
|
-
def rewindable_block(rewind, name, id, value, &block) #:nodoc:
|
|
114
|
+
def rewindable_block(rewind, name, id, by, value, &block) #:nodoc:
|
|
115
115
|
# Unfortunately this is almost exactly duplicated from Redis::Counter
|
|
116
116
|
raise ArgumentError, "Missing block to rewindable_block somehow" unless block_given?
|
|
117
117
|
ret = nil
|
|
118
118
|
begin
|
|
119
119
|
ret = yield value
|
|
120
120
|
rescue
|
|
121
|
-
send(rewind, name, id)
|
|
121
|
+
send(rewind, name, id, by)
|
|
122
122
|
raise
|
|
123
123
|
end
|
|
124
|
-
send(rewind, name, id) if ret.nil?
|
|
124
|
+
send(rewind, name, id, by) if ret.nil?
|
|
125
125
|
ret
|
|
126
126
|
end
|
|
127
127
|
end
|
data/lib/redis/objects/hashes.rb
CHANGED
|
@@ -14,7 +14,7 @@ class Redis
|
|
|
14
14
|
# Define a new hash key. It will function like a regular instance
|
|
15
15
|
# method, so it can be used alongside ActiveRecord, DataMapper, etc.
|
|
16
16
|
def hash_key(name, options={})
|
|
17
|
-
|
|
17
|
+
redis_objects[name.to_sym] = options.merge(:type => :dict)
|
|
18
18
|
klass_name = '::' + self.name
|
|
19
19
|
if options[:global]
|
|
20
20
|
instance_eval <<-EndMethods
|
data/lib/redis/objects/lists.rb
CHANGED
|
@@ -14,7 +14,7 @@ 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
|
-
|
|
17
|
+
redis_objects[name.to_sym] = options.merge(:type => :list)
|
|
18
18
|
klass_name = '::' + self.name
|
|
19
19
|
if options[:global]
|
|
20
20
|
instance_eval <<-EndMethods
|
|
@@ -42,4 +42,4 @@ class Redis
|
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
|
-
end
|
|
45
|
+
end
|
data/lib/redis/objects/locks.rb
CHANGED
|
@@ -17,7 +17,7 @@ class Redis
|
|
|
17
17
|
def lock(name, options={})
|
|
18
18
|
options[:timeout] ||= 5 # seconds
|
|
19
19
|
lock_name = "#{name}_lock"
|
|
20
|
-
|
|
20
|
+
redis_objects[lock_name.to_sym] = options.merge(:type => :lock)
|
|
21
21
|
klass_name = '::' + self.name
|
|
22
22
|
if options[:global]
|
|
23
23
|
instance_eval <<-EndMethods
|
|
@@ -46,7 +46,7 @@ class Redis
|
|
|
46
46
|
verify_lock_defined!(name)
|
|
47
47
|
raise ArgumentError, "Missing block to #{self.name}.obtain_lock" unless block_given?
|
|
48
48
|
lock_name = "#{name}_lock"
|
|
49
|
-
Redis::Lock.new(redis_field_key(lock_name, id), redis,
|
|
49
|
+
Redis::Lock.new(redis_field_key(lock_name, id), redis, redis_objects[lock_name.to_sym]).lock(&block)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# Clear the lock. Use with care - usually only in an Admin page to clear
|
|
@@ -57,9 +57,9 @@ class Redis
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
private
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
def verify_lock_defined!(name)
|
|
62
|
-
unless
|
|
62
|
+
unless redis_objects.has_key?("#{name}_lock".to_sym)
|
|
63
63
|
raise Redis::Objects::UndefinedLock, "Undefined lock :#{name} for class #{self.name}"
|
|
64
64
|
end
|
|
65
65
|
end
|
data/lib/redis/objects/sets.rb
CHANGED
|
@@ -14,7 +14,7 @@ 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
|
-
|
|
17
|
+
redis_objects[name.to_sym] = options.merge(:type => :set)
|
|
18
18
|
klass_name = '::' + self.name
|
|
19
19
|
if options[:global]
|
|
20
20
|
instance_eval <<-EndMethods
|
|
@@ -34,7 +34,7 @@ class Redis
|
|
|
34
34
|
end
|
|
35
35
|
EndMethods
|
|
36
36
|
end
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -43,4 +43,4 @@ class Redis
|
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
|
-
end
|
|
46
|
+
end
|
|
@@ -14,7 +14,7 @@ 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
|
-
|
|
17
|
+
redis_objects[name.to_sym] = options.merge(:type => :sorted_set)
|
|
18
18
|
klass_name = '::' + self.name
|
|
19
19
|
if options[:global]
|
|
20
20
|
instance_eval <<-EndMethods
|
|
@@ -42,4 +42,4 @@ class Redis
|
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
|
-
end
|
|
45
|
+
end
|
data/lib/redis/objects/values.rb
CHANGED
|
@@ -14,7 +14,7 @@ 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
|
-
|
|
17
|
+
redis_objects[name.to_sym] = options.merge(:type => :value)
|
|
18
18
|
klass_name = '::' + self.name
|
|
19
19
|
if options[:global]
|
|
20
20
|
instance_eval <<-EndMethods
|
|
@@ -43,13 +43,13 @@ class Redis
|
|
|
43
43
|
end
|
|
44
44
|
EndMethods
|
|
45
45
|
end
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
# Instance methods that appear in your class when you include Redis::Objects.
|
|
51
51
|
module InstanceMethods
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
|
-
end
|
|
55
|
+
end
|
data/lib/redis/objects.rb
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
# Redis::Objects - Lightweight object layer around redis-rb
|
|
2
2
|
# See README.rdoc for usage and approach.
|
|
3
3
|
require 'redis'
|
|
4
|
+
|
|
4
5
|
class Redis
|
|
6
|
+
autoload :Counter, 'redis/counter'
|
|
7
|
+
autoload :List, 'redis/list'
|
|
8
|
+
autoload :Lock, 'redis/lock'
|
|
9
|
+
autoload :Set, 'redis/set'
|
|
10
|
+
autoload :SortedSet, 'redis/sorted_set'
|
|
11
|
+
autoload :Value, 'redis/value'
|
|
12
|
+
autoload :HashKey, 'redis/hash_key'
|
|
13
|
+
|
|
5
14
|
#
|
|
6
15
|
# Redis::Objects enables high-performance atomic operations in your app
|
|
7
16
|
# by leveraging the atomic features of the Redis server. To use Redis::Objects,
|
|
@@ -17,7 +26,7 @@ class Redis
|
|
|
17
26
|
# lock :archive_game
|
|
18
27
|
# set :player_ids
|
|
19
28
|
# end
|
|
20
|
-
#
|
|
29
|
+
#
|
|
21
30
|
# The, you can use these counters both for bookeeping and as atomic actions:
|
|
22
31
|
#
|
|
23
32
|
# @game = Game.find(id)
|
|
@@ -38,30 +47,33 @@ class Redis
|
|
|
38
47
|
module Objects
|
|
39
48
|
dir = File.expand_path(__FILE__.sub(/\.rb$/,''))
|
|
40
49
|
|
|
41
|
-
autoload :Counters,
|
|
42
|
-
autoload :Lists,
|
|
43
|
-
autoload :Locks,
|
|
44
|
-
autoload :Sets,
|
|
45
|
-
autoload :SortedSets,
|
|
46
|
-
autoload :Values,
|
|
47
|
-
autoload :Hashes,
|
|
50
|
+
autoload :Counters, 'redis/objects/counters'
|
|
51
|
+
autoload :Lists, 'redis/objects/lists'
|
|
52
|
+
autoload :Locks, 'redis/objects/locks'
|
|
53
|
+
autoload :Sets, 'redis/objects/sets'
|
|
54
|
+
autoload :SortedSets, 'redis/objects/sorted_sets'
|
|
55
|
+
autoload :Values, 'redis/objects/values'
|
|
56
|
+
autoload :Hashes, 'redis/objects/hashes'
|
|
48
57
|
|
|
49
58
|
class NotConnected < StandardError; end
|
|
50
59
|
class NilObjectId < StandardError; end
|
|
51
60
|
|
|
52
61
|
class << self
|
|
53
|
-
def redis=(conn)
|
|
62
|
+
def redis=(conn)
|
|
63
|
+
@redis = conn
|
|
64
|
+
end
|
|
54
65
|
def redis
|
|
55
|
-
@redis
|
|
66
|
+
@redis || $redis || Redis.current ||
|
|
67
|
+
raise(NotConnected, "Redis::Objects.redis not set to a Redis.new connection")
|
|
56
68
|
end
|
|
57
69
|
|
|
58
70
|
def included(klass)
|
|
59
71
|
# Core (this file)
|
|
60
|
-
klass.instance_variable_set('@redis',
|
|
72
|
+
klass.instance_variable_set('@redis', nil)
|
|
61
73
|
klass.instance_variable_set('@redis_objects', {})
|
|
62
74
|
klass.send :include, InstanceMethods
|
|
63
75
|
klass.extend ClassMethods
|
|
64
|
-
|
|
76
|
+
|
|
65
77
|
# Pull in each object type
|
|
66
78
|
klass.send :include, Redis::Objects::Counters
|
|
67
79
|
klass.send :include, Redis::Objects::Lists
|
|
@@ -75,9 +87,17 @@ class Redis
|
|
|
75
87
|
|
|
76
88
|
# Class methods that appear in your class when you include Redis::Objects.
|
|
77
89
|
module ClassMethods
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def redis
|
|
90
|
+
# Enable per-class connections (eg, User and Post can use diff redis-server)
|
|
91
|
+
attr_writer :redis
|
|
92
|
+
def redis
|
|
93
|
+
@redis || Objects.redis
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Internal list of objects
|
|
97
|
+
attr_writer :redis_objects
|
|
98
|
+
def redis_objects
|
|
99
|
+
@redis_objects ||= {}
|
|
100
|
+
end
|
|
81
101
|
|
|
82
102
|
# Set the Redis redis_prefix to use. Defaults to model_name
|
|
83
103
|
def redis_prefix=(redis_prefix) @redis_prefix = redis_prefix end
|
data/lib/redis/set.rb
CHANGED
data/lib/redis/sorted_set.rb
CHANGED
|
@@ -12,7 +12,7 @@ class Redis
|
|
|
12
12
|
require 'redis/helpers/serialize'
|
|
13
13
|
include Redis::Helpers::Serialize
|
|
14
14
|
|
|
15
|
-
attr_reader :key, :options
|
|
15
|
+
attr_reader :key, :options
|
|
16
16
|
|
|
17
17
|
# How to add values using a sorted set. The key is the member, eg,
|
|
18
18
|
# "Peter", and the value is the score, eg, 163. So:
|
data/lib/redis/value.rb
CHANGED
|
@@ -10,10 +10,10 @@ class Redis
|
|
|
10
10
|
require 'redis/helpers/serialize'
|
|
11
11
|
include Redis::Helpers::Serialize
|
|
12
12
|
|
|
13
|
-
attr_reader :key, :options
|
|
13
|
+
attr_reader :key, :options
|
|
14
14
|
def initialize(key, *args)
|
|
15
15
|
super(key, *args)
|
|
16
|
-
|
|
16
|
+
redis.setnx(key, to_redis(@options[:default])) if @options[:default]
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def value=(val)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'redis/objects'
|
data/redis-objects.gemspec
CHANGED
|
@@ -5,24 +5,24 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = "redis-objects"
|
|
8
|
-
s.version = "0.
|
|
8
|
+
s.version = "0.7.0"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Nate Wiger"]
|
|
12
|
-
s.date = "
|
|
12
|
+
s.date = "2013-02-27"
|
|
13
13
|
s.description = "Map Redis types directly to Ruby objects. Works with any class or ORM."
|
|
14
|
-
s.email = "
|
|
14
|
+
s.email = "nwiger@gmail.com"
|
|
15
15
|
s.extra_rdoc_files = [
|
|
16
|
-
"README.
|
|
16
|
+
"README.md"
|
|
17
17
|
]
|
|
18
18
|
s.files = [
|
|
19
19
|
"ATOMICITY.rdoc",
|
|
20
20
|
"CHANGELOG.rdoc",
|
|
21
21
|
"Gemfile",
|
|
22
|
-
"
|
|
23
|
-
"README.rdoc",
|
|
22
|
+
"README.md",
|
|
24
23
|
"Rakefile",
|
|
25
24
|
"VERSION",
|
|
25
|
+
"lib/redis-objects.rb",
|
|
26
26
|
"lib/redis/base_object.rb",
|
|
27
27
|
"lib/redis/counter.rb",
|
|
28
28
|
"lib/redis/hash_key.rb",
|
|
@@ -42,15 +42,16 @@ Gem::Specification.new do |s|
|
|
|
42
42
|
"lib/redis/sorted_set.rb",
|
|
43
43
|
"lib/redis/value.rb",
|
|
44
44
|
"redis-objects.gemspec",
|
|
45
|
+
"spec/redis_autoload_objects_spec.rb",
|
|
45
46
|
"spec/redis_namespace_compat_spec.rb",
|
|
46
47
|
"spec/redis_objects_active_record_spec.rb",
|
|
48
|
+
"spec/redis_objects_conn_spec.rb",
|
|
47
49
|
"spec/redis_objects_instance_spec.rb",
|
|
48
50
|
"spec/redis_objects_model_spec.rb",
|
|
49
51
|
"spec/spec_helper.rb"
|
|
50
52
|
]
|
|
51
53
|
s.homepage = "http://github.com/nateware/redis-objects"
|
|
52
54
|
s.require_paths = ["lib"]
|
|
53
|
-
s.requirements = ["redis, v3.0.2 or greater"]
|
|
54
55
|
s.rubygems_version = "1.8.24"
|
|
55
56
|
s.summary = "Map Redis types directly to Ruby objects"
|
|
56
57
|
|
|
@@ -59,32 +60,17 @@ Gem::Specification.new do |s|
|
|
|
59
60
|
|
|
60
61
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
61
62
|
s.add_runtime_dependency(%q<redis>, [">= 3.0.2"])
|
|
62
|
-
s.add_runtime_dependency(%q<redis-namespace>, [">= 0"])
|
|
63
|
-
s.add_runtime_dependency(%q<bacon>, [">= 0"])
|
|
64
|
-
s.add_runtime_dependency(%q<jeweler>, [">= 0"])
|
|
65
|
-
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
|
66
63
|
s.add_development_dependency(%q<bacon>, [">= 0"])
|
|
67
64
|
s.add_development_dependency(%q<redis-namespace>, [">= 1.2.0"])
|
|
68
|
-
s.add_runtime_dependency(%q<redis>, [">= 3.0.2"])
|
|
69
65
|
else
|
|
70
66
|
s.add_dependency(%q<redis>, [">= 3.0.2"])
|
|
71
|
-
s.add_dependency(%q<redis-namespace>, [">= 0"])
|
|
72
|
-
s.add_dependency(%q<bacon>, [">= 0"])
|
|
73
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
74
|
-
s.add_dependency(%q<activerecord>, [">= 0"])
|
|
75
67
|
s.add_dependency(%q<bacon>, [">= 0"])
|
|
76
68
|
s.add_dependency(%q<redis-namespace>, [">= 1.2.0"])
|
|
77
|
-
s.add_dependency(%q<redis>, [">= 3.0.2"])
|
|
78
69
|
end
|
|
79
70
|
else
|
|
80
71
|
s.add_dependency(%q<redis>, [">= 3.0.2"])
|
|
81
|
-
s.add_dependency(%q<redis-namespace>, [">= 0"])
|
|
82
|
-
s.add_dependency(%q<bacon>, [">= 0"])
|
|
83
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
84
|
-
s.add_dependency(%q<activerecord>, [">= 0"])
|
|
85
72
|
s.add_dependency(%q<bacon>, [">= 0"])
|
|
86
73
|
s.add_dependency(%q<redis-namespace>, [">= 1.2.0"])
|
|
87
|
-
s.add_dependency(%q<redis>, [">= 3.0.2"])
|
|
88
74
|
end
|
|
89
75
|
end
|
|
90
76
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
3
|
+
|
|
4
|
+
# tests whether autoload functionality works correctly; had issues previously
|
|
5
|
+
|
|
6
|
+
require 'redis/objects'
|
|
7
|
+
# $redis used automatically
|
|
8
|
+
|
|
9
|
+
describe 'Redis::Objects' do
|
|
10
|
+
it "should autoload everything" do
|
|
11
|
+
defined?(::Redis::Counter).should == "constant"
|
|
12
|
+
x = Redis::Counter.new('x')
|
|
13
|
+
x.class.name.should == "Redis::Counter"
|
|
14
|
+
x.redis.should == REDIS_HANDLE
|
|
15
|
+
|
|
16
|
+
defined?(::Redis::HashKey).should == "constant"
|
|
17
|
+
x = Redis::HashKey.new('x')
|
|
18
|
+
x.class.name.should == "Redis::HashKey"
|
|
19
|
+
x.redis.should == REDIS_HANDLE
|
|
20
|
+
|
|
21
|
+
defined?(::Redis::List).should == "constant"
|
|
22
|
+
x = Redis::List.new('x')
|
|
23
|
+
x.class.name.should == "Redis::List"
|
|
24
|
+
x.redis.should == REDIS_HANDLE
|
|
25
|
+
|
|
26
|
+
defined?(::Redis::Lock).should == "constant"
|
|
27
|
+
x = Redis::Lock.new('x')
|
|
28
|
+
x.class.name.should == "Redis::Lock"
|
|
29
|
+
x.redis.should == REDIS_HANDLE
|
|
30
|
+
|
|
31
|
+
defined?(::Redis::Set).should == "constant"
|
|
32
|
+
x = Redis::Set.new('x')
|
|
33
|
+
x.class.name.should == "Redis::Set"
|
|
34
|
+
x.redis.should == REDIS_HANDLE
|
|
35
|
+
|
|
36
|
+
defined?(::Redis::SortedSet).should == "constant"
|
|
37
|
+
x = Redis::SortedSet.new('x')
|
|
38
|
+
x.class.name.should == "Redis::SortedSet"
|
|
39
|
+
x.redis.should == REDIS_HANDLE
|
|
40
|
+
|
|
41
|
+
defined?(::Redis::Value).should == "constant"
|
|
42
|
+
x = Redis::Value.new('x')
|
|
43
|
+
x.class.name.should == "Redis::Value"
|
|
44
|
+
x.redis.should == REDIS_HANDLE
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
|
3
3
|
require 'redis/objects'
|
|
4
|
-
Redis::Objects.redis =
|
|
4
|
+
Redis::Objects.redis = REDIS_HANDLE
|
|
5
5
|
|
|
6
6
|
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../../redis-namespace/lib')
|
|
7
7
|
begin
|
|
@@ -9,7 +9,7 @@ begin
|
|
|
9
9
|
|
|
10
10
|
describe 'Redis::Namespace compat' do
|
|
11
11
|
it "tests the compatibility of Hash and ::Hash conflicts" do
|
|
12
|
-
ns = Redis::Namespace.new("resque", :redis =>
|
|
12
|
+
ns = Redis::Namespace.new("resque", :redis => REDIS_HANDLE)
|
|
13
13
|
ns.instance_eval { rem_namespace({"resque:x" => nil}) }.should == {"x"=>nil}
|
|
14
14
|
class Foo
|
|
15
15
|
include Redis::Objects
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Connection tests - a bit ugly but important
|
|
3
|
+
#
|
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
5
|
+
|
|
6
|
+
require 'redis/objects'
|
|
7
|
+
|
|
8
|
+
BAD_REDIS = "totally bad bogus redis handle"
|
|
9
|
+
|
|
10
|
+
# Grab a global handle
|
|
11
|
+
describe 'Connection tests' do
|
|
12
|
+
it "should support local handles" do
|
|
13
|
+
Redis.current = nil # reset from other tests
|
|
14
|
+
Redis::Objects.redis = nil
|
|
15
|
+
@redis_handle = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
|
|
16
|
+
|
|
17
|
+
# Redis.current is lazily auto-populated to touch 6379
|
|
18
|
+
# This why we choose the weird 9212 port to avoid
|
|
19
|
+
Redis.current.inspect.should == Redis.new.inspect
|
|
20
|
+
Redis::Objects.redis.inspect.should == Redis.new.inspect
|
|
21
|
+
|
|
22
|
+
v = Redis::Value.new('conn/value', @redis_handle)
|
|
23
|
+
v.clear
|
|
24
|
+
v.value = 'yay'
|
|
25
|
+
v.value.should == 'yay'
|
|
26
|
+
|
|
27
|
+
h = Redis::HashKey.new('conn/hash', @redis_handle)
|
|
28
|
+
h.clear
|
|
29
|
+
h['k'] = 'v'
|
|
30
|
+
|
|
31
|
+
l = Redis::List.new('conn/list', @redis_handle)
|
|
32
|
+
l.clear
|
|
33
|
+
l << 3
|
|
34
|
+
l << 4
|
|
35
|
+
l << 5
|
|
36
|
+
|
|
37
|
+
s = Redis::Set.new('conn/set', @redis_handle)
|
|
38
|
+
s.clear
|
|
39
|
+
s << 5
|
|
40
|
+
s << 5
|
|
41
|
+
s << 6
|
|
42
|
+
s << 7
|
|
43
|
+
|
|
44
|
+
z = Redis::SortedSet.new('conn/zset', @redis_handle)
|
|
45
|
+
z.clear
|
|
46
|
+
z['a'] = 8
|
|
47
|
+
z['b'] = 7
|
|
48
|
+
z['c'] = 9
|
|
49
|
+
z['d'] = 6
|
|
50
|
+
|
|
51
|
+
c = Redis::Counter.new('conn/counter', @redis_handle)
|
|
52
|
+
c.reset
|
|
53
|
+
c.incr(3)
|
|
54
|
+
c.decr(1)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "should support Redis.current" do
|
|
58
|
+
Redis.current = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
|
|
59
|
+
|
|
60
|
+
Redis::Value.new('conn/value').should == 'yay'
|
|
61
|
+
Redis::HashKey.new('conn/hash').keys.should == ['k']
|
|
62
|
+
Redis::List.new('conn/list').sort.should == ['3', '4', '5']
|
|
63
|
+
Redis::Set.new('conn/set').sort.should == ['5', '6', '7']
|
|
64
|
+
Redis::SortedSet.new('conn/zset').should == ['d', 'b', 'a', 'c']
|
|
65
|
+
Redis::Counter.new('conn/counter').should == 2
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should support Redis::Objects.redis=" do
|
|
69
|
+
@redis_handle = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
|
|
70
|
+
|
|
71
|
+
# Redis.current is lazily auto-populated to touch 6379
|
|
72
|
+
# This why we choose the weird 9212 port to avoid
|
|
73
|
+
Redis.current = BAD_REDIS
|
|
74
|
+
Redis::Objects.redis.should == BAD_REDIS
|
|
75
|
+
|
|
76
|
+
# This set of tests sucks, it fucks up the per-data-type handles
|
|
77
|
+
# because Redis.current is then set to a BS value, and the lazy
|
|
78
|
+
# init code in redis-rb will keep that value until we clear it.
|
|
79
|
+
# This ends up fucking any sequential tests.
|
|
80
|
+
raises_exception{ Redis::Value.new('conn/value').should.be.nil }
|
|
81
|
+
raises_exception{ Redis::HashKey.new('conn/hash').keys.should == [] }
|
|
82
|
+
raises_exception{ Redis::List.new('conn/list').sort.should == [] }
|
|
83
|
+
raises_exception{ Redis::Set.new('conn/set').sort.should == [] }
|
|
84
|
+
raises_exception{ Redis::SortedSet.new('conn/zset').should == [] }
|
|
85
|
+
raises_exception{ Redis::Counter.new('conn/counter').get.should == 0 }
|
|
86
|
+
|
|
87
|
+
Redis::Objects.redis = @redis_handle
|
|
88
|
+
Redis::Value.new('fart').redis.should == @redis_handle
|
|
89
|
+
|
|
90
|
+
# These should now get the correct handle
|
|
91
|
+
Redis::Value.new('conn/value').should == 'yay'
|
|
92
|
+
Redis::HashKey.new('conn/hash').keys.should == ['k']
|
|
93
|
+
Redis::List.new('conn/list').sort.should == ['3', '4', '5']
|
|
94
|
+
Redis::Set.new('conn/set').sort.should == ['5', '6', '7']
|
|
95
|
+
Redis::SortedSet.new('conn/zset').should == ['d', 'b', 'a', 'c']
|
|
96
|
+
Redis::Counter.new('conn/counter').should == 2
|
|
97
|
+
|
|
98
|
+
# Fix for future tests
|
|
99
|
+
Redis.current = @redis_handle
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
|