activeredis 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module ActiveRedis
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/activeredis.rb CHANGED
@@ -37,11 +37,11 @@ module ActiveRedis
37
37
 
38
38
  class ActiveRedisError < StandardError
39
39
  end
40
-
40
+
41
41
  # Raised when Active Redis cannot find record by given id or set of ids.
42
42
  class RecordNotFound < ActiveRedisError
43
43
  end
44
-
44
+
45
45
  class Base
46
46
  include ActiveModel::Validations
47
47
  include ActiveModel::Dirty
@@ -50,7 +50,7 @@ module ActiveRedis
50
50
  include ActiveModel::Naming
51
51
 
52
52
  QUEUED = "QUEUED"
53
-
53
+
54
54
  # RAILSISM
55
55
  # Returns a hash of all the attributes with their names as keys and the values of the attributes as values
56
56
  # --> means: Strings as keys!
@@ -62,16 +62,16 @@ module ActiveRedis
62
62
  attr :frozen
63
63
 
64
64
  class << self; attr_accessor :_fields; end
65
-
65
+
66
66
  # INSTANCE METHODS
67
-
67
+
68
68
  def initialize(attributes = {}, id = nil)
69
69
  @id = id if id
70
70
  @attributes = {}
71
71
  initialize_attributes(attributes)
72
72
  frozen = false
73
73
  end
74
-
74
+
75
75
  # Object's attributes' keys are converted to strings because of railsisms.
76
76
  # Because of activeredisism, also values are converted to strings for consistency.
77
77
  def initialize_attributes(attributes)
@@ -89,26 +89,18 @@ module ActiveRedis
89
89
  def save
90
90
  creation = new_record?
91
91
  @id = self.class.fetch_new_identifier if creation
92
- while true
93
- begin
94
- connection.multi
95
- rescue
96
- sleep(0.1)
97
- redo
92
+ connection.multi do
93
+ if @attributes.size > 0
94
+ @attributes.each_pair { |key, value|
95
+ if key.to_sym == :updated_at
96
+ value = Time.now.to_s
97
+ end
98
+ connection.hset("#{key_namespace}:attributes", key, value)
99
+ }
98
100
  end
99
- break
100
- end
101
- if @attributes.size > 0
102
- @attributes.each_pair { |key, value|
103
- if key.to_sym == :updated_at
104
- value = Time.now.to_s
105
- end
106
- connection.hset("#{key_namespace}:attributes", key, value)
107
- }
101
+ connection.zadd("#{class_namespace}:all", @id, @id)
108
102
  end
109
- connection.zadd("#{class_namespace}:all", @id, @id)
110
- connection.exec
111
- return true
103
+ true
112
104
  end
113
105
 
114
106
  def update_attributes(attributes)
@@ -124,19 +116,19 @@ module ActiveRedis
124
116
  def reload
125
117
  @attributes = connection.hgetall "#{key_namespace}:attributes"
126
118
  end
127
-
119
+
128
120
  def new_record?
129
121
  @id == nil
130
122
  end
131
-
123
+
132
124
  def key_namespace
133
125
  "#{self.class.key_namespace}:#{self.id}"
134
126
  end
135
-
127
+
136
128
  def class_namespace
137
129
  "#{self.class.key_namespace}"
138
130
  end
139
-
131
+
140
132
  def connection
141
133
  self.class.connection
142
134
  end
@@ -147,13 +139,13 @@ module ActiveRedis
147
139
  connection.zrem "#{class_namespace}:all", @id
148
140
  @frozen = true
149
141
  end
150
- return true
142
+ return true
151
143
  end
152
144
 
153
145
  def frozen?
154
146
  @frozen
155
147
  end
156
-
148
+
157
149
  def add_attribute(name, value=nil)
158
150
  initialize_attributes({name => value})
159
151
  end
@@ -161,11 +153,11 @@ module ActiveRedis
161
153
  def [](field)
162
154
  send(field)
