simple_record 1.1.24 → 1.1.26

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.
data/README.markdown CHANGED
@@ -113,12 +113,11 @@ To set a global prefix across all your models, use:
113
113
 
114
114
  ### Connection Modes
115
115
 
116
- There are 4 different connection modes:
116
+ There are 3 different connection modes:
117
117
 
118
118
  * per_request (default) - opens and closes a new connection to simpledb for every simpledb request. Not the best performance, but it's safe and can handle many concurrent requests at the same time (unlike single mode).
119
119
  * single - one connection across the entire application, not recommended unless the app is used by a single person.
120
120
  * per_thread - a connection is used for every thread in the application. This is good, but the catch is that you have to ensure to close the connection.
121
- * pool - NOT IMPLEMENTED YET - opens a maximum number of connections and round robins them for any simpledb request.
122
121
 
123
122
  You set the mode when you call establish_connection:
124
123
 
@@ -194,6 +193,12 @@ or
194
193
 
195
194
  o.something_id = x
196
195
 
196
+ #### Batch Save
197
+
198
+ To do a batch save using SimpleDB's batch saving feature to improve performance, simply create your objects, add them to an array, then call:
199
+
200
+ MyClass.batch_save(object_list)
201
+
197
202
  ## Kudos
198
203
 
199
204
  Special thanks to Garrett Cox for creating Activerecord2sdb which SimpleRecord is based on:
data/lib/simple_record.rb CHANGED
@@ -83,25 +83,19 @@ module SimpleRecord
83
83
  def initialize(attrs={})
84
84
  # todo: Need to deal with objects passed in. iterate through belongs_to perhaps and if in attrs, set the objects id rather than the object itself
85
85
 
86
- # if params[0]
87
- #we have to handle the virtuals. Right now, this assumes that all parameters are passed from inside an array
88
- #this is the usually the case when the parameters are passed passed via POST and obtained from the params array
89
- @@virtuals.each do |virtual|
90
- #we first copy the information for the virtual to an instance variable of the same name
91
- eval("@#{virtual}=params[0]['#{virtual}']")
92
- #and then remove the parameter before it is passed to initialize, so that it is NOT sent to SimpleDB
93
- eval("params[0].delete('#{virtual}')")
94
- end
95
- # super(*params)
96
- # else
97
- super
98
- # end
86
+ #we have to handle the virtuals.
87
+ @@virtuals.each do |virtual|
88
+ #we first copy the information for the virtual to an instance variable of the same name
89
+ eval("@#{virtual}=attrs['#{virtual}']")
90
+ #and then remove the parameter before it is passed to initialize, so that it is NOT sent to SimpleDB
91
+ eval("attrs.delete('#{virtual}')")
92
+ end
93
+ super
99
94
  @errors=SimpleRecord_errors.new
100
95
  @dirty = {}
101
96
  end
102
97
 
103
98
 
104
-
105
99
  # todo: move into Callbacks module
106
100
  #this bit of code creates a "run_blank" function for everything value in the @@callbacks array.
107
101
  #this function can then be inserted in the appropriate place in the save, new, destroy, etc overrides
@@ -509,7 +503,7 @@ module SimpleRecord
509
503
  end
510
504
 
511
505
  def set_updated
512
- # puts 'SETTING UPDATED'
506
+ #puts 'SETTING UPDATED'
513
507
  # @updated = DateTime.now
514
508
  self[:updated] = DateTime.now
515
509
  # @tester = 'some test value updated'
@@ -520,7 +514,7 @@ module SimpleRecord
520
514
  @@padding = 20
521
515
  @@date_format = "%Y-%m-%dT%H:%M:%S"; # Time to second precision
522
516
 
523
- def self.pad_and_offset(x)
517
+ def self.pad_and_offset(x) # Change name to something more appropriate like ruby_to_sdb
524
518
  # todo: add Float, etc
525
519
  # puts 'padding=' + x.class.name + " -- " + x.inspect
526
520
  if x.kind_of? Integer
