redis-objects 0.2.1 → 0.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.
@@ -0,0 +1,275 @@
1
+ class Redis
2
+ #
3
+ # Class representing a sorted set.
4
+ #
5
+ class SortedSet
6
+ # require 'enumerator'
7
+ # include Enumerable
8
+ require 'redis/helpers/core_commands'
9
+ include Redis::Helpers::CoreCommands
10
+ require 'redis/helpers/serialize'
11
+ include Redis::Helpers::Serialize
12
+
13
+ attr_reader :key, :options, :redis
14
+
15
+ # Create a new SortedSet.
16
+ def initialize(key, *args)
17
+ @key = key
18
+ @options = args.last.is_a?(Hash) ? args.pop : {}
19
+ @redis = args.first || $redis
20
+ end
21
+
22
+ # How to add values using a sorted set. The key is the member, eg,
23
+ # "Peter", and the value is the score, eg, 163. So:
24
+ # num_posts['Peter'] = 163
25
+ def []=(member, score)
26
+ add(member, score)
27
+ end
28
+
29
+ # Add a member and its corresponding value to Redis. Note that the
30
+ # arguments to this are flipped; the member comes first rather than
31
+ # the score, since the member is the unique item (not the score).
32
+ def add(member, score)
33
+ redis.zadd(key, score, to_redis(member))
34
+ end
35
+
36
+ # Same functionality as Ruby arrays. If a single number is given, return
37
+ # just the element at that index using Redis: ZRANGE. Otherwise, return
38
+ # a range of values using Redis: ZRANGE.
39
+ def [](index, length=nil)
40
+ if index.is_a? Range
41
+ range(index.first, index.last)
42
+ elsif length
43
+ range(index, length)
44
+ else
45
+ score(index)
46
+ end
47
+ end
48
+
49
+ # Return the score of the specified element of the sorted set at key. If the
50
+ # specified element does not exist in the sorted set, or the key does not exist
51
+ # at all, nil is returned. Redis: ZSCORE.
52
+ def score(member)
53
+ redis.zscore(key, to_redis(member)).to_i
54
+ end
55
+
56
+ # Return the rank of the member in the sorted set, with scores ordered from
57
+ # low to high. +revrank+ returns the rank with scores ordered from high to low.
58
+ # When the given member does not exist in the sorted set, nil is returned.
59
+ # The returned rank (or index) of the member is 0-based for both commands
60
+ def rank(member)
61
+ redis.zrank(key, to_redis(member)).to_i
62
+ end
63
+
64
+ def revrank(member)
65
+ redis.zrevrank(key, to_redis(member)).to_i
66
+ end
67
+
68
+ # Return all members of the sorted set with their scores. Extremely CPU-intensive.
69
+ # Better to use a range instead.
70
+ def members(options={})
71
+ range(0, -1, options)
72
+ end
73
+
74
+ # Return a range of values from +start_index+ to +end_index+. Can also use
75
+ # the familiar list[start,end] Ruby syntax. Redis: ZRANGE
76
+ def range(start_index, end_index, options={})
77
+ if options[:withscores]
78
+ val = from_redis redis.zrange(key, start_index, end_index, 'withscores')
79
+ ret = []
80
+ while k = val.shift and v = val.shift
81
+ ret << [k, v.to_i]
82
+ end
83
+ ret
84
+ else
85
+ from_redis redis.zrange(key, start_index, end_index)
86
+ end
87
+ end
88
+
89
+ # Return a range of values from +start_index+ to +end_index+ in reverse order. Redis: ZREVRANGE
90
+ def revrange(start_index, end_index, options={})
91
+ if options[:withscores]
92
+ val = from_redis redis.zrevrange(key, start_index, end_index, 'withscores')
93
+ ret = []
94
+ while k = val.shift and v = val.shift
95
+ ret << [k, v.to_i]
96
+ end
97
+ ret
98
+ else
99
+ from_redis redis.zrevrange(key, start_index, end_index)
100
+ end
101
+ end
102
+
103
+ # Return the all the elements in the sorted set at key with a score between min and max
104
+ # (including elements with score equal to min or max). Options:
105
+ # :count, :offset - passed to LIMIT
106
+ # :withscores - if true, scores are returned as well
107
+ # Redis: ZRANGEBYSCORE
108
+ def rangebyscore(min, max, options={})
109
+ args = []
110
+ args += ['limit', options[:offset] || 0, options[:limit] || options[:count]] if
111
+ options[:offset] || options[:limit] || options[:count]
112
+ args += ['withscores'] if options[:withscores]
113
+ from_redis redis.zrangebyscore(key, min, max, *args)
114
+ end
115
+
116
+ # Forwards compat (not yet implemented in Redis)
117
+ def revrangebyscore(min, max, options={})
118
+ args = []
119
+ args += ['limit', options[:offset] || 0, options[:limit] || options[:count]] if
120
+ options[:offset] || options[:limit] || options[:count]
121
+ args += ['withscores'] if options[:withscores]
122
+ from_redis redis.zrevrangebyscore(key, min, max, *args)
123
+ end
124
+
125
+ # Remove all elements in the sorted set at key with rank between start and end. Start and end are
126
+ # 0-based with rank 0 being the element with the lowest score. Both start and end can be negative
127
+ # numbers, where they indicate offsets starting at the element with the highest rank. For example:
128
+ # -1 is the element with the highest score, -2 the element with the second highest score and so forth.
129
+ # Redis: ZREMRANGEBYRANK
130
+ def remrangebyrank(min, max)
131
+ redis.zremrangebyrank(key, min, max)
132
+ end
133
+
134
+ # Remove all the elements in the sorted set at key with a score between min and max (including
135
+ # elements with score equal to min or max). Redis: ZREMRANGEBYSCORE
136
+ def remrangebyscore(min, max)
137
+ redis.zremrangebyscore(key, min, max)
138
+ end
139
+
140
+ # Delete the value from the set. Redis: ZREM
141
+ def delete(value)
142
+ redis.zrem(key, value)
143
+ end
144
+
145
+ # Increment the rank of that member atomically and return the new value. This
146
+ # method is aliased as incr() for brevity. Redis: ZINCRBY
147
+ def increment(member, by=1)
148
+ redis.zincrby(key, by, member).to_i
149
+ end
150
+ alias_method :incr, :increment
151
+ alias_method :incrby, :increment
152
+
153
+ # Convenience to calling increment() with a negative number.
154
+ def decrement(by=1)
155
+ redis.zincrby(key, -by).to_i
156
+ end
157
+ alias_method :decr, :decrement
158
+ alias_method :decrby, :decrement
159
+
160
+ # Return the intersection with another set. Can pass it either another set
161
+ # object or set name. Also available as & which is a bit cleaner:
162
+ #
163
+ # members_in_both = set1 & set2
164
+ #
165
+ # If you want to specify multiple sets, you must use +intersection+:
166
+ #
167
+ # members_in_all = set1.intersection(set2, set3, set4)
168
+ # members_in_all = set1.inter(set2, set3, set4) # alias
169
+ #
170
+ # Redis: SINTER
171
+ def intersection(*sets)
172
+ from_redis redis.zinter(key, *keys_from_objects(sets))
173
+ end
174
+ alias_method :intersect, :intersection
175
+ alias_method :inter, :intersection
176
+ alias_method :&, :intersection
177
+
178
+ # Calculate the intersection and store it in Redis as +name+. Returns the number
179
+ # of elements in the stored intersection. Redis: SUNIONSTORE
180
+ def interstore(name, *sets)
181
+ redis.zinterstore(name, key, *keys_from_objects(sets))
182
+ end
183
+
184
+ # Return the union with another set. Can pass it either another set
185
+ # object or set name. Also available as | and + which are a bit cleaner:
186
+ #
187
+ # members_in_either = set1 | set2
188
+ # members_in_either = set1 + set2
189
+ #
190
+ # If you want to specify multiple sets, you must use +union+:
191
+ #
192
+ # members_in_all = set1.union(set2, set3, set4)
193
+ #
194
+ # Redis: SUNION
195
+ def union(*sets)
196
+ from_redis redis.zunion(key, *keys_from_objects(sets))
197
+ end
198
+ alias_method :|, :union
199
+ alias_method :+, :union
200
+
201
+ # Calculate the union and store it in Redis as +name+. Returns the number
202
+ # of elements in the stored union. Redis: SUNIONSTORE
203
+ def unionstore(name, *sets)
204
+ redis.zunionstore(name, key, *keys_from_objects(sets))
205
+ end
206
+
207
+ # Return the difference vs another set. Can pass it either another set
208
+ # object or set name. Also available as ^ or - which is a bit cleaner:
209
+ #
210
+ # members_difference = set1 ^ set2
211
+ # members_difference = set1 - set2
212
+ #
213
+ # If you want to specify multiple sets, you must use +difference+:
214
+ #
215
+ # members_difference = set1.difference(set2, set3, set4)
216
+ # members_difference = set1.diff(set2, set3, set4)
217
+ #
218
+ # Redis: SDIFF
219
+ def difference(*sets)
220
+ from_redis redis.zdiff(key, *keys_from_objects(sets))
221
+ end
222
+ alias_method :diff, :difference
223
+ alias_method :^, :difference
224
+ alias_method :-, :difference
225
+
226
+ # Calculate the diff and store it in Redis as +name+. Returns the number
227
+ # of elements in the stored union. Redis: SDIFFSTORE
228
+ def diffstore(name, *sets)
229
+ redis.zdiffstore(name, key, *keys_from_objects(sets))
230
+ end
231
+
232
+ # Returns true if the set has no members. Redis: SCARD == 0
233
+ def empty?
234
+ length == 0
235
+ end
236
+
237
+ def ==(x)
238
+ members == x
239
+ end
240
+
241
+ def to_s
242
+ members.join(', ')
243
+ end
244
+
245
+ # Return the value at the given index. Can also use familiar list[index] syntax.
246
+ # Redis: ZRANGE
247
+ def at(index)
248
+ range(index, index).first
249
+ end
250
+
251
+ # Return the first element in the list. Redis: ZRANGE(0)
252
+ def first
253
+ at(0)
254
+ end
255
+
256
+ # Return the last element in the list. Redis: ZRANGE(-1)
257
+ def last
258
+ at(-1)
259
+ end
260
+
261
+ # The number of members in the set. Aliased as size. Redis: ZCARD
262
+ def length
263
+ redis.zcard(key)
264
+ end
265
+ alias_method :size, :length
266
+
267
+ private
268
+
269
+ def keys_from_objects(sets)
270
+ raise ArgumentError, "Must pass in one or more set names" if sets.empty?
271
+ sets.collect{|set| set.is_a?(Redis::SortedSet) ? set.key : set}
272
+ end
273
+
274
+ end
275
+ end
data/lib/redis/value.rb CHANGED
@@ -3,31 +3,29 @@ class Redis
3
3
  # Class representing a simple value. You can use standard Ruby operations on it.
