ampere 0.1.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm use 1.9.2@ampere
1
+ rvm use 1.9.3@ampere
data/README.md CHANGED
@@ -5,12 +5,24 @@ Ampere is an ActiveRecord-style ORM for the Redis key/value data store.
5
5
  This is under active development right now and not very far along. Stay
6
6
  tuned for further developments.
7
7
 
8
+ ## A note about version 1.0 (IMPORTANT!!!)
9
+
10
+ For the 1.0 release I changed Ampere's API so that instead of subclassing
11
+ `Ampere::Model` to use Ampere's methods, you include it as a mixin. This
12
+ change has been reflected in the examples below.
13
+
14
+ This change was to unify the usage of Ampere a little more with usage of
15
+ Mongoid, and also so that users of Ampere can use their own class hierarchies,
16
+ which at some later date might have significance with how Ampere works.
17
+
8
18
  ## Usage
9
19
 
10
20
  Write a model class and make it inherit from the `Ampere::Model` class.
11
21
  These work pretty similarly to how they do in ActiveRecord or Mongoid.
12
22
 
13
- class Car < Ampere::Model
23
+ class Car
24
+ include Ampere::Model
25
+
14
26
  field :make
15
27
  field :model
16
28
  field :year
@@ -19,7 +31,9 @@ These work pretty similarly to how they do in ActiveRecord or Mongoid.
19
31
  has_many :passengers
20
32
  end
21
33
 
22
- class Engine < Ampere::Model
34
+ class Engine
35
+ include Ampere::Model
36
+
23
37
  field :displacement
24
38
  field :cylinders
25
39
  field :configuration
@@ -27,7 +41,9 @@ These work pretty similarly to how they do in ActiveRecord or Mongoid.
27
41
  belongs_to :car
28
42
  end
29
43
 
30
- class Passenger < Ampere::Model
44
+ class Passenger
45
+ include Ampere::Model
46
+
31
47
  field :name
32
48
  field :seat
33
49
 
@@ -46,9 +62,11 @@ be slower if one of the keys you are searching by isn't indexed).
46
62
 
47
63
  ### Indexes
48
64
 
49
- Indexes work similar to Mongoid. They are non-unique.
65
+ Indexes work similar to Mongoid. They are non-unique by default.
50
66
 
51
- class Student < Ampere::Model
67
+ class Student
68
+ include Ampere::Model
69
+
52
70
  field :last_name
53
71
  field :first_name
54
72
 
@@ -60,7 +78,9 @@ last_name will happen faster.
60
78
 
61
79
  You can also define indices on multiple fields.
62
80
 
63
- class Student < Ampere::Model
81
+ class Student
82
+ include Ampere::Model
83
+
64
84
  field :last_name
65
85
  field :first_name
66
86
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 1.0.0
data/ampere.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "ampere"
8
- s.version = "0.1.3"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Max Thom Stahl"]
12
- s.date = "2012-01-19"
12
+ s.date = "2012-04-20"
13
13
  s.description = "An ActiveRecord/Mongoid-esque object model for the Redis key/value data store."
14
14
  s.email = "max@villainousindustri.es"