@@ -536,7 +530,9 @@ module SimpleRecord
536
530
  # Amazon suggests: 2008-02-10T16:52:01.000-05:00
537
531
  # "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
538
532
  #
539
- if x.is_a? DateTime
533
+ if x.is_a? Date
534
+ x_str = x.strftime(@@date_format)
535
+ elsif x.is_a? DateTime
540
536
  x_str = x.new_offset(0).strftime(@@date_format)
541
537
  else
542
538
  x_str = x.getutc.strftime(@@date_format)
@@ -613,7 +609,7 @@ module SimpleRecord
613
609
  options[:dirty_atts] = @dirty
614
610
  end
615
611
  to_delete = get_atts_to_delete # todo: this should use the @dirty hash now
616
- # puts 'saving'
612
+ # puts 'done to_delete ' + to_delete.inspect
617
613
  if super(options)
618
614
  # puts 'SAVED super'
619
615
  self.class.cache_results(self)
@@ -646,6 +642,14 @@ module SimpleRecord
646
642
  end
647
643
  end
648
644
 
645
+ def save_with_validation!(options={})
646
+ if valid?
647
+ save
648
+ else
649
+ raise RecordInvalid.new(self)
650
+ end
651
+ end
652
+
649
653
  def pad_and_offset_ints_to_sdb()
650
654
 
651
655
  defined_attributes_local.each_pair do |name, att_meta|
@@ -687,7 +691,8 @@ module SimpleRecord
687
691
  ok = run_before_validation && (is_create ? run_before_validation_on_create : run_before_validation_on_update)
688
692
  return false unless ok
689
693
 
690
- validate
694
+ validate()
695
+
691
696
  is_create ? validate_on_create : validate_on_update
692
697
  # puts 'AFTER VALIDATIONS, ERRORS=' + errors.inspect
693
698
  if (!@errors.nil? && @errors.length > 0 )
@@ -730,9 +735,10 @@ module SimpleRecord
730
735
  # todo: this should use the @dirty hash now
731
736
  to_delete = []
732
737
  @attributes.each do |key, value|
733
- # puts 'value=' + value.inspect
734
- if value.nil? || (value.is_a?(Array) && value.size == 0)
738
+ # puts 'key=' + key.inspect + ' value=' + value.inspect
739
+ if value.nil? || (value.is_a?(Array) && value.size == 0) || (value.is_a?(Array) && value.size == 1 && value[0] == nil)
735
740
  to_delete << key
741
+ @attributes.delete(key)
736
742
  end
737
743
  end
738
744
  return to_delete
@@ -770,6 +776,7 @@ module SimpleRecord
770
776
  end
771
777
 
772
778
  def delete_niled(to_delete)
779
+ # puts 'to_delete=' + to_delete.inspect
773
780
  if to_delete.size > 0
774
781
  # puts 'Deleting attributes=' + to_delete.inspect
775
782
  delete_attributes to_delete
@@ -1131,5 +1138,17 @@ module SimpleRecord
1131
1138
  end
1132
1139
 
1133
1140
  end
1141
+
1142
+ class SimpleRecordError < StandardError
1143
+
1144
+ end
1145
+
1146
+ class RecordInvalid < SimpleRecordError
1147
+ attr_accessor :record
1148
+
1149
+ def initialize(record)
1150
+ @record = record
1151
+ end
1152
+ end
1134
1153
  end
1135
1154
 
