simple_record 2.0.5 → 2.1.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.
data/README.markdown CHANGED
@@ -70,6 +70,11 @@ This is required because SimpleDB only has strings so SimpleRecord needs to know
70
70
  has_booleans :is_nerd
71
71
  end
72
72
 
73
+ ### Multi-value attributes
74
+
75
+ SimpleDB supports having multiple values for the same attribute so to use this feature, simply set an attribute to an
76
+ array of values.
77
+
73
78
  ### belongs_to
74
79
 
75
80
  Creates a many-to-one relationship. Can only have one per belongs_to call.
@@ -207,13 +212,34 @@ Use per_thread connection mode and close the connection after each request.
207
212
 
208
213
  ### Disable ActiveRecord so you don't have to setup another database
209
214
 
210
- This is most helpful on windows so Rails doesn't need sqlite or mysql gems/drivers installed which are painful to install on windows. In environment.rb, add 'config.frameworks -= [ :active_record ]', should look something like:
215
+ #### Rails 2
216
+
217
+ This is most helpful on windows so Rails doesn't need sqlite or mysql gems/drivers installed which are painful to install on windows.
218
+ In environment.rb, add 'config.frameworks -= [ :active_record ]', so it should look something like:
211
219
 
212
220
  Rails::Initializer.run do |config|
213
221
  config.frameworks -= [ :active_record ]
214
222
  ....
215
223
  end
216
224
 
225
+ #### Rails 3
226
+
227
+ At the top of application.rb, comment out `require 'rails/all` and add the following:
228
+
229
+ #require 'rails/all'
230
+ %w(
231
+ action_controller
232
+ action_mailer
233
+ active_resource
234
+ rails/test_unit
235
+ ).each do |framework|
236
+ begin
237
+ require "#{framework}/railtie"
238
+ rescue LoadError
239
+ end
240
+ end
241
+
242
+ This is the same as rails/all minus active_record.
217
243
 
218
244
  ## Large Objects (LOBS)
219
245
 
data/lib/simple_record.rb CHANGED
@@ -28,6 +28,13 @@ require 'aws'
28
28
  require 'base64'
29
29
  require 'active_support'
30
30
  require 'active_support/core_ext'
31
+ begin
32
+ # comment out line below to test rails2 validations
33
+ require 'active_model'
34
+ rescue LoadError => ex
35
+ puts "ActiveModel not available, falling back."
36
+ end
37
+ require File.expand_path(File.dirname(__FILE__) + "/simple_record/validations")
31
38
  require File.expand_path(File.dirname(__FILE__) + "/simple_record/attributes")
32
39
  require File.expand_path(File.dirname(__FILE__) + "/simple_record/active_sdb")
33
40
  require File.expand_path(File.dirname(__FILE__) + "/simple_record/callbacks")
@@ -36,7 +43,6 @@ require File.expand_path(File.dirname(__FILE__) + "/simple_record/errors")
36
43
  require File.expand_path(File.dirname(__FILE__) + "/simple_record/json")
37
44
  require File.expand_path(File.dirname(__FILE__) + "/simple_record/logging")
38
45
  require File.expand_path(File.dirname(__FILE__) + "/simple_record/password")
39
- require File.expand_path(File.dirname(__FILE__) + "/simple_record/rails2")
40
46
  require File.expand_path(File.dirname(__FILE__) + "/simple_record/results_array")
41
47
  require File.expand_path(File.dirname(__FILE__) + "/simple_record/stats")
42
48
  require File.expand_path(File.dirname(__FILE__) + "/simple_record/translations")
@@ -170,14 +176,28 @@ module SimpleRecord
170
176
 
171
177
 
172
178
  # puts 'Is ActiveModel defined? ' + defined?(ActiveModel).inspect
179
+
180
+
173
181
  if defined?(ActiveModel)
182
+ @@active_model = true
174
183
  extend ActiveModel::Naming
175
184
  include ActiveModel::Conversion
176
185
  include ActiveModel::Validations
186
+ extend ActiveModel::Callbacks # for ActiveRecord like callbacks
187
+ include ActiveModel::Validations::Callbacks
188
+ define_model_callbacks :save, :create, :update, :destroy
189
+ include SimpleRecord::Callbacks3
190
+ alias_method :am_valid?, :valid?
191
+
192
+
177
193
  else
194
+ @@active_model = false
195
+ puts "using rails2 validations."
178
196
  attr_accessor :errors
