redpear 0.6.4 → 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.
@@ -0,0 +1,147 @@
1
+ class Redpear::Store::Set < Redpear::Store::Enumerable
2
+ include Enumerable
3
+
4
+ # @yield over a field-value pair
5
+ # @yieldparam [String] field
6
+ # @yieldparam [String] value
7
+ def each(&block)
8
+ members.each(&block)
9
+ end
10
+
11
+ # @return [Set] all members
12
+ def all
13
+ members.to_set
14
+ end
15
+ alias_method :to_set, :all
16
+ alias_method :value, :all
17
+
18
+ # @return [Array] the array of members
19
+ def members
20
+ conn.smembers(key) || []
21
+ end
22
+ alias_method :to_a, :members
23
+
24
+ # @return [Integer] the number of items in the set
25
+ def length
26
+ conn.scard key
27
+ end
28
+ alias_method :size, :length
29
+
30
+ # Adds a single value. Chainable example:
31
+ # set << 'a' << 'b'
32
+ # @param [String] value
33
+ # A value to add
34
+ def add(value)
35
+ conn.sadd key, value
36
+ self
37
+ end
38
+ alias_method :<<, :add
39
+
40
+ # @param [String] value
41
+ # A value to delete
42
+ def delete(value)
43
+ conn.srem key, value
44
+ end
45
+ alias_method :remove, :delete
46
+
47
+ # @return [Boolean] true, if value is included
48
+ def include?(value)
49
+ !!conn.sismember(key, value)
50
+ end
51
+ alias_method :member?, :include?
52
+
53
+ # @return [Boolean] true, if empty
54
+ def empty?
55
+ length.zero?
56
+ end
57
+
58
+ # Removes a random value
59
+ # @return [String] the removed value
60
+ def pop
61
+ conn.spop key
62
+ end
63
+
64
+ # Subtracts values using other sets
65
+ # @param [multiple] others
66
+ # The other sets
67
+ # @return [Array] remaining values
68
+ def diff(*others)
69
+ conn.sdiff key, *others.map(&:to_s)
70
+ end
71
+ alias_method :-, :diff
72
+
73
+ # Store the result of a diff in a new +target+ key
74
+ # @param [String] target
75
+ # The target key
76
+ # @param [multiple] others
77
+ # The other sets
78
+ # @return [Redpear::Store::Set] the result set
79
+ def diffstore(target, *others)
80
+ conn.sdiffstore target.to_s, key, *others.map(&:to_s)
81
+ self.class.new target.to_s, conn
82
+ end
83
+
84
+ # Merges values of two sets
85
+ # @param [multiple] others
86
+ # The other sets
87
+ # @return [Array] union
88
+ def union(*others)
89
+ conn.sunion key, *others.map(&:to_s)
90
+ end
91
+ alias_method :+, :union
92
+ alias_method :|, :union
93
+ alias_method :merge, :union
94
+
95
+ # Store the result of a union in a new +target+ key
96
+ # @param [Redpear::Store::Set] other
97
+ # The other set
98
+ # @param [multiple] others
99
+ # The other sets
100
+ # @return [Redpear::Store::Set] the result set
101
+ def unionstore(target, *others)
102
+ conn.sunionstore target.to_s, key, *others.map(&:to_s)
103
+ self.class.new target.to_s, conn
104
+ end
105
+
106
+ # @param [multiple] other
107
+ # The other sets
108
+ # @return [Array] the intersection +other+ set
109
+ def inter(*others)
110
+ conn.sinter key, *others.map(&:to_s)
111
+ end
112
+ alias_method :intersect, :inter
113
+ alias_method :inter, :inter
114
+ alias_method :&, :inter
115
+
116
+ # Store the result of an intersection in a new +target+ key
117
+ # @param [String] target
118
+ # The target key
119
+ # @param [multiple] others
120
+ # The other sets
121
+ # @return [Redpear::Store::Set] the result set
122
+ def interstore(target, *others)
123
+ conn.sinterstore target.to_s, key, *others.map(&:to_s)
124
+ self.class.new target.to_s, conn
125
+ end
126
+
127
+ # @return [String] a random member
128
+ def random
129
+ conn.srandmember key
130
+ end
131
+
132
+ # Comparator
133
+ # @return [Boolean] true if contains same members as other
134
+ def ==(other)
135
+ other.respond_to?(:to_set) && other.to_set == to_set
136
+ end
137
+
138
+ # Move a value to +target+ set
139
+ # @param [String] target
140
+ # The key of the target set
141
+ # @param [String] value
142
+ # The value to move
143
+ def move(target, value)
144
+ conn.smove key, target.to_s, value
145
+ end
146
+
147
+ end
@@ -0,0 +1,239 @@
1
+ class Redpear::Store::SortedSet < Redpear::Store::Enumerable
2
+ include Enumerable
3
+
4
+ # @yield over a field-score pair
5
+ # @yieldparam [String] field
6
+ # @yieldparam [String] score
7
+ def each(&block)
8
+ all.each(&block)
9
+ end
10
+
11
+ # @param [Hash] options
12
+ # @option [Boolean] with_scores
13
+ # Return with scores, defaults to true
14
+ # @return [Array] all elements
15
+ def all(options = {})
16
+ slice(0..-1, options)
17
+ end
18
+ alias_method :to_a, :all
19
+
20
+ # @return [Integer] the number of items in the set
21
+ def length
22
+ conn.zcard key
23
+ end
24
+ alias_method :size, :length
25
+
26
+ # @param [Range] range
27
+ # @return [Integer] the number of items within given score `range`
28
+ def count(range)
29
+ conn.zcount key, *range_pair(range)
30
+ end
31
+
32
+ # Adds a single member.
33
+ # @param [String] member
34
+ # A member to add
35
+ # @param [Integer] score
36
+ # The score
37
+ def add(member, score)
38
+ conn.zadd key, score, member
39
+ self
40
+ end
41
+ alias_method :[]=, :add
42
+
43
+ # Determines the score of a member
44
+ # @param [String] member
45
+ # @return [Integer] the score for the given `member`
46
+ def score(member)
47
+ number = conn.zscore(key, member)
48
+ number.to_f if number
49
+ end
50
+ alias_method :[], :score
51
+
52
+ # Determines the index of a member (based on ascending scores)
53
+ # @param [String] member
54
+ # @return [Integer] the index for the given `member`
55
+ def index(member)
56
+ number = conn.zrank(key, member)
57
+ number.to_i if number
58
+ end
59
+ alias_method :rank, :index
60
+
61
+ # Determines the reverse index of a member (based on descending scores)
62
+ # @param [String] member
63
+ # @return [Integer] the index for the given `member`
64
+ def rindex(member)
65
+ number = conn.zrevrank(key, member)
66
+ number.to_i if number
67
+ end
68
+ alias_method :rrank, :rindex
69
+
70
+ # @param [String] member
71
+ # The `member` to delete
72
+ def delete(member)
73
+ conn.zrem key, member
74
+ end
75
+
76
+ # @return [Boolean] true, if member is included
77
+ def include?(member)
78
+ !!conn.zscore(key, member)
79
+ end
80
+ alias_method :member?, :include?
81
+
82
+ # @return [Boolean] true, if empty
83
+ def empty?
84
+ length.zero?
85
+ end
86
+
87
+ # Returns a slice of members between index +range+, with the lower index returned first
88
+ # @param [Range] range
89
+ # The index range of the elements
90
+ # @param [Hash] options
91
+ # @option [Boolean] with_scores
92
+ # Return with scores, defaults to true
93
+ # @return [Array] the members
94
+ def slice(range, options = {})
95
+ start, finish = range_pair(range)
96
+ fetch_range :zrange, start, finish, options
97
+ end
98
+ alias_method :top, :slice
99
+
100
+ # Returns a slice of members between rindex +range+, with the higher index returned first
101
+ # @param [Range] range
102
+ # The rindex range of the elements
103
+ # @param [Hash] options
104
+ # @option [Boolean] with_scores
105
+ # Return with scores, defaults to true
106
+ # @return [Array] the members
107
+ def rslice(range, options = {})
108
+ start, finish = range_pair(range)
109
+ fetch_range :zrevrange, start, finish, options
110
+ end
111
+ alias_method :bottom, :rslice
112
+
113
+ # Selects members between a score +range+. Lower scores returned first
114
+ # @param [Range] range
115
+ # The score range of the elements
116
+ # @param [Hash] options
117
+ # @option [Boolean] with_scores
118
+ # Return with scores, defaults to true
119
+ # @option [Integer] limit
120
+ # Limit the results
121
+ # @return [Array] the members
122
+ def select(range, options = {})
123
+ start, finish = range_pair(range)
124
+ fetch_range :zrangebyscore, start, finish, options
125
+ end
126
+
127
+ # Selects members between a score +range+. Higher scores returned first
128
+ # @param [Range] range
129
+ # The score range of the elements
130
+ # @param [Hash] options
131
+ # @option [Boolean] with_scores
132
+ # Return with scores, defaults to true
133
+ # @option [Integer] limit
134
+ # Limit the results
135
+ # @return [Array] the members
136
+ def rselect(range, options = {})
137
+ start, finish = range_pair(range)
138
+ fetch_range :zrevrangebyscore, finish, start, options
139
+ end
140
+
141
+ # Comparator
142
+ # @return [Boolean] true if contains same members as other
143
+ def ==(other)
144
+ other.respond_to?(:to_a) && other.to_a == to_a
145
+ end
146
+
147
+ # @param [Integer] index
148
+ # @param [Hash] options
149
+ # @option [Boolean] with_scores
150
+ # Return with scores, defaults to true
151
+ # @return [Array] member + score for given `index`.
152
+ def at(index, options = {})
153
+ slice(index..index, options).first
154
+ end
155
+
156
+ # @return [String] member with the lowest index
157
+ def first(count = 0)
158
+ if count > 0
159
+ slice(0..(count-1), :with_scores => false)
160
+ else
161
+ at(0, :with_scores => false)
162
+ end
163
+ end
164
+
165
+ # @return [String] member with the highest index
166
+ def last(count = 0)
167
+ if count > 0
168
+ slice(-count..-1, :with_scores => false)
169
+ else
170
+ at(-1, :with_scores => false)
171
+ end
172
+ end
173
+
174
+ # @return [Float] the lowest score
175
+ def minimum
176
+ _, score = at(0); score
177
+ end
178
+
179
+ # @return [Float] the higest score
180
+ def maximum
181
+ _, score = at(-1); score
182
+ end
183
+
184
+ # Store the result of a union in a new +target+ key
185
+ # @param [Redpear::Store::Set] other
186
+ # The other set
187
+ # @param [multiple] others
188
+ # The other sets
189
+ # @param [Hash] options
190
+ # @option [Array] weights
191
+ # @option [Symbol] aggregate
192
+ # @return [Redpear::Store::Set] the result set
193
+ def unionstore(target, *others)
194
+ opts = others.last.is_a?(Hash) ? others.pop : {}
195
+ conn.zunionstore target.to_s, [key] + others.map(&:to_s), opts
196
+ self.class.new target.to_s, conn
197
+ end
198
+
199
+ # Store the result of an intersection in a new +target+ key
200
+ # @param [String] target
201
+ # The target key
202
+ # @param [multiple] others
203
+ # The other sets
204
+ # @param [Hash] options
205
+ # @option [Array] weights
206
+ # @option [Symbol] aggregate
207
+ # @return [Redpear::Store::SortedSet] the result set
208
+ def interstore(target, *others)
209
+ opts = others.last.is_a?(Hash) ? others.pop : {}
210
+ conn.zinterstore target.to_s, [key] + others.map(&:to_s), opts
211
+ self.class.new target.to_s, conn
212
+ end
213
+
214
+ # @param [String] member
215
+ # The member to increment
216
+ # @param [Integer] by
217
+ # The increment, defaults to 1
218
+ def increment(member, by = 1)
219
+ conn.zincrby(key, by, member).to_f
220
+ end
221
+
222
+ # @param [String] member
223
+ # The member to decrement
224
+ # @param [Integer] by
225
+ # The decrement, defaults to 1
226
+ def decrement(member, by = 1)
227
+ increment member, -by
228
+ end
229
+
230
+ private
231
+
232
+ def fetch_range(method, start, finish, options = {})
233
+ options[:limit] = [options[:offset] || 0, options[:limit]] if options[:offset] || options[:limit]
234
+ options[:with_scores] = true unless options.key?(:with_scores)
235
+ result = conn.send method, key, start, finish, options
236
+ options[:with_scores] ? result.each_slice(2).map {|m,s| [m, s.to_f] } : result
237
+ end
238
+
239
+ end
@@ -0,0 +1,66 @@
1
+ class Redpear::Store::Value < Redpear::Store::Base
2
+
3
+ # Deletes the value
4
+ # @see Redpear::Store::Base#purge!
5
+ alias_method :delete, :purge!
6
+
7
+ # @return [String] the value
8
+ def get
9
+ conn.get(key)
10
+ end
11
+
12
+ # @see #get
13
+ def value
14
+ get
15
+ end
16
+
17
+ # Sets the value
18
+ # @param [String] the value to set
19
+ def set(value)
20
+ conn.set(key, value)
21
+ end
22
+
23
+ # @see #set
24
+ def value=(*a)
25
+ set(*a)
26
+ end
27
+
28
+ # @see #set
29
+ def replace(*a)
30
+ set(*a)
31
+ end
32
+
33
+ # Appends a `value`
34
+ # @param [Integer] value
35
+ # The value to append
36
+ def append(value)
37
+ conn.append(key, value)
38
+ self
39
+ end
40
+ alias_method :<<, :append
41
+
42
+ # Comparator
43
+ # @param [String] other
44
+ # @return [Boolean] true, if equals `other`
45
+ def ==(other)
46
+ value == other
47
+ end
48
+
49
+ # @return [Boolean] true, if value is nil
50
+ def nil?
51
+ value.nil?
52
+ end
53
+
54
+ # @return [Boolean] true, if responds to `method`
55
+ def respond_to?(method, *a)
56
+ super || (value || "").respond_to?(method, *a)
57
+ end
58
+
59
+ protected
60
+
61
+ def method_missing(method, *a, &b)
62
+ base = (value || "")
63
+ base.respond_to?(method) ? base.send(method, *a, &b) : super
64
+ end
65
+
66
+ end
@@ -0,0 +1,11 @@
1
+ module Redpear::Store
2
+ autoload :Base, 'redpear/store/base'
3
+ autoload :Counter, 'redpear/store/counter'
4
+ autoload :Enumerable, 'redpear/store/enumerable'
5
+ autoload :Hash, 'redpear/store/hash'
6
+ autoload :List, 'redpear/store/list'
7
+ autoload :Lock, 'redpear/store/lock'
8
+ autoload :Set, 'redpear/store/set'
9
+ autoload :SortedSet, 'redpear/store/sorted_set'
10
+ autoload :Value, 'redpear/store/value'
11
+ end
data/lib/redpear.rb CHANGED
@@ -1,27 +1,12 @@
1
1
  require "redis"