data/lib/stats.rb CHANGED
@@ -1,16 +1,16 @@
1
- module SimpleRecord
2
- class Stats
3
- attr_accessor :selects, :puts
4
-
5
- def initialize
6
- @selects = 0
7
- @puts = 0
8
- end
9
-
10
- def clear
11
- self.selects = 0
12
- self.puts = 0
13
- end
14
- end
15
- end
16
-
1
+ module SimpleRecord
2
+ class Stats
3
+ attr_accessor :selects, :puts
4
+
5
+ def initialize
6
+ @selects = 0
7
+ @puts = 0
8
+ end
9
+
10
+ def clear
11
+ self.selects = 0
12
+ self.puts = 0
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,14 @@
1
+
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/simple_record")
4
+ require "yaml"
5
+ require 'right_aws'
6
+ require 'my_model'
7
+ require 'my_child_model'
8
+
9
+ x = 0
10
+ puts SimpleRecord::Base.pad_and_offset(x)
11
+
12
+ x = 1
13
+ puts SimpleRecord::Base.pad_and_offset(x)
14
+
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/simple_record")
2
+
3
+ class MyBaseModel < SimpleRecord::Base
4
+
5
+ has_strings :base_string
6
+
7
+ end
@@ -1,34 +1,34 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../lib/simple_record")
2
- require 'my_model'
3
-
4
- class MyChildModel < SimpleRecord::Base
5
- belongs_to :my_model
6
- has_attributes :name, :child_attr
7
-
8
- end
9
-
10
-
11
- =begin
12
-
13
-
14
- puts 'word'
15
-
16
- mm = MyModel.new
17
- puts 'word2'
18
-
19
- mcm = MyChildModel.new
20
-
21
- puts 'mcm instance methods=' + MyChildModel.instance_methods(true).inspect
22
- #puts 'mcm=' + mcm.instance_methods(false)
23
- puts 'mcm class vars = ' + mcm.class.class_variables.inspect
24
- puts mcm.class == MyChildModel
25
- puts 'saved? ' + mm.save.to_s
26
- puts mm.errors.inspect
27
-
28
- puts "mm attributes=" + MyModel.defined_attributes.inspect
29
- puts "mcm attributes=" + MyChildModel.defined_attributes.inspect
30
-
31
- mcm2 = MyChildModel.new
32
- puts "mcm2 attributes=" + MyChildModel.defined_attributes.inspect
33
-
34
- =end
1
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/simple_record")
2
+ require 'my_model'
3
+
4
+ class MyChildModel < SimpleRecord::Base
5
+ belongs_to :my_model
6
+ has_attributes :name, :child_attr
7
+
8
+ end
9
+
10
+
11
+ =begin
12
+
13
+
14
+ puts 'word'
15
+
16
+ mm = MyModel.new
17
+ puts 'word2'
18
+
19
+ mcm = MyChildModel.new
20
+
21
+ puts 'mcm instance methods=' + MyChildModel.instance_methods(true).inspect
22
+ #puts 'mcm=' + mcm.instance_methods(false)
23
+ puts 'mcm class vars = ' + mcm.class.class_variables.inspect
24
+ puts mcm.class == MyChildModel
25
+ puts 'saved? ' + mm.save.to_s
26
+ puts mm.errors.inspect
27
+
28
+ puts "mm attributes=" + MyModel.defined_attributes.inspect
29
+ puts "mcm attributes=" + MyChildModel.defined_attributes.inspect
30
+
31
+ mcm2 = MyChildModel.new
32
+ puts "mcm2 attributes=" + MyChildModel.defined_attributes.inspect
33
+
34
+ =end
data/test/my_model.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + "/../lib/simple_record")
2
+ require 'my_base_model'
2
3
 
3
- class MyModel < SimpleRecord::Base
4
+ class MyModel < MyBaseModel
4
5
 
5
6
  has_strings :name, :nickname
6
7
  has_ints :age, :save_count
@@ -11,7 +12,7 @@ class MyModel < SimpleRecord::Base
11
12
  #callbacks
12
13
  before_create :set_nickname
13
14
 
14
- after_save :bump_save_count
15
+ before_save :bump_save_count
15
16
 
16
17
  def set_nickname
17
18
  self.nickname = name if self.nickname.blank?
@@ -1,15 +1,15 @@
1
-
2
- require File.expand_path(File.dirname(__FILE__) + "/../lib/results_array")
3
-
4
- array = SimpleRecord::ResultsArray.new()
5
- #array.extend(ResultsArray)
6
-
7
- 500.times do |i|
8
- array << "_ob_" + i.to_s
9
- end
10
-
11
- array.each do |v|
12
- puts v.to_s
13
- end
14
-
1
+
2
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/results_array")
3
+
4
+ array = SimpleRecord::ResultsArray.new()
5
+ #array.extend(ResultsArray)
6
+
7
+ 500.times do |i|
8
+ array << "_ob_" + i.to_s
9
+ end
10
+
11
+ array.each do |v|
12
+ puts v.to_s
13
+ end
14
+
15
15
  puts array[10]