163
155
  end
164
-
156
+
165
157
  def []=(field, value)
166
158
  send(field+"=", value)
167
159
  end
168
-
160
+
169
161
  #
170
162
  # CLASS METHODS
171
163
  #
@@ -173,7 +165,7 @@ module ActiveRedis
173
165
  def self.create(attributes)
174
166
  self.new(attributes).save
175
167
  end
176
-
168
+
177
169
  def self.define_field(field)
178
170
  define_method field.to_sym do
179
171
  if field.to_sym == :updated_at
@@ -201,61 +193,41 @@ module ActiveRedis
201
193
  def self.key_namespace
202
194
  "#{self}"
203
195
  end
204
-
196
+
205
197
  def self.fetch_new_identifier
206
198
  self.connection.incr self.identifier_sequencer
207
199
  end
208
-
200
+
209
201
  def self.identifier_sequencer
210
202
  "#{key_namespace}:sequence"
211
203
  end
212
-
204
+
213
205
  def self.inherited(child)
214
206
  #puts "Redis.new(:host => #{ActiveRedis.host}, :port => #{ActiveRedis.port})"
215
207
  @@redis = Redis.new(:host => ActiveRedis.host, :port => ActiveRedis.port)
216
208
  @@class = child
217
209
  end
218
-
210
+
219
211
  def self.redis_information
220
212
  connection.info # call_command [:info]
221
213
  end
222
-
214
+
223
215
  def self.connection
224
216
  @@redis
225
217
  end
226
218
 
227
219
  def self.count
228
- begin
229
- size = connection.zcard "#{key_namespace}:all"
230
- while size == QUEUED
231
- sleep(0.1)
232
- size = connection.zcard "#{key_namespace}:all"
233
- end
234
- return size
235
- rescue RuntimeError => e
236
- return 0
237
- end
220
+ size = connection.zcard "#{key_namespace}:all"
238
221
  end
239
222
 
240
223
  def self.find_all()
241
- record = []
224
+ records = []
242
225
  # TODO Interim fix, "QUEUED" is find(id) rescue
243
- while true
244
- ids = connection.zrange "#{key_namespace}:all", 0, count
245
- while ids == QUEUED
246
- sleep(0.1)
247
- ids = connection.zrange "#{key_namespace}:all", 0, count
248
- end
249
- begin
250
- ids.each do |id|
251
- record << find(id)
252
- end
253
- rescue
254
- redo
255
- end
256
- break
226
+ ids = connection.zrange "#{key_namespace}:all", 0, count
227
+ ids.each do |id|
228
+ records << find(id)
257
229
  end
258
- record
230
+ records
259
231
  end
260
232
 
261
233
  def self.all
@@ -291,11 +263,14 @@ module ActiveRedis
291
263
 
292
264
  def self.find_by_param(field, value)
293
265
  records = find_all_by_param(field, value)
294
- if records.size > 0
295
- return records[0]
296
- else
297
- nil
266
+ ids = connection.zrange "#{key_namespace}:all", 0, count
267
+ ids.each do |id|
268
+ record = find(id)
269
+ if record.attributes[field.to_s] == value.to_s
270
+ return record
271
+ end
298
272
  end
273
+ nil
299
274
  end
300
275
 
301
276
  def self.method_missing(name, *args)
@@ -303,7 +278,7 @@ module ActiveRedis
303
278
  return find_all_by_param($1.to_sym, args[0]) if name.to_s =~ /^find_all_by_(.*)/
304
279
  super
305
280
  end
306
-
281
+
307
282
  def self.delete_unused_field
308
283
  ids = connection.zrange "#{key_namespace}:all", 0, count
309
284
  if ids.size > 0
