redis-objects 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -118,7 +118,7 @@ class Redis
118
118
 
119
119
  # Set keys in bulk if they do not exist. Takes a hash of field/values {'field1' => 'val1'}. Redis: HSETNX
120
120
  def fill(pairs={})
121
- raise ArgumentErorr, "Arugment to fill must be a hash of key/value pairs" unless pairs.is_a?(::Hash)
121
+ raise ArgumentError, "Arugment to fill must be a hash of key/value pairs" unless pairs.is_a?(::Hash)
122
122
  pairs.each do |field, value|
123
123
  redis.hsetnx(key, field, to_redis(value, options[:marshal_keys][field]))
124
124
  end
data/lib/redis/list.rb CHANGED
@@ -20,15 +20,15 @@ class Redis
20
20
  push(value)
21
21
  self # for << 'a' << 'b'
22
22
  end
23
-
23
+
24
24
  # Add a member before or after pivot in the list. Redis: LINSERT
25
25
  def insert(where,pivot,value)
26
26
  redis.linsert(key,where,to_redis(pivot),to_redis(value))
27
27
  end
28
28
 
29
29
  # Add a member to the end of the list. Redis: RPUSH
30
- def push(value)
31
- redis.rpush(key, to_redis(value))
30
+ def push(*values)
31
+ redis.rpush(key, values.map{|v| to_redis(v) })
32
32
  redis.ltrim(key, -options[:maxlength], -1) if options[:maxlength]
33
33
  end
34
34
 
@@ -50,8 +50,8 @@ class Redis
50
50
  end
51
51
 
52
52
  # Add a member to the start of the list. Redis: LPUSH
53
- def unshift(value)
54
- redis.lpush(key, to_redis(value))
53
+ def unshift(*values)
54
+ redis.lpush(key, values.map{|v| to_redis(v) })
55
55
  redis.ltrim(key, 0, options[:maxlength] - 1) if options[:maxlength]
56
56
  end
57
57
 
@@ -88,7 +88,7 @@ class Redis
88
88
 
89
89
  # Same functionality as Ruby arrays.
90
90
  def []=(index, value)
91
- redis.lset(key, index, value)
91
+ redis.lset(key, index, to_redis(value))
92
92
  end
93
93
 
94
94
  # Delete the element(s) from the list that match name. If count is specified,
@@ -132,16 +132,16 @@ class Redis
132
132
  redis.llen(key)
133
133
  end
134
134
  alias_method :size, :length
135
-
135
+
136
136
  # Returns true if there are no elements in the list. Redis: LLEN == 0
137
137
  def empty?
138
138
  length == 0
139
139
  end
140
-
140
+
141
141
  def ==(x)
142
142
  values == x
143
143
  end
144
-
144
+
145
145
  def to_s
146
146
  values.join(', ')
147
147
  end
data/lib/redis/objects.rb CHANGED
@@ -109,19 +109,24 @@ class Redis
109
109
  downcase
110
110
  end
111
111
 
112
- def redis_field_key(name, id=nil) #:nodoc:
112
+ def redis_field_key(name, id=nil, context=self) #:nodoc:
113
113
  klass = first_ancestor_with(name)
114
114
  # READ THIS: This can never ever ever ever change or upgrades will corrupt all data
115
115
  # I don't think people were using Proc as keys before (that would create a weird key). Should be ok
116
- key = klass.redis_objects[name.to_sym][:key]
117
- if key && key.respond_to?(:call)
118
- key = key.call self
119
- end
120
- if id.nil? and !klass.redis_objects[name.to_sym][:global]
121
- raise NilObjectId,
122
- "[#{klass.redis_objects[name.to_sym]}] Attempt to address redis-object :#{name} on class #{klass.name} with nil id (unsaved record?) [object_id=#{object_id}]"
116
+ if key = klass.redis_objects[name.to_sym][:key]
117
+ if key.respond_to?(:call)
118
+ key = key.call context
119
+ else
120
+ context.instance_eval "%(#{key})"
121
+ end
122
+ else
123
+ if id.nil? and !klass.redis_objects[name.to_sym][:global]
124
+ raise NilObjectId,
125
+ "[#{klass.redis_objects[name.to_sym]}] Attempt to address redis-object " +
126
+ ":#{name} on class #{klass.name} with nil id (unsaved record?) [object_id=#{object_id}]"
127
+ end
128
+ "#{redis_prefix(klass)}:#{id}:#{name}"
123
129
  end
124
- key || "#{redis_prefix(klass)}:#{id}:#{name}"
125
130
  end
126
131
 
127
132
  def first_ancestor_with(name)
@@ -131,27 +136,20 @@ class Redis
131
136
  superclass.first_ancestor_with(name)
132
137
  end
133
138
  end
139
+
140
+ def redis_id_field(id=nil)
141
+ @redis_id_field = id || @redis_id_field || :id
142
+ end
134
143
  end
135
144
 
136
145
  # Instance methods that appear in your class when you include Redis::Objects.