data/test/temp_test.rb CHANGED
@@ -1,63 +1,63 @@
1
- # rubymine won't run 1.9 tests
2
-
3
- require 'minitest/unit'
4
- require File.expand_path(File.dirname(__FILE__) + "/../lib/simple_record")
5
- require "yaml"
6
- require 'right_aws'
7
- require 'my_model'
8
- require 'my_child_model'
9
-
10
-
11
- def setup
12
- @config = YAML::load(File.read('test-config.yml'))
13
- puts 'akey=' + @config['amazon']['access_key']
14
- puts 'skey=' + @config['amazon']['secret_key']
15
- RightAws::ActiveSdb.establish_connection(@config['amazon']['access_key'], @config['amazon']['secret_key'], :port=>80, :protocol=>"http")
16
- SimpleRecord::Base.set_domain_prefix("simplerecord_tests_")
17
- end
18
-
19
- def teardown
20
- RightAws::ActiveSdb.close_connection()
21
- end
22
-
23
- def test_dates
24
- mm = MyModel.new
25
- mm.name = "Travis"
26
- mm.age = 32
27
- mm.cool = true
28
- mm.created = DateTime.now - 10
29
- mm.updated = DateTime.now
30
- mm.birthday = Time.now - (3600 * 24 * 365 * 10)
31
- puts 'before save=' + mm.inspect
32
- mm.save
33
- puts 'after save=' + mm.inspect
34
-
35
- mms = MyModel.find(:all, :conditions => ["created > ?", DateTime.now - 1])
36
- puts 'mms=' + mms.inspect
37
-
38
- end
39
-
40
- def test_date_comparisons
41
-
42
- t = SimpleRecord::Base.pad_and_offset(Time.now)
43
- puts t
44
- dt = SimpleRecord::Base.pad_and_offset(DateTime.now)
45
- puts dt
46
- dt_tomorrow = SimpleRecord::Base.pad_and_offset(DateTime.now + 1)
47
-
48
-
49
- puts 'compare=' + (t <=> dt).to_s
50
- puts 'compare=' + (t <=> dt_tomorrow).to_s
51
-
52
- dts = DateTime.parse(dt_tomorrow)
53
- puts dts.to_s
54
- ts = Time.parse(dt)
55
- puts ts.to_s
56
- end
57
-
58
- setup
59
-
60
- #test_dates
61
- test_date_comparisons
62
-
63
- teardown
1
+ # rubymine won't run 1.9 tests
2
+
3
+ require 'minitest/unit'
4
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/simple_record")
5
+ require "yaml"
6
+ require 'right_aws'
7
+ require 'my_model'
8
+ require 'my_child_model'
9
+
10
+
11
+ def setup
12
+ @config = YAML::load(File.read('test-config.yml'))
13
+ puts 'akey=' + @config['amazon']['access_key']
14
+ puts 'skey=' + @config['amazon']['secret_key']
15
+ RightAws::ActiveSdb.establish_connection(@config['amazon']['access_key'], @config['amazon']['secret_key'], :port=>80, :protocol=>"http")
16
+ SimpleRecord::Base.set_domain_prefix("simplerecord_tests_")
17
+ end
18
+
19
+ def teardown
20
+ RightAws::ActiveSdb.close_connection()
21
+ end
22
+
23
+ def test_dates
24
+ mm = MyModel.new
25
+ mm.name = "Travis"
26
+ mm.age = 32
27
+ mm.cool = true
28
+ mm.created = DateTime.now - 10
29
+ mm.updated = DateTime.now
30
+ mm.birthday = Time.now - (3600 * 24 * 365 * 10)
31
+ puts 'before save=' + mm.inspect
32
+ mm.save
33
+ puts 'after save=' + mm.inspect
34
+
35
+ mms = MyModel.find(:all, :conditions => ["created > ?", DateTime.now - 1])
36
+ puts 'mms=' + mms.inspect
37
+
38
+ end
39
+
40
+ def test_date_comparisons
41
+
42
+ t = SimpleRecord::Base.pad_and_offset(Time.now)
43
+ puts t
44
+ dt = SimpleRecord::Base.pad_and_offset(DateTime.now)
45
+ puts dt
46
+ dt_tomorrow = SimpleRecord::Base.pad_and_offset(DateTime.now + 1)
47
+
48
+
49
+ puts 'compare=' + (t <=> dt).to_s
50
+ puts 'compare=' + (t <=> dt_tomorrow).to_s
51
+
52
+ dts = DateTime.parse(dt_tomorrow)
53
+ puts dts.to_s
54
+ ts = Time.parse(dt)
55
+ puts ts.to_s
56
+ end
57
+
58
+ setup
59
+
60
+ #test_dates
61
+ test_date_comparisons
62
+
63
+ teardown
@@ -8,14 +8,19 @@ require 'my_child_model'
8
8
  class TestSimpleRecord < Test::Unit::TestCase