2
2
  require "date"
3
+ require "set"
4
+ require "securerandom"
3
5
 
4
6
  module Redpear
5
-
6
- def self.autoload(const, path = nil)
7
- path ||= "redpear/#{const.to_s.downcase}"
8
- super const, path
9
- end
10
-
11
- autoload :Column
12
- autoload :Concern
13
- autoload :Connection
14
- autoload :Counters
15
- autoload :Expiration
16
- autoload :Finders
17
- autoload :Index
18
- autoload :Members
19
- autoload :Model
20
- autoload :Namespace
21
- autoload :Nest
22
- autoload :Persistence
23
- autoload :Schema
24
- autoload :ZIndex
25
- autoload :ZMembers
26
-
7
+ autoload :Concern, "redpear/concern"
8
+ autoload :Connection, "redpear/connection"
9
+ autoload :Model, "redpear/model"
10
+ autoload :Schema, "redpear/schema"
11
+ autoload :Store, "redpear/store"
27
12
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redpear
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 0.7.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-06 00:00:00.000000000Z
12
+ date: 2012-01-31 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
16
- requirement: &27432700 !ruby/object:Gem::Requirement
16
+ requirement: &22040360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.2.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *27432700
24
+ version_requirements: *22040360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &27432320 !ruby/object:Gem::Requirement
27
+ requirement: &22039760 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *27432320
35
+ version_requirements: *22039760
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bundler
38
- requirement: &27431860 !ruby/object:Gem::Requirement
38
+ requirement: &22038240 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *27431860
46
+ version_requirements: *22038240
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &27461340 !ruby/object:Gem::Requirement
49
+ requirement: &22036720 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *27461340
57
+ version_requirements: *22036720
58
58
  - !ruby/object:Gem::Dependency