137
146
  module InstanceMethods
138
- def redis() self.class.redis end
147
+ # Map up one level to make modular extend/include approach sane
148
+ def redis() self.class.redis end
149
+ def redis_objects() self.class.redis_objects end
150
+
139
151
  def redis_field_key(name) #:nodoc:
140
- klass = self.class.first_ancestor_with(name)
141
- if key = klass.redis_objects[name.to_sym][:key]
142
- if key.respond_to?(:call)
143
- key.call self
144
- else
145
- eval "%(#{key})"
146
- end
147
- else
148
- if id.nil? and !klass.redis_objects[name.to_sym][:global]
149
- raise NilObjectId,
150
- "Attempt to address redis-object :#{name} on class #{klass.name} with nil id (unsaved record?) [object_id=#{object_id}]"
151
- end
152
- # don't try to refactor into class redis_field_key because fucks up eval context
153
- "#{klass.redis_prefix}:#{id}:#{name}"
154
- end
152
+ self.class.redis_field_key(name, send(self.class.redis_id_field), self)
155
153
  end
156
154
  end
157
155
  end
@@ -23,24 +23,27 @@ class Redis
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
- klass_name = '::' + self.name
26
+
27
+ mod = Module.new do
28
+ define_method(name) do
29
+ instance_variable_get("@#{name}") or
30
+ instance_variable_set("@#{name}",
31
+ Redis::Counter.new(
32
+ redis_field_key(name), redis, redis_objects[name.to_sym]
33
+ )
34
+ )
35
+ end
36
+ end
37
+
27
38
  if options[:global]
28
- instance_eval <<-EndMethods
29
- def #{name}
30
- @#{name} ||= Redis::Counter.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
31
- end
32
- EndMethods
33
- class_eval <<-EndMethods
34
- def #{name}
35
- self.class.#{name}
36
- end
37
- EndMethods
39
+ extend mod
40
+
41
+ # dispatch to class methods
42
+ define_method(name) do
43
+ self.class.public_send(name)
44
+ end
38
45
  else
39
- class_eval <<-EndMethods
40
- def #{name}
41
- @#{name} ||= Redis::Counter.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
42
- end
43
- EndMethods
46
+ include mod
44
47
  end
45
48
  end
46
49
 
@@ -15,24 +15,27 @@ class Redis
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
- klass_name = '::' + self.name
18
+
19
+ mod = Module.new do
20
+ define_method(name) do
21
+ instance_variable_get("@#{name}") or
22
+ instance_variable_set("@#{name}",
23
+ Redis::HashKey.new(
24
+ redis_field_key(name), redis, redis_objects[name.to_sym]
25
+ )
26
+ )
27
+ end
28
+ end
29
+
19
30
  if options[:global]
20
- instance_eval <<-EndMethods
21
- def #{name}
22
- @#{name} ||= Redis::HashKey.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
23
- end
24
- EndMethods
25
- class_eval <<-EndMethods
26
- def #{name}
27
- self.class.#{name}
28
- end
29
- EndMethods
31
+ extend mod
32
+
33
+ # dispatch to class methods
34
+ define_method(name) do
35
+ self.class.public_send(name)
36
+ end
30
37
  else
31
- class_eval <<-EndMethods
32
- def #{name}
33
- @#{name} ||= Redis::HashKey.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
34
- end
35
- EndMethods
38
+ include mod
36
39
  end
37
40
  end
38
41
  end
@@ -15,24 +15,27 @@ class Redis
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
- klass_name = '::' + self.name
18
+
19
+ mod = Module.new do
20
+ define_method(name) do
21
+ instance_variable_get("@#{name}") or
22
+ instance_variable_set("@#{name}",
23
+ Redis::List.new(
24
+ redis_field_key(name), redis, redis_objects[name.to_sym]
25
+ )
26
+ )
27
+ end
28
+ end
29
+
19
30
  if options[:global]
20
- instance_eval <<-EndMethods
21
- def #{name}
22
- @#{name} ||= Redis::List.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
23
- end
24
- EndMethods
25
- class_eval <<-EndMethods
26
- def #{name}
27
- self.class.#{name}
28
- end
29
- EndMethods
31
+ extend mod
32
+
33
+ # dispatch to class methods
34
+ define_method(name) do
35
+ self.class.public_send(name)
36
+ end
30
37
  else
31
- class_eval <<-EndMethods
32
- def #{name}
33
- @#{name} ||= Redis::List.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
34
- end
35
- EndMethods
38
+ include mod
36
39
  end
37
40
  end
38
41
  end
@@ -18,24 +18,27 @@ class Redis
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
- klass_name = '::' + self.name
21
+
22
+ mod = Module.new do
23
+ define_method(lock_name) do |&block|
24
+ instance_variable_get("@#{lock_name}") or
25
+ instance_variable_set("@#{lock_name}",
26
+ Redis::Lock.new(
27
+ redis_field_key(lock_name), redis, redis_objects[lock_name.to_sym]
28
+ )
29
+ )
30
+ end
31
+ end
32
+
22
33
  if options[:global]