9
9
 
10
10
  def setup
11
- @config = YAML::load(File.open(File.expand_path("~/.amazon/simple_record_tests.yml")))
12
- #puts @config.inspect
13
- SimpleRecord.establish_connection(@config['amazon']['access_key'], @config['amazon']['secret_key'], :port=>80, :protocol=>"http")
11
+ @config = YAML::load(File.open(File.expand_path("~/.test-configs/simple_record.yml")))
12
+ #puts 'inspecting config = ' + @config.inspect
13
+
14
+ # Establish AWS connection directly
15
+ @@sdb = RightAws::SdbInterface.new(@config['amazon']['access_key'], @config['amazon']['secret_key'], {:connection_mode => :per_request, :protocol => "http", :port => 80})
16
+
17
+
18
+ SimpleRecord.establish_connection(@config['amazon']['access_key'], @config['amazon']['secret_key'], :connection_mode=>:single)
14
19
  SimpleRecord::Base.set_domain_prefix("simplerecord_tests_")
15
20
  end
16
21
 
17
22
  def teardown
18
- SimpleRecord.close_connection()
23
+ SimpleRecord.close_connection
19
24
  end
20
25
 
21
26
 
@@ -46,6 +51,15 @@ class TestSimpleRecord < Test::Unit::TestCase
46
51
  assert mm2.cool = true
47
52
  assert mm2.name = "Travis"
48
53
  assert mm2.created.is_a? DateTime
54
+
55
+ # test nilification
56
+ mm2.age = nil
57
+ mm2.save
58
+ puts mm2.errors.inspect
59
+ sleep 1
60
+ mm2 = MyModel.find(id)
61
+ puts mm2.inspect
62
+ assert mm2.age.nil?, "doh, age is " + mm2.age.inspect
49
63
  end
50
64
 
51
65
  def test_bad_query
@@ -133,7 +147,7 @@ class TestSimpleRecord < Test::Unit::TestCase
133
147
  mm2.name = "Travis 2"
134
148
  mm2.save(:dirty=>true)
135
149
 
136
- # todo: how do we assert this?
150
+ # todo: how do we assert this? perhaps change a value directly in sdb and see that it doesn't get overwritten
137
151
 
138
152
  end
139
153
 
@@ -206,14 +220,7 @@ class TestSimpleRecord < Test::Unit::TestCase
206
220
 
207
221
  # ensures that it uses next token and what not
208
222
  def test_big_result
209
- mms = MyModel.find(:all)
210
- puts 'mms.size=' + mms.size.to_s
211
- i = 0
212
- mms.each do |x|
213
- puts 'deleting=' + i.to_s
214
- x.delete
215
- i+=1
216
- end
223
+ i = clear_out_my_models
217
224
  num_made = 110
218
225
  num_made.times do |i|