59
- name: fakeredis
60
- requirement: &27460920 !ruby/object:Gem::Requirement
59
+ name: shoulda-matchers
60
+ requirement: &22035080 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,21 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *27460920
68
+ version_requirements: *22035080
69
69
  - !ruby/object:Gem::Dependency
70
- name: shoulda-matchers
71
- requirement: &27460500 !ruby/object:Gem::Requirement
70
+ name: machinist
71
+ requirement: &22033100 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *22033100
80
+ - !ruby/object:Gem::Dependency
81
+ name: factory_girl
82
+ requirement: &22032660 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,7 +87,7 @@ dependencies:
76
87
  version: '0'
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *27460500
90
+ version_requirements: *22032660
80
91
  description: Simple, elegant & efficient ORM for Redis
81
92
  email: dimitrij@blacksquaremedia.com
82
93
  executables: []
@@ -85,23 +96,27 @@ extra_rdoc_files: []
85
96
  files:
86
97
  - lib/redpear.rb
87
98
  - lib/redpear/connection.rb
99
+ - lib/redpear/schema/column.rb
100
+ - lib/redpear/schema/index.rb
88
101
  - lib/redpear/schema/collection.rb
89
- - lib/redpear/core_ext/stringify_keys.rb
102
+ - lib/redpear/schema/score.rb
90
103
  - lib/redpear/concern.rb