179
- include SimpleRecord::Rails2
197
+ include SimpleRecord::Callbacks
180
198
  end
199
+ include SimpleRecord::Validations
200
+
181
201
 
182
202
  include SimpleRecord::Translations
183
203
  # include SimpleRecord::Attributes
@@ -185,7 +205,6 @@ module SimpleRecord
185
205
  include SimpleRecord::Attributes
186
206
  extend SimpleRecord::Sharding::ClassMethods
187
207
  include SimpleRecord::Sharding
188
- include SimpleRecord::Callbacks
189
208
  include SimpleRecord::Json
190
209
  include SimpleRecord::Logging
191
210
  extend SimpleRecord::Logging::ClassMethods
@@ -362,11 +381,10 @@ module SimpleRecord
362
381
  end
363
382
 
364
383
  def clear_errors
365
- # @errors=SimpleRecord_errors.new
366
- if not (defined?(ActiveModel))
367
- @errors=SimpleRecord_errors.new
368
- else
384
+ if defined?(ActiveModel)
369
385
  @errors = ActiveModel::Errors.new(self)
386
+ else
387
+ @errors=SimpleRecord_errors.new
370
388
  end
371
389
  end
372
390
 
@@ -398,9 +416,6 @@ module SimpleRecord
398
416
  self.updated
399
417
  end
400
418
 
401
- def read_attribute_for_validation(key)
402
- @attributes[key.to_s]
403
- end
404
419
 
405
420
  def cache_store
406
421
  @@cache_store
@@ -429,8 +444,9 @@ module SimpleRecord
429
444
  # - :dirty => true - Will only store attributes that were modified. To make it save regardless and have it update the :updated value, include this and set it to false.
430
445
  # - :domain => Explicitly define domain to use.
431
446
  #
447
+
432
448
  def save(options={})
433
- # puts 'SAVING: ' + self.inspect if SimpleRecord.logging?
449
+ puts 'SAVING: ' + self.inspect if SimpleRecord.logging?
434
450
  # todo: Clean out undefined values in @attributes (in case someone set the attributes hash with values that they hadn't defined)
435
451
  clear_errors
436
452
  # todo: decide whether this should go before pre_save or after pre_save? pre_save dirties "updated" and perhaps other items due to callbacks
@@ -441,6 +457,7 @@ module SimpleRecord
441
457
  is_create = self[:id].nil?
442
458
  ok = pre_save(options) # Validates and sets ID
443
459
  if ok
460
+ # puts 'ok'
444
461
  begin
445
462
  dirty = @dirty
446
463
  # puts 'dirty before=' + @dirty.inspect
@@ -449,48 +466,119 @@ module SimpleRecord
449
466
  return true if @dirty.size == 0 # This should probably never happen because after pre_save, created/updated dates are changed
450
467
  options[:dirty_atts] = @dirty
451
468
  end
452
- to_delete = get_atts_to_delete
453
- SimpleRecord.stats.saves += 1
469
+ to_delete = get_atts_to_delete
470
+
454
471
 
455
472
  if self.class.is_sharded?
456
473
  options[:domain] = sharded_domain
457
474
  end
458
475
 
459
- if super(options)
460
- self.class.cache_results(self)
461
- delete_niled(to_delete)
462
- save_lobs(dirty)
463
- after_save_cleanup
464
- if (is_create ? run_after_create : run_after_update) && run_after_save
465
- # puts 'all good?'
466
- return true
467
- else
468
- return false
469
- end
476
+ if @@active_model
477
+ x = save_super(dirty, is_create, options, to_delete)
478
+ # puts 'save_super result = ' + x.to_s
479
+ return x
470
480
  else
471
- return false
481
+ # puts 'not activemodel callbacks'
482
+ return save_super(dirty, is_create, options, to_delete)
472
483
  end
473
484
  rescue Aws::AwsError => ex
474
- # puts "RESCUED in save: " + $!
475
- # Domain is created in aws lib now using :create_domain=>true
476
- # if (domain_ok(ex, options))
477
- # if !@create_domain_called
478
- # @create_domain_called = true
479
- # save(options)
480
- # else
481
- # raise $!
482
- # end
483
- # else
484
- # raise $!
485
- # end
486
485
  raise ex
487
486
  end
488
487
  else
489
- #@debug = "not saved"
488
+ # puts 'returning false'
490
489
  return false
491
490
  end
492
491
  end
493
492
 