219
226
  mm = MyModel.create(:name=>"Travis", :age=>i, :cool=>true)
@@ -228,6 +235,17 @@ class TestSimpleRecord < Test::Unit::TestCase
228
235
  assert i == num_made
229
236
  end
230
237
 
238
+ def clear_out_my_models
239
+ mms = MyModel.find(:all)
240
+ puts 'mms.size=' + mms.size.to_s
241
+ i = 0
242
+ mms.each do |x|
243
+ puts 'deleting=' + i.to_s
244
+ x.delete
245
+ i+=1
246
+ end
247
+ end
248
+
231
249
  def test_results_array
232
250
  mms = MyModel.find(:all) # select 2
233
251
  assert !mms.first.nil?
@@ -294,7 +312,80 @@ class TestSimpleRecord < Test::Unit::TestCase
294
312
 
295
313
  assert mm.valid?, mm.errors.inspect
296
314
  assert mm.save_count == 1
315
+ end
316
+
317
+
318
+ def test_nil_attr_deletion
319
+ mm = MyModel.new
320
+ mm.name = "Chad"
321
+ mm.age = 30
322
+ mm.cool = false
323
+ mm.save
324
+
325
+ # Should have 1 age attribute
326
+ assert @@sdb.get_attributes('simplerecord_tests_mymodel', mm.id, 'age')[:attributes].size == 1
327
+
328
+ mm.age = nil
329
+ mm.save
330
+
331
+ # Should be NIL
332
+ assert mm.age == nil
333
+
334
+ # Should have NO age attributes
335
+ assert @@sdb.get_attributes('simplerecord_tests_mymodel', mm.id, 'age')[:attributes].size == 0
336
+ end
337
+
338
+ def test_null
339
+ puts Time.now.to_i.to_s
340
+ clear_out_my_models
341
+
342
+ mm = MyModel.new(:name=>"birthay is null")
343
+ mm.save
344
+ mm2 = MyModel.new(:name=>"birthday is not null")
345
+ mm2.birthday = Time.now
346
+ mm2.save
347
+ sleep 2
348
+ mms = MyModel.find(:all, :conditions=>["birthday is null"])
349
+ mms.each do |m|
350
+ puts m.inspect
351
+ end
352
+ assert mms.size == 1
353
+ assert mms[0].id = mm.id
354
+ mms = MyModel.find(:all, :conditions=>["birthday is not null"])
355
+ mms.each do |m|
356
+ puts m.inspect
357
+ end
358
+ assert mms.size == 1
359
+ assert mms[0].id = mm2.id
360
+
361
+ end
362
+
363
+ # Test to add support for IN
364
+ def test_in_clause
365
+ mms = MyModel.find(:all)
366
+
367
+ mms2 = MyModel.find(:all, :conditions=>["id in ?"])
297
368
 
298
369
  end
299
370
 
371
+ def test_base_attributes
372
+ mm = MyModel.new()
373
+ mm.name = "test name"
374
+ mm.base_string = "in base class"
375
+ mm.save_with_validation!
376
+
377
+ mm2 = MyModel.find(mm.id)
378
+ assert mm2.base_string == mm.base_string
379
+
380
+ mm2.base_string = "changed base string"
381
+ mm2.save_with_validation!
382
+
383
+ mm3 = MyModel.find(mm2.id)
384
+ assert mm3.base_string == mm2.base_string
385
+ puts mm3.inspect
386
+
387
+
388
+ end
389
+
390
+
300
391
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.24
4
+ version: 1.1.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - Travis Reeder
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2009-10-12 00:00:00 -07:00
14
+ date: 2009-10-29 00:00:00 -07:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -66,6 +66,8 @@ signing_key:
66
66
  specification_version: 3
67
67
  summary: Drop in replacement for ActiveRecord to Amazon SimpleDB instead.
68
68
  test_files:
69
+ - test/conversions.rb
70
+ - test/my_base_model.rb
69
71
  - test/my_child_model.rb
70
72
  - test/my_model.rb
71
73
  - test/paging_array_test.rb