@@ -0,0 +1,326 @@
1
+ require 'redis'
2
+ require 'time'
3
+ require 'active_model'
4
+
5
+ require 'active_model/version'
6
+
7
+ class Module
8
+ def module_attr_reader(*syms)
9
+ syms.each do |sym|
10
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
11
+ @@#{sym} = nil unless defined?(@@#{sym})
12
+ def self.#{sym}()
13
+ return @@#{sym}
14
+ end
15
+ EOS
16
+ end
17
+ end
18
+ def module_attr_writer(*syms)
19
+ syms.each do |sym|
20
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
21
+ def self.#{sym}=(obj)
22
+ @@#{sym} = obj
23
+ end
24
+ EOS
25
+ end
26
+ end
27
+ def module_attr_accessor(*syms)
28
+ module_attr_reader(*syms)
29
+ module_attr_writer(*syms)
30
+ end
31
+ end
32
+
33
+ module ActiveRedis
34
+ module_attr_accessor :host, :port
35
+ @@host = "localhost"
36
+ @@port = "6379"
37
+
38
+ class ActiveRedisError < StandardError
39
+ end
40
+
41
+ # Raised when Active Redis cannot find record by given id or set of ids.
42
+ class RecordNotFound < ActiveRedisError
43
+ end
44
+
45
+ class Base
46
+ include ActiveModel::Validations
47
+ include ActiveModel::Dirty
48
+ include ActiveModel::Serialization
49
+ include ActiveModel::Serializers::JSON
50
+ include ActiveModel::Naming
51
+
52
+ QUEUED = "QUEUED"
53
+
54
+ # RAILSISM
55
+ # Returns a hash of all the attributes with their names as keys and the values of the attributes as values
56
+ # --> means: Strings as keys!
57
+ # --> initialize stringifies
58
+ #
59
+ # called by to_json for_example
60
+ attr_reader :attributes
61
+ attr_reader :id
62
+ attr :frozen
63
+
64
+ class << self; attr_accessor :_fields; end
65
+
66
+ # INSTANCE METHODS
67
+
68
+ def initialize(attributes = {}, id = nil)
69
+ @id = id if id
70
+ @attributes = {}
71
+ initialize_attributes(attributes)
72
+ frozen = false
73
+ end
74
+
75
+ # Object's attributes' keys are converted to strings because of railsisms.
76
+ # Because of activeredisism, also values are converted to strings for consistency.
77
+ def initialize_attributes(attributes)
78
+ fields = Hash[[self.class._fields, Array.new(self.class._fields.size)].transpose]
79
+ fields.stringify_keys! # NEEDS to be strings for railsisms
80
+ attributes.stringify_keys! # NEEDS to be strings for railsisms
81
+ attributes.each_pair { |key, value| attributes[key] = value.to_s }
82
+ fields.merge!(attributes)
83
+ @attributes.merge!(fields)
84
+ @attributes.each_pair do |key, value|
85
+ self.class.define_field key
86
+ end
87
+ end
88
+
89
+ def save
90
+ creation = new_record?
91
+ @id = self.class.fetch_new_identifier if creation
92
+ while true
93
+ begin
94
+ connection.multi
95
+ rescue
96
+ sleep(0.1)
97
+ redo
98
+ end
99
+ break
100
+ end
101
+ if @attributes.size > 0
102
+ @attributes.each_pair { |key, value|
103
+ if key.to_sym == :updated_at
104
+ value = Time.now.to_s
105
+ end
106
+ connection.hset("#{key_namespace}:attributes", key, value)
107
+ }
108
+ end
109
+ connection.zadd("#{class_namespace}:all", @id, @id)
110
+ connection.exec
111
+ return true
112
+ end
113
+
114
+ def update_attributes(attributes)
115
+ attributes.stringify_keys! # NEEDS to be strings for railsisms
116
+ attributes.each_pair { |key, value| attributes[key] = value.to_s }
117
+ @attributes.merge!(attributes)
118
+ attributes.each_pair do |key, value|
119
+ self.class.define_field key
120
+ end
121
+ save
122
+ end
123
+
124
+ def reload
125
+ @attributes = connection.hgetall "#{key_namespace}:attributes"
126
+ end
127
+
128
+ def new_record?
129
+ @id == nil
130
+ end
131
+
132
+ def key_namespace
133
+ "#{self.class.key_namespace}:#{self.id}"
134
+ end
135
+
136
+ def class_namespace
137
+ "#{self.class.key_namespace}"
138
+ end
139
+
140
+ def connection
141
+ self.class.connection
142
+ end
143
+
144
+ def destroy
145
+ connection.multi do
146
+ connection.del "#{key_namespace}:attributes"
147
+ connection.zrem "#{class_namespace}:all", @id
148
+ @frozen = true
149
+ end
150
+ return true
151
+ end
152
+
153
+ def frozen?
154
+ @frozen
155
+ end
156
+
157
+ def add_attribute(name, value=nil)
158
+ initialize_attributes({name => value})
159
+ end
160
+
161
+ def [](field)
162
+ send(field)
163
+ end
164
+
165
+ def []=(field, value)
166
+ send(field+"=", value)
167
+ end
168
+
169
+ #
170
+ # CLASS METHODS
171
+ #
172
+
173
+ def self.create(attributes)
174
+ self.new(attributes).save
175
+ end
176
+
177
+ def self.define_field(field)
178
+ define_method field.to_sym do
179
+ if field.to_sym == :updated_at
180
+ Time.parse(@attributes["#{field}"])
181
+ else
182
+ @attributes["#{field}"]
183
+ end
184
+ end
185
+
186
+ define_method "#{field}=".to_sym do |new_value|
187
+ @attributes["#{field}"] = new_value.to_s
188
+ end
189
+ end
190
+
191
+ # Run this method to declare the fields of your model.
192
+ def self.fields(*fields)
193
+ self._fields ||= []
194
+ self._fields = fields
195
+ end
196
+
197
+ def self.get_fields
198
+ self._fields
199
+ end
200
+
201
+ def self.key_namespace
202
+ "#{self}"
203
+ end
204
+
205
+ def self.fetch_new_identifier
206
+ self.connection.incr self.identifier_sequencer
207
+ end
208
+
209
+ def self.identifier_sequencer
210
+ "#{key_namespace}:sequence"
211
+ end
212
+
213
+ def self.inherited(child)
214
+ #puts "Redis.new(:host => #{ActiveRedis.host}, :port => #{ActiveRedis.port})"
215
+ @@redis = Redis.new(:host => ActiveRedis.host, :port => ActiveRedis.port)
216
+ @@class = child
217
+ end
218
+
219
+ def self.redis_information
220
+ connection.info # call_command [:info]
221
+ end
222
+
223
+ def self.connection
224
+ @@redis
225
+ end
226
+
227
+ def self.count
228
+ begin
229
+ size = connection.zcard "#{key_namespace}:all"
230
+ while size == QUEUED
231
+ sleep(0.1)
232
+ size = connection.zcard "#{key_namespace}:all"
233
+ end
234
+ return size
235
+ rescue RuntimeError => e
236
+ return 0
237
+ end
238
+ end
239
+
240
+ def self.find_all()
241
+ record = []
242
+ # TODO Interim fix, "QUEUED" is find(id) rescue
243
+ while true
244
+ ids = nil
245
+ while true
246
+ ids = connection.zrange "#{key_namespace}:all", 0, count
247
+ break if ids != QUEUED
248
+ sleep(0.1)
249
+ end
250
+ begin
251
+ ids.each do |id|
252
+ record << find(id)
253
+ end
254
+ rescue
255
+ redo
256
+ end
257
+ break
258
+ end
259
+ record
260
+ end
261
+
262
+ def self.all
263
+ find_all
264
+ end
265
+
266
+ def self.delete_all
267
+ records = find_all
268
+ records.each do |record|
269
+ record.destroy
270
+ end
271
+ end
272
+
273
+ def self.find(id)
274
+ return find_all if id == :all
275
+ exists = connection.zscore "#{key_namespace}:all", id
276
+ raise RecordNotFound.new("Couldn't find #{self.name} with ID=#{id}") unless exists
277
+ attributes = connection.hgetall "#{key_namespace}:#{id}:attributes"
278
+ obj = self.new attributes, id
279
+ return obj
280
+ end
281
+
282
+ def self.find_all_by_param(field, value)
283
+ finded = []
284
+ records = find_all
285
+ records.each do |record|
286
+ if record.attributes[field.to_s] == value.to_s
287
+ finded << record
288
+ end
289
+ end
290
+ return finded
291
+ end
292
+
293
+ def self.find_by_param(field, value)
294
+ records = find_all_by_param(field, value)
295
+ if records.size > 0
296
+ return records[0]
297
+ else
298
+ nil
299
+ end
300
+ end
301
+
302
+ def self.method_missing(name, *args)
303
+ return find_by_param($1.to_sym, args[0]) if name.to_s =~ /^find_by_(.*)/
304
+ return find_all_by_param($1.to_sym, args[0]) if name.to_s =~ /^find_all_by_(.*)/
305
+ super
306
+ end
307
+
308
+ def self.delete_unused_field
309
+ ids = connection.zrange "#{key_namespace}:all", 0, count
310
+ if ids.size > 0
311
+ attributes = connection.hgetall "#{key_namespace}:#{ids[0]}:attributes"
312
+ now_keys = self.get_fields
313
+ array = []
314
+ now_keys.each do |key|
315
+ array << key.to_s
316
+ end
317
+ attributes.reject! {|key| array.include? key }
318
+ attributes.keys.each do |delete_key|
319
+ ids.each do |id|
320
+ connection.hdel "#{key_namespace}:#{id}:attributes", delete_key
321
+ end
322
+ end
323
+ end
324
+ end
325
+ end
326
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeredis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-10-09 00:00:00.000000000Z
13
+ date: 2013-02-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: redis
17
- requirement: &70240177908780 !ruby/object:Gem::Requirement
17
+ requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,15 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70240177908780
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
26
31
  - !ruby/object:Gem::Dependency