493
+ if @@active_model
494
+ alias_method :old_save, :save
495
+
496
+ def save(options={})
497
+ # puts 'extended save'
498
+ x = create_or_update
499
+ # puts 'save x=' + x.to_s
500
+ x
501
+ end
502
+ end
503
+
504
+ def create_or_update #:nodoc:
505
+ # puts 'create_or_update'
506
+ ret = true
507
+ _run_save_callbacks do
508
+ result = new_record? ? create : update
509
+ # puts 'save_callbacks result=' + result.inspect
510
+ ret = result
511
+ end
512
+ ret
513
+ end
514
+
515
+ def create #:nodoc:
516
+ puts '3 create'
517
+ ret = true
518
+ _run_create_callbacks do
519
+ x = old_save
520
+ # puts 'create old_save result=' + x.to_s
521
+ ret = x
522
+ end
523
+ ret
524
+ end
525
+
526
+ #
527
+ def update(*) #:nodoc:
528
+ puts '3 update'
529
+ ret = true
530
+ _run_update_callbacks do
531
+ x = old_save
532
+ # puts 'update old_save result=' + x.to_s
533
+ ret = x
534
+ end
535
+ ret
536
+ end
537
+
538
+
539
+ def save!(options={})
540
+ save(options) || raise(RecordNotSaved.new(self))
541
+ end
542
+
543
+ # this is a bit wonky, save! should call this, not sure why it's here.
544
+ def save_with_validation!(options={})
545
+ save!
546
+ end
547
+
548
+ def self.create(attributes={})
549
+ # puts "About to create in domain #{domain}"
550
+ super
551
+ end
552
+
553
+ def self.create!(attributes={})
554
+ item = self.new(attributes)
555
+ item.save!
556
+ item
557
+ end
558
+
559
+
560
+ def save_super(dirty, is_create, options, to_delete)
561
+ SimpleRecord.stats.saves += 1
562
+ if save2(options)
563
+ self.class.cache_results(self)
564
+ delete_niled(to_delete)
565
+ save_lobs(dirty)
566
+ after_save_cleanup
567
+ unless @@active_model
568
+ if (is_create ? run_after_create : run_after_update) && run_after_save
569
+ # puts 'all good?'
570
+ return true
571
+ else
572
+ return false
573
+ end
574
+ end
575
+ return true
576
+ else
577
+ return false
578
+ end
579
+ end
580
+
581
+
494
582
  def save_lobs(dirty=nil)
495
583
  # puts 'dirty.inspect=' + dirty.inspect
496
584
  dirty = @dirty if dirty.nil?
@@ -600,26 +688,6 @@ module SimpleRecord
600
688
  "lobs/#{self.id}_single_clob"
601
689
  end
602
690
 
603
- def save!(options={})
604
- save(options) || raise(RecordNotSaved.new(nil, self))
605
- end
606
-
607
- # this is a bit wonky, save! should call this, not sure why it's here.
608
- def save_with_validation!(options={})
609
- save!
610
- end
611
-
612
- def self.create(attributes={})
613
- # puts "About to create in domain #{domain}"
614
- super
615
- end
616
-
617
- def self.create!(attributes={})
618
- item = self.new(attributes)
619
- item.save!
620
- item
621
- end
622
-
623
691
 
624
692
  def self.get_encryption_key()
625
693
  key = SimpleRecord.options[:encryption_key]
@@ -630,28 +698,20 @@ module SimpleRecord
630
698
  return key
631
699
  end
632
700
 
633
- def validate
634
- true
635
- end
636
-
637
- def validate_on_create
638
- true
639
- end
640
-
641
- def validate_on_update
642
- true
643
- end
644
-
645
-
646
701
  def pre_save(options)
647
702
 
703
+
704
+ ok = true
648
705
  is_create = self[:id].nil?
649
- ok = run_before_validation && (is_create ? run_before_validation_on_create : run_before_validation_on_update)
650
- return false unless ok
706
+ unless @@active_model
707
+ ok = run_before_validation && (is_create ? run_before_validation_on_create : run_before_validation_on_update)
708
+ return false unless ok
709
+ end
651
710
 
652
711
  # validate()
653
712
  # is_create ? validate_on_create : validate_on_update
654
713
  if !valid?
714
+ puts 'not valid'
655
715
  return false
656
716
  end
657
717
  #
@@ -661,23 +721,26 @@ module SimpleRecord
661
721
  # return false
662
722
  # end
663
723
 