91
- - lib/redpear/zmembers.rb
92
- - lib/redpear/namespace.rb
93
- - lib/redpear/nest.rb
94
- - lib/redpear/finders.rb
95
- - lib/redpear/zindex.rb
96
- - lib/redpear/persistence.rb
97
- - lib/redpear/expiration.rb
98
- - lib/redpear/column.rb
104
+ - lib/redpear/store.rb
105
+ - lib/redpear/model/factory_girl.rb
106
+ - lib/redpear/model/finders.rb
107
+ - lib/redpear/model/expiration.rb
108
+ - lib/redpear/model/machinist.rb
109
+ - lib/redpear/store/lock.rb
110
+ - lib/redpear/store/enumerable.rb
111
+ - lib/redpear/store/counter.rb
112
+ - lib/redpear/store/hash.rb
113
+ - lib/redpear/store/base.rb
114
+ - lib/redpear/store/value.rb
115
+ - lib/redpear/store/list.rb
116
+ - lib/redpear/store/set.rb
117
+ - lib/redpear/store/sorted_set.rb
99
118
  - lib/redpear/model.rb
100
- - lib/redpear/index.rb
101
- - lib/redpear/members.rb
102
119
  - lib/redpear/schema.rb
103
- - lib/redpear/counters.rb
104
- - lib/redpear/machinist.rb
105
120
  homepage: https://github.com/bsm/redpear