27
32
  name: activemodel
28
- requirement: &70240177908360 !ruby/object:Gem::Requirement
33
+ requirement: !ruby/object:Gem::Requirement
29
34
  none: false
30
35
  requirements:
31
36
  - - ! '>='
@@ -33,10 +38,15 @@ dependencies:
33
38
  version: '0'
34
39
  type: :runtime
35
40
  prerelease: false
36
- version_requirements: *70240177908360
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
37
47
  - !ruby/object:Gem::Dependency
38
48
  name: rspec
39
- requirement: &70240177907940 !ruby/object:Gem::Requirement
49
+ requirement: !ruby/object:Gem::Requirement
40
50
  none: false
41
51
  requirements:
42
52
  - - ! '>='
@@ -44,7 +54,12 @@ dependencies:
44
54
  version: '0'
45
55
  type: :development
46
56
  prerelease: false
47
- version_requirements: *70240177907940
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
48
63
  description: ActiveModel based object persistance library for Redis
49
64
  email:
50
65
  - sonixlabs@sonix.asia
@@ -64,6 +79,7 @@ files:
64
79
  - benchmark_results.txt
65
80
  - lib/activeredis.rb
66
81
  - lib/activeredis/version.rb
82
+ - lib/old_activeredis.rb
67
83
  - sample/user.rb
68
84
  - spec/active_redis_spec.rb
69
85
  - spec/spec_helper.rb
@@ -87,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
103
  version: '0'
88
104
  requirements: []
89
105
  rubyforge_project:
90
- rubygems_version: 1.8.6
106
+ rubygems_version: 1.8.23
91
107
  signing_key:
92
108
  specification_version: 3
93
109
  summary: ActiveModel based object persisting library for Redis key-value database.