664
- ok = run_after_validation && (is_create ? run_after_validation_on_create : run_after_validation_on_update)
665
- return false unless ok
724
+ unless @@active_model
725
+ ok = run_after_validation && (is_create ? run_after_validation_on_create : run_after_validation_on_update)
726
+ return false unless ok
727
+ end
666
728
 
667
- ok = respond_to?('before_save') ? before_save : true
668
- if ok
669
- if is_create && respond_to?('before_create')
670
- ok = before_create
671
- elsif !is_create && respond_to?('before_update')
672
- ok = before_update
729
+ # Now for callbacks
730
+ unless @@active_model
731
+ ok = respond_to?('before_save') ? before_save : true
732
+ if ok
733
+ if is_create && respond_to?('before_create')
734
+ ok = before_create
735
+ elsif !is_create && respond_to?('before_update')
736
+ ok = before_update
737
+ end
673
738
  end
674
- end
675
- if ok
676
- ok = run_before_save && (is_create ? run_before_create : run_before_update)
677
- end
678
- if ok
679
- # Now translate all fields into SimpleDB friendly strings
680
- # convert_all_atts_to_sdb()
739
+ if ok
740
+ ok = run_before_save && (is_create ? run_before_create : run_before_update)
741
+ end
742
+ else
743
+
681
744
  end
682
745
  prepare_for_update
683
746
  ok
@@ -779,10 +842,15 @@ module SimpleRecord
779
842
  end
780
843
 
781
844
  def destroy
782
- return run_before_destroy && delete && run_after_destroy
845
+ if @@active_model
846
+ _run_destroy_callbacks do
847
+ delete
848
+ end
849
+ else
850
+ return run_before_destroy && delete && run_after_destroy
851
+ end
783
852
  end
784
853
 
785
-
786
854
  def delete_niled(to_delete)
787
855
  # puts 'to_delete=' + to_delete.inspect
788
856
  if to_delete.size > 0
@@ -861,6 +929,11 @@ module SimpleRecord
861
929
  if params.size > 1
862
930
  options = params[1]
863
931
  end
932
+ conditions = options[:conditions]
933
+ if conditions && conditions.is_a?(String)
934
+ conditions = [conditions]
935
+ options[:conditions] = conditions
936
+ end
864
937
 
865
938
  if !options[:shard_find] && is_sharded?
866
939
  # then break off and get results across all shards
@@ -958,7 +1031,8 @@ module SimpleRecord
958
1031
  def self.convert_condition_params(options)
959
1032
  return if options.nil?
960
1033
  conditions = options[:conditions]
961
- if !conditions.nil? && conditions.size > 1
1034
+ return if conditions.nil?
1035
+ if conditions.size > 1
962
1036
  # all after first are values
963
1037
  conditions.collect! { |x|
964
1038
  Translations.pad_and_offset(x)
@@ -856,7 +856,7 @@ module SimpleRecord
856
856
  # - :except => Array of attributes to NOT save
857
857
  #
858
858
  # compare to +put+ method
859
- def save(options={})
859
+ def save2(options={})
860
860
  options[:create_domain] = true if options[:create_domain].nil?
861
861
  pre_save2
862
862
  atts_to_save = @attributes.dup
@@ -346,14 +346,14 @@ module SimpleRecord
346
346
  begin
347
347
  single_clob = s3_bucket(false, :s3_bucket=>:new).get(single_clob_id)
348
348
  single_clob = JSON.parse(single_clob)
349
- puts "single_clob=" + single_clob.inspect
349
+ # puts "single_clob=" + single_clob.inspect
350
350
  single_clob.each_pair do |name2,val|
351
351
  @lobs[name2.to_sym] = val
352
352
  end
353
353
  ret = @lobs[name]
354
354
  SimpleRecord.stats.s3_gets += 1
355
355
  rescue Aws::AwsError => ex
356
- if ex.include? /NoSuchKey/
356
+ if ex.include?(/NoSuchKey/) || ex.include?(/NoSuchBucket/)
357
357
  ret = nil
358
358
  else
359
359
  raise ex
@@ -365,7 +365,7 @@ module SimpleRecord
365
365
  # puts 'got from s3 ' + ret.inspect
366
366
  SimpleRecord.stats.s3_gets += 1
367
367
  rescue Aws::AwsError => ex
368
- if ex.include? /NoSuchKey/
368
+ if ex.include?(/NoSuchKey/) || ex.include?(/NoSuchBucket/)
369
369
  ret = nil
370
370
  else
371
371
  raise ex