23
- instance_eval <<-EndMethods
24
- def #{lock_name}(&block)
25
- @#{lock_name} ||= Redis::Lock.new(redis_field_key(:#{lock_name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{lock_name}])
26
- end
27
- EndMethods
28
- class_eval <<-EndMethods
29
- def #{lock_name}(&block)
30
- self.class.#{lock_name}(block)
31
- end
32
- EndMethods
34
+ extend mod
35
+
36
+ # dispatch to class methods
37
+ define_method(lock_name) do |&block|
38
+ self.class.public_send(lock_name, &block)
39
+ end
33
40
  else
34
- class_eval <<-EndMethods
35
- def #{lock_name}(&block)
36
- @#{lock_name} ||= Redis::Lock.new(redis_field_key(:#{lock_name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{lock_name}])
37
- end
38
- EndMethods
41
+ include mod
39
42
  end
40
43
  end
41
44
 
@@ -15,26 +15,28 @@ class Redis
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
- klass_name = '::' + self.name
18
+
19
+ mod = Module.new do
20
+ define_method(name) do
21
+ instance_variable_get("@#{name}") or
22
+ instance_variable_set("@#{name}",
23
+ Redis::Set.new(
24
+ redis_field_key(name), redis, redis_objects[name.to_sym]
25
+ )
26
+ )
27
+ end
28
+ end
29
+
19
30
  if options[:global]
20
- instance_eval <<-EndMethods
21
- def #{name}
22
- @#{name} ||= Redis::Set.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
23
- end
24
- EndMethods
25
- class_eval <<-EndMethods
26
- def #{name}
27
- self.class.#{name}
28
- end
29
- EndMethods
31
+ extend mod
32
+
33
+ # dispatch to class methods
34
+ define_method(name) do
35
+ self.class.public_send(name)
36
+ end
30
37
  else
31
- class_eval <<-EndMethods
32
- def #{name}
33
- @#{name} ||= Redis::Set.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
34
- end
35
- EndMethods
38
+ include mod
36
39
  end
37
-
38
40
  end
39
41
  end
40
42
 
@@ -15,24 +15,27 @@ class Redis
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
- klass_name = '::' + self.name
18
+
19
+ mod = Module.new do
20
+ define_method(name) do
21
+ instance_variable_get("@#{name}") or
22
+ instance_variable_set("@#{name}",
23
+ Redis::SortedSet.new(
24
+ redis_field_key(name), redis, redis_objects[name.to_sym]
25
+ )
26
+ )
27
+ end
28
+ end
29
+
19
30
  if options[:global]
20
- instance_eval <<-EndMethods
21
- def #{name}
22
- @#{name} ||= Redis::SortedSet.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
23
- end
24
- EndMethods
25
- class_eval <<-EndMethods
26
- def #{name}
27
- self.class.#{name}
28
- end
29
- EndMethods
31
+ extend mod
32
+
33
+ # dispatch to class methods
34
+ define_method(name) do
35
+ self.class.public_send(name)
36
+ end
30
37
  else
31
- class_eval <<-EndMethods
32
- def #{name}
33
- @#{name} ||= Redis::SortedSet.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
34
- end
35
- EndMethods
38
+ include mod
36
39
  end
37
40
  end
38
41
  end
@@ -15,35 +15,34 @@ class Redis
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
- klass_name = '::' + self.name
18
+
19
+ mod = Module.new do
20
+ define_method(name) do
21
+ instance_variable_get("@#{name}") or
22
+ instance_variable_set("@#{name}",
23
+ Redis::Value.new(
24
+ redis_field_key(name), redis, redis_objects[name.to_sym]
25
+ )
26
+ )
27
+ end
28
+ define_method("#{name}=") do |value|
29
+ public_send(name).value = value
30
+ end
31
+ end
32
+
19
33
  if options[:global]
20
- instance_eval <<-EndMethods
21
- def #{name}
22
- @#{name} ||= Redis::Value.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
23
- end
24
- def #{name}=(value)
25
- #{name}.value = value
26
- end
27
- EndMethods
28
- class_eval <<-EndMethods
29
- def #{name}
30
- self.class.#{name}
31
- end
32
- def #{name}=(value)
33
- self.class.#{name} = value
34
- end
35
- EndMethods
34
+ extend mod
35
+
36
+ # dispatch to class methods
37
+ define_method(name) do
38
+ self.class.public_send(name)
39
+ end
40
+ define_method("#{name}=") do |value|
41
+ self.class.public_send("#{name}=", value)
42
+ end
36
43
  else
37
- class_eval <<-EndMethods
38
- def #{name}
39
- @#{name} ||= Redis::Value.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
40
- end
41
- def #{name}=(value)
42
- #{name}.value = value
43
- end
44
- EndMethods
44
+ include mod
45
45
  end
46
-
47
46
  end
48
47
  end
49
48