106
121
  licenses: []
107
122
  post_install_message:
@@ -113,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
128
  requirements:
114
129
  - - ! '>='
115
130
  - !ruby/object:Gem::Version
116
- version: 1.8.7
131
+ version: 1.9.2
117
132
  required_rubygems_version: !ruby/object:Gem::Requirement
118
133
  none: false
119
134
  requirements:
@@ -1,17 +0,0 @@
1
- # Hash stringify_keys extension. "Borrowed" from ActiveSupport.
2
- class Hash
3
-
4
- # Return a new hash with all keys converted to strings.
5
- def stringify_keys
6
- dup.stringify_keys!
7
- end
8
-
9
- # Destructively convert all keys to strings.
10
- def stringify_keys!
11
- keys.each do |key|
12
- self[key.to_s] = delete(key) unless key.is_a?(String)
13
- end
14
- self
15
- end
16
-
17
- end unless Hash.new.respond_to?(:symbolize_keys)
@@ -1,26 +0,0 @@
1
- module Redpear::Counters
2
-
3
- # Increments the value of a counter attribute
4
- # @param [String|Symbol] column
5
- # The column name to increment
6
- # @param [Integer] by
7
- # Increment by this value
8
- def increment!(column, by = 1)
9
- return false unless persisted?
10
-
11
- col = self.class.columns[column]
12
- return false unless col && col.type == :counter
13
-
14
- self[col.name] = nest.hincrby(col.name, by).to_i
15
- end
16
-
17
- # Decrements the value of a counter attribute
18
- # @param [String|Symbol] column
19
- # The column name to decrement
20
- # @param [Integer] by
21
- # Decrement by this value
22
- def decrement!(column, by = 1)
23
- increment!(column, -by)
24
- end
25
-
26
- end