15
15
  s.extra_rdoc_files = [
@@ -49,7 +49,7 @@ Gem::Specification.new do |s|
49
49
  s.homepage = "http://github.com/mstahl/ampere"
50
50
  s.licenses = ["EPL"]
51
51
  s.require_paths = ["lib"]
52
- s.rubygems_version = "1.8.10"
52
+ s.rubygems_version = "1.8.17"
53
53
  s.summary = "A pure Ruby ORM for Redis."
54
54
 
55
55
  if s.respond_to? :specification_version then
data/lib/ampere/model.rb CHANGED
@@ -1,11 +1,23 @@
1
1
  module Ampere
2
- class Model
3
- attr_reader :id
2
+ module Model
4
3
 
5
- @fields = []
6
- @field_defaults = {}
7
- @indices = []
8
- @field_types = {}
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+
7
+ base.class_eval do
8
+ attr_reader :id
9
+
10
+ attr_accessor :fields
11
+ attr_accessor :field_defaults
12
+ attr_accessor :indices
13
+ attr_accessor :field_types
14
+
15
+ @fields = []
16
+ @field_defaults = {}
17
+ @indices = []
18
+ @field_types = {}
19
+ end
20
+ end
9
21
 
10
22
  ### Instance methods
11
23
 
@@ -138,225 +150,226 @@ module Ampere
138
150
 
139
151
  ### Class methods
140
152
 
141
- # Returns an array of all the records that have been stored.
142
- def self.all
143
- Ampere.connection.keys("#{to_s.downcase}.*").map{|m| find m}
144
- end
153
+ module ClassMethods
154
+ # Returns an array of all the records that have been stored.
155
+ def all
156
+ Ampere.connection.keys("#{to_s.downcase}.*").map{|m| find m}
157
+ end
145
158
 
146
- # Declares a belongs_to relationship to another model.
147
- def self.belongs_to(field_name, options = {})
148
- has_one field_name, options
149
- end
159
+ # Declares a belongs_to relationship to another model.
160
+ def belongs_to(field_name, options = {})
161
+ has_one field_name, options
162
+ end
150
163
 
151
- # Like @indices, but only returns the compound indices this class defines.
152
- def self.compound_indices
153
- @indices.select{|i| i.class == Array}
154
- end
164
+ # Like @indices, but only returns the compound indices this class defines.
165
+ def compound_indices
166
+ @indices.select{|i| i.class == Array}
167
+ end
155
168
 
156
- # Returns the number of instances of this record that have been stored.
157
- def self.count
158
- Ampere.connection.keys("#{to_s.downcase}.*").length
159
- end
169
+ # Returns the number of instances of this record that have been stored.
170
+ def count
171
+ Ampere.connection.keys("#{to_s.downcase}.*").length
172
+ end
160
173
 
161
- # Instantiates and saves a new record.
162
- def self.create(hash = {})
163
- new(hash).save
164
- end
174
+ # Instantiates and saves a new record.
175
+ def create(hash = {})
176
+ new(hash).save
177
+ end
165
178
 
166
- # Deletes the record with the given ID.
167
- def self.delete(id)
168
- Ampere.connection.del(id)
169
- end
179
+ # Deletes the record with the given ID.
180
+ def delete(id)
181
+ Ampere.connection.del(id)
182
+ end
170
183
 
171
- # Declares a field. See the README for more details.
172
- def self.field(name, options = {})
173
- @fields ||= []
174
- @field_defaults ||= {}
175
- @indices ||= []
176
- @unique_indices ||= []
177
- @field_types ||= {}
184
+ # Declares a field. See the README for more details.
185
+ def field(name, options = {})
186
+ @fields ||= []
187
+ @field_defaults ||= {}
188
+ @indices ||= []
189
+ @unique_indices ||= []
190
+ @field_types ||= {}
178
191
 
179
- @fields << name
192
+ @fields << name
180
193
 
181
- # attr_accessor :"#{name}"
194
+ # attr_accessor :"#{name}"
182
195
 
183
- # Handle default value
184
- @field_defaults[name] = options[:default]
196
+ # Handle default value
197
+ @field_defaults[name] = options[:default]
185
198
 
186
- # Handle type, if any
187
- if options[:type] then
188
- @field_types[:"#{name}"] = options[:type].to_s
189
- end
199
+ # Handle type, if any
200
+ if options[:type] then
201
+ @field_types[:"#{name}"] = options[:type].to_s
202
+ end
190
203
 
191
- define_method :"#{name}" do
192
- instance_variable_get("@#{name}") or self.class.field_defaults[name]
193
- end
204
+ define_method :"#{name}" do
205
+ instance_variable_get("@#{name}") or self.class.field_defaults[name]
206
+ end
194
207
 
195
- define_method :"#{name}=" do |val|
196
- if not self.class.field_types[:"#{name}"] or val.is_a?(eval(self.class.field_types[:"#{name}"])) then
197
- instance_variable_set("@#{name}", val)
198
- else
199
- raise "Cannot set field of type #{self.class.field_types[name.to_sym]} with #{val.class} value"
208
+ define_method :"#{name}=" do |val|
209
+ if not self.class.field_types[:"#{name}"] or val.is_a?(eval(self.class.field_types[:"#{name}"])) then
210
+ instance_variable_set("@#{name}", val)
211
+ else
212
+ raise "Cannot set field of type #{self.class.field_types[name.to_sym]} with #{val.class} value"
213
+ end
200
214
  end
201
215
  end
202
- end
203
216
 
204
- def self.fields
205
- @fields
206
- end
217
+ def fields
218
+ @fields
219
+ end
207
220
 
208
- def self.field_defaults
209
- @field_defaults
210
- end
221
+ def field_defaults
222
+ @field_defaults
223
+ end
211
224
 
212
- def self.field_types
213
- @field_types
214
- end
225
+ def field_types
226
+ @field_types
227
+ end
215
228
 
216
- # Finds the record with the given ID, or the first that matches the given conditions
217
- def self.find(options = {})
218
- if options.class == String then
219
- if Ampere.connection.exists(options) then
220
- new(Ampere.connection.hgetall(options), true)
229
+ # Finds the record with the given ID, or the first that matches the given conditions
230
+ def find(options = {})
231
+ if options.class == String then
232
+ if Ampere.connection.exists(options) then
233
+ new(Ampere.connection.hgetall(options), true)
234
+ else
235
+ nil
236
+ end
221
237
  else
222
- nil
238
+ # TODO Write a handler for this case, even if it's an exception
239
+ raise "Cannot find by #{options.class} yet"
223
240
  end
224
- else
225
- # TODO Write a handler for this case, even if it's an exception
226
- raise "Cannot find by #{options.class} yet"
227
241
  end
228
- end
229
242
 
230
- # Defines a has_one relationship with another model. See the README for more details.
231
- def self.has_one(field_name, options = {})
232
- referred_klass_name = (options[:class] or options['class'] or field_name)
233
- my_klass_name = to_s.downcase
243
+ # Defines a has_one relationship with another model. See the README for more details.
244
+ def has_one(field_name, options = {})
245
+ referred_klass_name = (options[:class] or options['class'] or field_name)
246
+ my_klass_name = to_s.downcase
234
247
 
235
- field :"#{field_name}_id"
248
+ field :"#{field_name}_id"
236
249
 
237
- define_method(field_name.to_sym) do
238
- return if self.send("#{field_name}_id").nil?
239
- eval(referred_klass_name.to_s.capitalize).find(self.send("#{field_name}_id"))
240
- end
250
+ define_method(field_name.to_sym) do
251
+ return if self.send("#{field_name}_id").nil?
252
+ eval(referred_klass_name.to_s.capitalize).find(self.send("#{field_name}_id"))
253
+ end
241
254
 
242
- define_method(:"#{field_name}=") do |val|
243
- return nil if val.nil?
244
- # Set attr with key where referred model is stored
245
- self.send("#{field_name}_id=", val.id)
246
- # Also update that model's hash with a pointer back to here
247
- val.send("#{my_klass_name}_id=", self.send("id"))
255
+ define_method(:"#{field_name}=") do |val|
256
+ return nil if val.nil?
257
+ # Set attr with key where referred model is stored
258
+ self.send("#{field_name}_id=", val.id)
259
+ # Also update that model's hash with a pointer back to here
260
+ val.send("#{my_klass_name}_id=", self.send("id"))
261
+ end
248
262
  end
249
- end
250
263
 
251
- # Defines a has_many relationship with another model. See the README for more details.
252
- def self.has_many(field_name, options = {})
253
- klass_name = (options[:class] or options['class'] or field_name.to_s.gsub(/s$/, ''))
254
- my_klass_name = to_s.downcase
264
+ # Defines a has_many relationship with another model. See the README for more details.
265
+ def has_many(field_name, options = {})
266
+ klass_name = (options[:class] or options['class'] or field_name.to_s.gsub(/s$/, ''))
267
+ my_klass_name = to_s.downcase
255
268
 
256
- define_method(:"#{field_name}") do
257
- (Ampere.connection.smembers("#{to_s.downcase}.#{self.id}.has_many.#{field_name}")).map do |id|
258
- eval(klass_name.to_s.capitalize).find(id)
269
+ define_method(:"#{field_name}") do
270
+ (Ampere.connection.smembers("#{to_s.downcase}.#{self.id}.has_many.#{field_name}")).map do |id|
271
+ eval(klass_name.to_s.capitalize).find(id)
272
+ end
259
273
  end
260
- end
261
274
 
262
- define_method(:"#{field_name}=") do |val|
263
- val.each do |v|
264
- Ampere.connection.sadd("#{to_s.downcase}.#{self.id}.has_many.#{field_name}", v.id)
265
- # Set pointer for belongs_to
266
- Ampere.connection.hset(v.id, "#{my_klass_name}_id", self.send("id"))
275
+ define_method(:"#{field_name}=") do |val|
276
+ val.each do |v|
277
+ Ampere.connection.sadd("#{to_s.downcase}.#{self.id}.has_many.#{field_name}", v.id)
278
+ # Set pointer for belongs_to
279
+ Ampere.connection.hset(v.id, "#{my_klass_name}_id", self.send("id"))
280
+ end
267
281
  end
268
282
  end
269
- end
270
283
 
271
- # Defines an index. See the README for more details.
272
- def self.index(field_name, options = {})
273
- # TODO There has just got to be a better way to handle this.
274
- @fields ||= []
275
- @field_defaults ||= {}
276
- @indices ||= []
277
- @unique_indices ||= []
278
- @field_types ||= {}
284
+ # Defines an index. See the README for more details.
285
+ def index(field_name, options = {})
286
+ # TODO There has just got to be a better way to handle this.
287
+ @fields ||= []
288
+ @field_defaults ||= {}
289
+ @indices ||= []
290
+ @unique_indices ||= []
291
+ @field_types ||= {}
279
292
 
280
- if field_name.class == String or field_name.class == Symbol then
281
- # Singular index
282
- raise "Can't index a nonexistent field!" unless @fields.include?(field_name)
283
- elsif field_name.class == Array then
284
- # Compound index
285
- field_name.each{|f| raise "Can't index a nonexistent field!" unless @fields.include?(f)}
286
- field_name.sort!
287
- else
288
- raise "Can't index a #{field_name.class}"
289
- end
293
+ if field_name.class == String or field_name.class == Symbol then
294
+ # Singular index
295
+ raise "Can't index a nonexistent field!" unless @fields.include?(field_name)
296
+ elsif field_name.class == Array then
297
+ # Compound index
298
+ field_name.each{|f| raise "Can't index a nonexistent field!" unless @fields.include?(f)}
299
+ field_name.sort!
300
+ else
301
+ raise "Can't index a #{field_name.class}"
302
+ end
290
303
 
291
- @indices << field_name
292
- @unique_indices << field_name if options[:unique]
293
- end
304
+ @indices << field_name
305
+ @unique_indices << field_name if options[:unique]
306
+ end
294
307
 
295
- def self.indices
296
- @indices
297
- end
308
+ def indices
309
+ @indices
310
+ end
298
311
 
299
- def self.unique_indices
300
- @unique_indices
301
- end
312
+ def unique_indices
313
+ @unique_indices
314
+ end
302
315
 
303
- # Finds an array of records which match the given conditions. This method is
304
- # much faster when all the fields given are indexed.
305
- def self.where(options = {})
306
- if options.empty? then
307
- Ampere::Collection.new(eval(to_s), [])
308
- else
309
- indexed_fields = (options.keys & @indices) + compound_indices_for(options)
310
- nonindexed_fields = (options.keys - @indices) - compound_indices_for(options).flatten
316
+ # Finds an array of records which match the given conditions. This method is
317
+ # much faster when all the fields given are indexed.
318
+ def where(options = {})
319
+ if options.empty? then
320
+ Ampere::Collection.new(eval(to_s), [])
321
+ else
322
+ indexed_fields = (options.keys & @indices) + compound_indices_for(options)
323
+ nonindexed_fields = (options.keys - @indices) - compound_indices_for(options).flatten
311
324
 
312
- results = nil
325
+ results = nil
313
326
 
314
- unless indexed_fields.empty?
315
- indexed_fields.map {|key|
316
- if key.class == String or key.class == Symbol then
317
- Ampere.connection.hget("ampere.index.#{to_s.downcase}.#{key}", options[key]).split(/:/) #.map {|id| find(id)}
318
- else
319
- # Compound index
320
- Ampere.connection.hget(
321
- "ampere.index.#{to_s.downcase}.#{key.join(':')}",
322
- key.map{|k| options[k]}.join(':')
323
- ).split(/:/) #.map {|id| find(id)}
324
- end
325
- }.each {|s|
326
- return s if s.empty?
327
+ unless indexed_fields.empty?
328
+ indexed_fields.map {|key|
329
+ if key.class == String or key.class == Symbol then
330
+ Ampere.connection.hget("ampere.index.#{to_s.downcase}.#{key}", options[key]).split(/:/) #.map {|id| find(id)}
331
+ else
332
+ # Compound index
333
+ Ampere.connection.hget(
334
+ "ampere.index.#{to_s.downcase}.#{key.join(':')}",
335
+ key.map{|k| options[k]}.join(':')
336
+ ).split(/:/) #.map {|id| find(id)}
337
+ end
338
+ }.each {|s|
339
+ return s if s.empty?
327
340
 
328
- if results.nil? then
329
- results = s
330
- else
331
- results &= s
332
- end
333
- }
334
- end
335
-
336
- unless nonindexed_fields.empty?
337
- results = all if results.nil?
338
- results = results.to_a.map{|r| r.class == String ? find(r) : r}
339
- nonindexed_fields.each do |key|
340
- results.select!{|r|
341
- r.send(key) == options[key]
341
+ if results.nil? then
342
+ results = s
343
+ else
344
+ results &= s
345
+ end
342
346
  }
343
347
  end
344
- end
348
+
349
+ unless nonindexed_fields.empty?
350
+ results = all if results.nil?
351
+ results = results.to_a.map{|r| r.class == String ? find(r) : r}
352
+ nonindexed_fields.each do |key|
353
+ results.select!{|r|
354
+ r.send(key) == options[key]
355
+ }
356
+ end
357
+ end
345
358
 
346
- # TODO The eval(to_s) trick seems a little... ghetto.
347
- Ampere::Collection.new(eval(to_s), results.reverse)
359
+ # TODO The eval(to_s) trick seems a little... ghetto.
360
+ Ampere::Collection.new(eval(to_s), results.reverse)
361
+ end
348
362
  end
349
- end
350
363
 
351
- private
364
+ private
352
365
 
353
- def self.compound_indices_for(query)
354
- compound_indices.select{|ci|
355
- (query.keys - ci).empty?
356
- }
366
+ def compound_indices_for(query)
367
+ compound_indices.select{|ci|
368
+ (query.keys - ci).empty?
369
+ }
370
+ end
357
371
  end
358
372
 
359
-
360
373
  end
361
374
 
362
375
  end
@@ -1,11 +1,13 @@
1
1
  require File.join(File.dirname(__FILE__), "..", "spec_helper.rb")
2
2
 
3
3
  describe "Model indices", :indices => true do
4
- before :all do
4
+ before :each do
5
5
  Redis.new.flushall
6
6
  Ampere.connect
7
7
 
8
- class Student < Ampere::Model
8
+ class Student
9
+ include Ampere::Model
10
+
9
11
  field :first_name
10
12
  field :last_name
11
13
  field :student_id_num
@@ -48,19 +50,25 @@ describe "Model indices", :indices => true do
48
50
 
49
51
  it 'should refuse to create an index on a field that does not exist' do
50
52
  (->{
51
- class Student < Ampere::Model
53
+ class Student
54
+ include Ampere::Model
55
+
52
56
  field :this_field_exists
53
57
 
54
58
  index :this_field_exists
55
59
  end
56
60
  }).should_not raise_error
57
61
  (->{
58
- class Student < Ampere::Model
62
+ class Student
63
+ include Ampere::Model
64
+
59
65
  index :this_field_does_not_exist
60
66
  end
61
67
  }).should raise_error
62
68
  (->{
63
- class Student < Ampere::Model
69
+ class Student
70
+ include Ampere::Model
71
+
64
72
  field :this_field_exists
65
73
 
66
74
  index [:this_field_exists, :but_this_one_does_not]
@@ -68,7 +76,7 @@ describe "Model indices", :indices => true do
68
76
  }).should raise_error
69
77
  end
70
78
 
71
- it 'should enforce the uniqueness of unique single-field indices', wip:true do
79
+ it 'should enforce the uniqueness of unique single-field indices' do
72
80
  # The student_id_num field of Student is unique. If two Students
73
81
  # with the same student_id_num are stored, the second should not
74
82
  # save successfully, throwing an exception instead.
@@ -87,7 +95,9 @@ describe "Model indices", :indices => true do
87
95
 
88
96
  context 'compound indices' do
89
97
  before :all do
90
- class Professor < Ampere::Model
98
+ class Professor
99
+ include Ampere::Model
100
+
91
101
  field :first_name
92
102
  field :last_name
93
103
  field :employee_id_number
@@ -9,7 +9,9 @@ describe "Base models", :model => true do
9
9
  Redis.new.flushall
10
10
 
11
11
  # Define a model class here.
12
- class Post < Ampere::Model
12
+ class Post
13
+ include Ampere::Model
14
+
13
15
  field :title
14
16
  field :byline
15
17
  field :content
@@ -37,7 +39,9 @@ describe "Base models", :model => true do
37
39
  end
38
40
 
39
41
  it "should have default values definable" do
40
- class Comment < Ampere::Model
42
+ class Comment
43
+ include Ampere::Model
44
+
41
45
  field :subject, :default => "No subject"
42
46
  field :content
43
47
  end
@@ -54,7 +58,9 @@ describe "Base models", :model => true do
54
58
  context 'types', :types => true do
55
59
  before :all do
56
60
  # Just adding a field with a type to Post
57
- class Post < Ampere::Model
61
+ class Post
62
+ include Ampere::Model
63
+
58
64
  field :pageviews, :type => Integer, :default => 0
59
65
  end
60
66
  end
@@ -5,7 +5,9 @@ describe 'queries', :queries => true do
5
5
  Redis.new.flushall
6
6
  Ampere.connect
7
7
 
8
- class Kitty < Ampere::Model
8
+ class Kitty
9
+ include Ampere::Model
10
+
9
11
  field :name
10
12
  field :breed
11
13
  field :age
@@ -6,7 +6,9 @@ describe 'belongs_to relationships', :belongs_to => true do
6
6
  Ampere.connect
7
7
 
8
8
  # These are used by the has_one/belongs_to example below
9
- class Car < Ampere::Model
9
+ class Car
10
+ include Ampere::Model
11
+
10
12
  field :make
11
13
  field :model
12
14
  field :year
@@ -15,7 +17,9 @@ describe 'belongs_to relationships', :belongs_to => true do
15
17
  has_many :passengers
16
18
  end
17
19
 
18
- class Engine < Ampere::Model
20
+ class Engine
21
+ include Ampere::Model
22
+
19
23
  field :displacement
20
24
  field :cylinders
21
25
  field :configuration
@@ -23,7 +27,9 @@ describe 'belongs_to relationships', :belongs_to => true do
23
27
  belongs_to :car
24
28
  end
25
29
 
26
- class Passenger < Ampere::Model
30
+ class Passenger
31
+ include Ampere::Model
32
+
27
33
  field :name
28
34
  field :seat
29
35
 
@@ -6,7 +6,9 @@ describe 'has_many relationships', :has_many => true do
6
6
  Ampere.connect
7
7
 
8
8
  # These are used by the has_one/belongs_to example below
9
- class Car < Ampere::Model
9
+ class Car
10
+ include Ampere::Model
11
+
10
12
  field :make
11
13
  field :model
12
14
  field :year
@@ -14,7 +16,9 @@ describe 'has_many relationships', :has_many => true do
14
16
  has_many :passengers
15
17
  end
16
18
 
17
- class Passenger < Ampere::Model
19
+ class Passenger
20
+ include Ampere::Model
21
+
18
22
  field :name
19
23
  field :seat
20
24
 
@@ -6,7 +6,9 @@ describe 'has_one relationships', has_one:true do
6
6
  Ampere.connect
7
7
 
8
8
  # These are used by the has_one/belongs_to example below
9
- class Car < Ampere::Model
9
+ class Car
10
+ include Ampere::Model
11
+
10
12
  field :make
11
13
  field :model
12
14
  field :year
@@ -14,7 +16,9 @@ describe 'has_one relationships', has_one:true do
14
16
  has_one :engine
15
17
  end
16
18
 
17
- class Engine < Ampere::Model
19
+ class Engine
20
+ include Ampere::Model
21
+
18
22
  field :displacement
19
23
  field :cylinders
20
24
  field :configuration
@@ -5,7 +5,9 @@ describe 'queries', :queries => true do
5
5
  Redis.new.flushall
6
6
  Ampere.connect
7
7
 
8
- class Motorcycle < Ampere::Model
8
+ class Motorcycle
9
+ include Ampere::Model
10
+
9
11
  field :make
10
12
  field :model
11
13
  field :year
@@ -5,7 +5,9 @@ describe 'Collections', :collections => true do
5
5
  Redis.new.flushall
6
6
  Ampere.connect
7
7
 
8
- class President < Ampere::Model
8
+ class President
9
+ include Ampere::Model
10
+
9
11
  field :name
10
12
  field :party
11
13
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ampere
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 1.0.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-19 00:00:00.000000000Z
12
+ date: 2012-04-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
16
- requirement: &70296343880340 !ruby/object:Gem::Requirement
16
+ requirement: &70280166250520 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70296343880340
24
+ version_requirements: *70280166250520
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: shoulda
27
- requirement: &70296343658140 !ruby/object:Gem::Requirement
27
+ requirement: &70280166249600 !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: *70296343658140
35
+ version_requirements: *70280166249600
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: cucumber
38
- requirement: &70296343657240 !ruby/object:Gem::Requirement
38
+ requirement: &70280166263980 !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: *70296343657240
46
+ version_requirements: *70280166263980
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &70296343656200 !ruby/object:Gem::Requirement
49
+ requirement: &70280166262680 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.0.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70296343656200
57
+ version_requirements: *70280166262680
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: jeweler
60
- requirement: &70296343655220 !ruby/object:Gem::Requirement
60
+ requirement: &70280166261440 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.6.4
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70296343655220
68
+ version_requirements: *70280166261440
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: simplecov
71
- requirement: &70296343654580 !ruby/object:Gem::Requirement
71
+ requirement: &70280166260320 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70296343654580
79
+ version_requirements: *70280166260320
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &70296343653980 !ruby/object:Gem::Requirement
82
+ requirement: &70280166259660 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70296343653980
90
+ version_requirements: *70280166259660
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rdoc
93
- requirement: &70296343653400 !ruby/object:Gem::Requirement
93
+ requirement: &70280166257860 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70296343653400
101
+ version_requirements: *70280166257860
102
102
  description: An ActiveRecord/Mongoid-esque object model for the Redis key/value data
103
103
  store.
104
104
  email: max@villainousindustri.es
@@ -151,7 +151,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
151
151
  version: '0'
152
152
  segments:
153
153
  - 0
154
- hash: -723934337440945373
154
+ hash: 719359362580818516
155
155
  required_rubygems_version: !ruby/object:Gem::Requirement
156
156
  none: false
157
157
  requirements:
@@ -160,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
160
  version: '0'
161
161
  requirements: []
162
162
  rubyforge_project:
163
- rubygems_version: 1.8.10
163
+ rubygems_version: 1.8.17
164
164
  signing_key:
165
165
  specification_version: 3
166
166
  summary: A pure Ruby ORM for Redis.