4
4
  #
5
5
  class Value
6
- require 'redis/serialize'
7
- include Redis::Serialize
6
+ require 'redis/helpers/core_commands'
7
+ include Redis::Helpers::CoreCommands
8
+ require 'redis/helpers/serialize'
9
+ include Redis::Helpers::Serialize
8
10
 
9
11
  attr_reader :key, :options, :redis
10
- def initialize(key, redis=$redis, options={})
12
+ def initialize(key, *args)
11
13
  @key = key
12
- @redis = redis
13
- @options = options
14
+ @options = args.last.is_a?(Hash) ? args.pop : {}
15
+ @redis = args.first || $redis
14
16
  @redis.setnx(key, @options[:default]) if @options[:default]
15
17
  end
16
18
 
17
19
  def value=(val)
18
- redis.set(key, to_redis(val))
20
+ redis.set key, to_redis(val)
19
21
  end
20
-
22
+ alias_method :set, :value=
23
+
21
24
  def value
22
25
  from_redis redis.get(key)
23
26
  end
24
27
  alias_method :get, :value
25
28
 
26
- def delete
27
- redis.del(key)
28
- end
29
- alias_method :del, :delete
30
-
31
29
  def to_s; value.to_s; end
32
30
  alias_method :to_str, :to_s
33
31