simple_record 2.1.10 → 2.1.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -62,18 +62,18 @@ module SimpleRecord
62
62
  class << self;
63
63
  attr_accessor :aws_access_key, :aws_secret_key
64
64
 
65
- # Deprecated
65
+ # Deprecated
66
66
  def enable_logging
67
67
  @@logging = true
68
68
  @@logger.level = Logger::DEBUG
69
69
  end
70
70
 
71
- # Deprecated
71
+ # Deprecated
72
72
  def disable_logging
73
73
  @@logging = false
74
74
  end
75
75
 
76
- # Deprecated
76
+ # Deprecated
77
77
  def logging?
78
78
  @@logging
79
79
  end
@@ -82,9 +82,9 @@ module SimpleRecord
82
82
  @@logger
83
83
  end
84
84
 
85
- # This can be used to log queries and what not to a file.
86
- # Params:
87
- # :select=>{:filename=>"file_to_write_to", :format=>"csv"}
85
+ # This can be used to log queries and what not to a file.
86
+ # Params:
87
+ # :select=>{:filename=>"file_to_write_to", :format=>"csv"}
88
88
  def log_usage(types={})
89
89
  @usage_logging_options = {} unless @usage_logging_options
90
90
  return if types.nil?
@@ -109,26 +109,26 @@ module SimpleRecord
109
109
  end
110
110
 
111
111
 
112
- # Create a new handle to an Sdb account. All handles share the same per process or per thread
113
- # HTTP connection to Amazon Sdb. Each handle is for a specific account.
114
- # The +params+ are passed through as-is to Aws::SdbInterface.new
115
- # Params:
116
- # { :server => 'sdb.amazonaws.com' # Amazon service host: 'sdb.amazonaws.com'(default)
117
- # :port => 443 # Amazon service port: 80(default) or 443
118
- # :protocol => 'https' # Amazon service protocol: 'http'(default) or 'https'
119
- # :signature_version => '0' # The signature version : '0' or '1'(default)
120
- # :connection_mode => :default # options are
121
- # :default (will use best known safe (as in won't need explicit close) option, may change in the future)
122
- # :per_request (opens and closes a connection on every request to SDB)
123
- # :single (one thread across entire app)
124
- # :per_thread (one connection per thread)
125
- # :pool (uses a connection pool with a maximum number of connections - NOT IMPLEMENTED YET)
126
- # :logger => Logger Object # Logger instance: logs to STDOUT if omitted
112
+ # Create a new handle to an Sdb account. All handles share the same per process or per thread
113
+ # HTTP connection to Amazon Sdb. Each handle is for a specific account.
114
+ # The +params+ are passed through as-is to Aws::SdbInterface.new
115
+ # Params:
116
+ # { :server => 'sdb.amazonaws.com' # Amazon service host: 'sdb.amazonaws.com'(default)
117
+ # :port => 443 # Amazon service port: 80(default) or 443
118
+ # :protocol => 'https' # Amazon service protocol: 'http'(default) or 'https'
119
+ # :signature_version => '0' # The signature version : '0' or '1'(default)
120
+ # :connection_mode => :default # options are
121
+ # :default (will use best known safe (as in won't need explicit close) option, may change in the future)
122
+ # :per_request (opens and closes a connection on every request to SDB)
123
+ # :single (one thread across entire app)
124
+ # :per_thread (one connection per thread)
125
+ # :pool (uses a connection pool with a maximum number of connections - NOT IMPLEMENTED YET)
126
+ # :logger => Logger Object # Logger instance: logs to STDOUT if omitted
127
127
  def establish_connection(aws_access_key=nil, aws_secret_key=nil, options={})
128
128
  @aws_access_key = aws_access_key
129
129
  @aws_secret_key = aws_secret_key
130
130
  @@options.merge!(options)
131
- #puts 'SimpleRecord.establish_connection with options: ' + @@options.inspect
131
+ #puts 'SimpleRecord.establish_connection with options: ' + @@options.inspect
132
132
  SimpleRecord::ActiveSdb.establish_connection(aws_access_key, aws_secret_key, @@options)
133
133
  if options[:connection_mode] == :per_thread
134
134
  @@auto_close_s3 = true
@@ -147,17 +147,17 @@ module SimpleRecord
147
147
 
148
148
  end
149
149
 
150
- # Call this to close the connection to SimpleDB.
151
- # If you're using this in Rails with per_thread connection mode, you should do this in
152
- # an after_filter for each request.
150
+ # Call this to close the connection to SimpleDB.
151
+ # If you're using this in Rails with per_thread connection mode, you should do this in
152
+ # an after_filter for each request.
153
153
  def close_connection()
154
154
  SimpleRecord::ActiveSdb.close_connection
155
155
  @@s3.close_connection if @@auto_close_s3
156
156
  end
157
157
 
158
- # If you'd like to specify the s3 connection to use for LOBs, you can pass it in here.
159
- # We recommend that this connection matches the type of connection you're using for SimpleDB,
160
- # at least if you're using per_thread connection mode.
158
+ # If you'd like to specify the s3 connection to use for LOBs, you can pass it in here.
159
+ # We recommend that this connection matches the type of connection you're using for SimpleDB,
160
+ # at least if you're using per_thread connection mode.
161
161
  def s3=(s3)
162
162
  @@s3 = s3
163
163
  end
@@ -196,7 +196,7 @@ module SimpleRecord
196
196
  include SimpleRecord::Callbacks
197
197
  end
198
198
  include SimpleRecord::Validations
199
-
199
+ extend SimpleRecord::Validations::ClassMethods
200
200
 
201
201
  include SimpleRecord::Translations
202
202
  # include SimpleRecord::Attributes
@@ -217,7 +217,7 @@ module SimpleRecord
217
217
 
218
218
  initialize_base(attrs)
219
219
 
220
- # Convert attributes to sdb values
220
+ # Convert attributes to sdb values
221
221
  attrs.each_pair do |name, value|
222
222
  set(name, value, true)
223
223
  end
@@ -226,7 +226,7 @@ module SimpleRecord
226
226
  def initialize_base(attrs={})
227
227
 
228
228
  #we have to handle the virtuals.
229
- Attributes.handle_virtuals(attrs)
229
+ handle_virtuals(attrs)
230
230
 
231
231
  clear_errors
232
232
 
@@ -278,10 +278,10 @@ module SimpleRecord
278
278
  attr_accessor :domain_prefix
279
279
  end
280
280
 
281
- #@domain_name_for_class = nil
281
+ #@domain_name_for_class = nil
282
282
 
283
283
  @@cache_store = nil
284
- # Set the cache to use
284
+ # Set the cache to use
285
285
  def self.cache_store=(cache)
286
286
  @@cache_store = cache
287
287
  end
@@ -290,18 +290,18 @@ module SimpleRecord
290
290
  return @@cache_store
291
291
  end
292
292
 
293
- # If you want a domain prefix for all your models, set it here.
293
+ # If you want a domain prefix for all your models, set it here.
294
294
  def self.set_domain_prefix(prefix)
295
295
  #puts 'set_domain_prefix=' + prefix
296
296
  self.domain_prefix = prefix
297
297
  end
298
298
 
299
- # Same as set_table_name
299
+ # Same as set_table_name
300
300
  def self.set_table_name(table_name)
301
301
  set_domain_name table_name
302
302
  end
303
303
 
304
- # Sets the domain name for this class
304
+ # Sets the domain name for this class
305
305
  def self.set_domain_name(table_name)
306
306
  super
307
307
  end
@@ -405,12 +405,12 @@ module SimpleRecord
405
405
  set(SimpleRecord.options[:updated_col] || :updated, Time.now)
406
406
  end
407
407
 
408
- # an aliased method since many people use created_at/updated_at naming convention
408
+ # an aliased method since many people use created_at/updated_at naming convention
409
409
  def created_at
410
410
  self.created
411
411
  end
412
412
 
413
- # an aliased method since many people use created_at/updated_at naming convention
413
+ # an aliased method since many people use created_at/updated_at naming convention
414
414
  def updated_at
415
415
  self.updated
416
416
  end
@@ -438,17 +438,17 @@ module SimpleRecord
438
438
 
439
439
  @create_domain_called = false
440
440
 
441
- # Options:
442
- # - :except => Array of attributes to NOT save
443
- # - :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.
444
- # - :domain => Explicitly define domain to use.
445
- #
441
+ # Options:
442
+ # - :except => Array of attributes to NOT save
443
+ # - :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.
444
+ # - :domain => Explicitly define domain to use.
445
+ #
446
446
 
447
447
  def save(options={})
448
448
  puts 'SAVING: ' + self.inspect if SimpleRecord.logging?
449
- # todo: Clean out undefined values in @attributes (in case someone set the attributes hash with values that they hadn't defined)
449
+ # todo: Clean out undefined values in @attributes (in case someone set the attributes hash with values that they hadn't defined)
450
450
  clear_errors
451
- # todo: decide whether this should go before pre_save or after pre_save? pre_save dirties "updated" and perhaps other items due to callbacks
451
+ # todo: decide whether this should go before pre_save or after pre_save? pre_save dirties "updated" and perhaps other items due to callbacks
452
452
  if options[:dirty]
453
453
  # puts '@dirtyA=' + @dirty.inspect
454
454
  return true if @dirty.size == 0 # Nothing to save so skip it
@@ -470,7 +470,7 @@ module SimpleRecord
470
470
  is_create = new_record? # self[:id].nil?
471
471
 
472
472
  dirty = @dirty
473
- # puts 'dirty before=' + @dirty.inspect
473
+ # puts 'dirty before=' + @dirty.inspect
474
474
  if options[:dirty]
475
475
  # puts '@dirty=' + @dirty.inspect
476
476
  return true if @dirty.size == 0 # This should probably never happen because after pre_save, created/updated dates are changed
@@ -500,7 +500,7 @@ module SimpleRecord
500
500
  # end
501
501
 
502
502
  def create_or_update(options) #:nodoc:
503
- # puts 'create_or_update'
503
+ # puts 'create_or_update'
504
504
  ret = true
505
505
  _run_save_callbacks do
506
506
  result = new_record? ? create(options) : update(options)
@@ -538,7 +538,7 @@ module SimpleRecord
538
538
  save(options) || raise(RecordNotSaved.new(self))
539
539
  end
540
540
 
541
- # this is a bit wonky, save! should call this, not sure why it's here.
541
+ # this is a bit wonky, save! should call this, not sure why it's here.
542
542
  def save_with_validation!(options={})
543
543
  save!
544
544
  end
@@ -642,21 +642,21 @@ module SimpleRecord
642
642
 
643
643
  def is_dirty?(name)
644
644
  # todo: should change all the dirty stuff to symbols?
645
- # puts '@dirty=' + @dirty.inspect
646
- # puts 'name=' +name.to_s
645
+ # puts '@dirty=' + @dirty.inspect
646
+ # puts 'name=' +name.to_s
647
647
  @dirty.include? name.to_s
648
648
  end
649
649
 
650
650
  def s3
651
651
 
652
652
  return SimpleRecord.s3 if SimpleRecord.s3
653
- # todo: should optimize this somehow, like use the same connection_mode as used in SR
654
- # or keep open while looping in ResultsArray.
653
+ # todo: should optimize this somehow, like use the same connection_mode as used in SR
654
+ # or keep open while looping in ResultsArray.
655
655
  Aws::S3.new(SimpleRecord.aws_access_key, SimpleRecord.aws_secret_key)
656
656
  end
657
657
 
658
- # options:
659
- # :s3_bucket => :old/:new/"#{any_bucket_name}". :new if want to use new bucket. Defaults to :old for backwards compatability.
658
+ # options:
659
+ # :s3_bucket => :old/:new/"#{any_bucket_name}". :new if want to use new bucket. Defaults to :old for backwards compatability.
660
660
  def s3_bucket(create=false, options={})
661
661
  s3.bucket(s3_bucket_name(options[:s3_bucket]), create)
662
662
  end
@@ -725,7 +725,7 @@ module SimpleRecord
725
725
  return false unless ok
726
726
  end
727
727
 
728
- # Now for callbacks
728
+ # Now for callbacks
729
729
  unless @@active_model
730
730
  ok = respond_to?(:before_save) ? before_save : true
731
731
  if ok
@@ -766,8 +766,8 @@ module SimpleRecord
766
766
  return to_delete
767
767
  end
768
768
 
769
- # Run pre_save on each object, then runs batch_put_attributes
770
- # Returns
769
+ # Run pre_save on each object, then runs batch_put_attributes
770
+ # Returns
771
771
  def self.batch_save(objects, options={})
772
772
  options[:create_domain] = true if options[:create_domain].nil?
773
773
  results = []
@@ -793,7 +793,7 @@ module SimpleRecord
793
793
  results
794
794
  end
795
795
 
796
- # Pass in an array of objects
796
+ # Pass in an array of objects
797
797
  def self.batch_delete(objects, options={})
798
798
  if objects
799
799
  # 25 item limit, we should maybe handle this limit in here.
@@ -801,15 +801,15 @@ module SimpleRecord
801
801
  end
802
802
  end
803
803
 
804
- #
805
- # Usage: ClassName.delete id
806
- #
804
+ #
805
+ # Usage: ClassName.delete id
806
+ #
807
807
  def self.delete(id)
808
808
  connection.delete_attributes(domain, id)
809
809
  @deleted = true
810
810
  end
811
811
 
812
- # Pass in the same OPTIONS you'd pass into a find(:all, OPTIONS)
812
+ # Pass in the same OPTIONS you'd pass into a find(:all, OPTIONS)
813
813
  def self.delete_all(options={})
814
814
  # could make this quicker by just getting item_names and deleting attributes rather than creating objects
815
815
  obs = self.find(:all, options)
@@ -821,7 +821,7 @@ module SimpleRecord
821
821
  return i
822
822
  end
823
823
 
824
- # Pass in the same OPTIONS you'd pass into a find(:all, OPTIONS)
824
+ # Pass in the same OPTIONS you'd pass into a find(:all, OPTIONS)
825
825
  def self.destroy_all(options={})
826
826
  obs = self.find(:all, options)
827
827
  i = 0
@@ -838,7 +838,7 @@ module SimpleRecord
838
838
  end
839
839
  super(options)
840
840
 
841
- # delete lobs now too
841
+ # delete lobs now too
842
842
  delete_lobs
843
843
  end
844
844
 
@@ -885,7 +885,7 @@ module SimpleRecord
885
885
 
886
886
  def self.quote_regexp(a, re)
887
887
  a =~ re
888
- #was there a match?
888
+ #was there a match?
889
889
  if $&
890
890
  before=$`
891
891
  middle=$&
@@ -905,19 +905,19 @@ module SimpleRecord
905
905
 
906
906
  @@regex_no_id = /.*Couldn't find.*with ID.*/
907
907
 
908
- #
909
- # Usage:
910
- # Find by ID:
911
- # MyModel.find(ID)
912
- #
913
- # Query example:
914
- # MyModel.find(:all, :conditions=>["name = ?", name], :order=>"created desc", :limit=>10)
915
- #
916
- # Extra options:
917
- # :per_token => the number of results to return per next_token, max is 2500.
918
- # :consistent_read => true/false -- as per http://developer.amazonwebservices.com/connect/entry.jspa?externalID=3572
919
- # :retries => maximum number of times to retry this query on an error response.
920
- # :shard => shard name or array of shard names to use on this query.
908
+ #
909
+ # Usage:
910
+ # Find by ID:
911
+ # MyModel.find(ID)
912
+ #
913
+ # Query example:
914
+ # MyModel.find(:all, :conditions=>["name = ?", name], :order=>"created desc", :limit=>10)
915
+ #
916
+ # Extra options:
917
+ # :per_token => the number of results to return per next_token, max is 2500.
918
+ # :consistent_read => true/false -- as per http://developer.amazonwebservices.com/connect/entry.jspa?externalID=3572
919
+ # :retries => maximum number of times to retry this query on an error response.
920
+ # :shard => shard name or array of shard names to use on this query.
921
921
  def self.find(*params)
922
922
  #puts 'params=' + params.inspect
923
923
 
@@ -941,12 +941,12 @@ module SimpleRecord
941
941
  return find_sharded(*params)
942
942
  end
943
943
 
944
- # Pad and Offset number attributes
944
+ # Pad and Offset number attributes
945
945
  params_dup = params.dup
946
946
  if params.size > 1
947
947
  options = params[1]
948
- #puts 'options=' + options.inspect
949
- #puts 'after collect=' + options.inspect
948
+ #puts 'options=' + options.inspect
949
+ #puts 'after collect=' + options.inspect
950
950
  convert_condition_params(options)
951
951
  per_token = options[:per_token]
952
952
  consistent_read = options[:consistent_read]
@@ -957,20 +957,20 @@ module SimpleRecord
957
957
  params_dup[1] = op_dup
958
958
  end
959
959
  end
960
- # puts 'params2=' + params.inspect
960
+ # puts 'params2=' + params.inspect
961
961
 
962
962
  ret = q_type == :all ? [] : nil
963
963
  begin
964
964
  results=find_with_metadata(*params_dup)
965
965
  #puts "RESULT=" + results.inspect
966
966
  write_usage(:select, domain, q_type, options, results)
967
- #puts 'params3=' + params.inspect
967
+ #puts 'params3=' + params.inspect
968
968
  SimpleRecord.stats.selects += 1
969
969
  if q_type == :count
970
970
  ret = results[:count]
971
971
  elsif q_type == :first
972
972
  ret = results[:items].first
973
- # todo: we should store request_id and box_usage with the object maybe?
973
+ # todo: we should store request_id and box_usage with the object maybe?
974
974
  cache_results(ret)
975
975
  elsif results[:single_only]
976
976
  ret = results[:single]
@@ -987,14 +987,14 @@ module SimpleRecord
987
987
  #puts "RESCUED: " + ex.message
988
988
  if (ex.message().index("NoSuchDomain") != nil)
989
989
  # this is ok
990
- # elsif (ex.message() =~ @@regex_no_id) This is RecordNotFound now
991
- # ret = nil
990
+ # elsif (ex.message() =~ @@regex_no_id) This is RecordNotFound now
991
+ # ret = nil
992
992
  else
993
993
  #puts 're-raising'
994
994
  raise ex
995
995
  end
996
996
  end
997
- # puts 'single2=' + ret.inspect
997
+ # puts 'single2=' + ret.inspect
998
998
  return ret
999
999
  end
1000
1000
 
@@ -1014,8 +1014,8 @@ module SimpleRecord
1014
1014
  find(:count, *args)
1015
1015
  end
1016
1016
 
1017
- # This gets less and less efficient the higher the page since SimpleDB has no way
1018
- # to start at a specific row. So it will iterate from the first record and pull out the specific pages.
1017
+ # This gets less and less efficient the higher the page since SimpleDB has no way
1018
+ # to start at a specific row. So it will iterate from the first record and pull out the specific pages.
1019
1019
  def self.paginate(options={})
1020
1020
  # options = args.pop
1021
1021
  # puts 'paginate options=' + options.inspect if SimpleRecord.logging?
@@ -1053,14 +1053,14 @@ module SimpleRecord
1053
1053
  class_name = item.class.name
1054
1054
  id = item.id
1055
1055
  cache_key = self.cache_key(class_name, id)
1056
- #puts 'caching result at ' + cache_key + ': ' + results.inspect
1056
+ #puts 'caching result at ' + cache_key + ': ' + results.inspect
1057
1057
  cache_store.write(cache_key, item, :expires_in =>30)
1058
1058
  end
1059
1059
  else
1060
1060
  class_name = results.class.name
1061
1061
  id = results.id
1062
1062
  cache_key = self.cache_key(class_name, id)
1063
- #puts 'caching result at ' + cache_key + ': ' + results.inspect
1063
+ #puts 'caching result at ' + cache_key + ': ' + results.inspect
1064
1064
  cache_store.write(cache_key, results, :expires_in =>30)
1065
1065
  end
1066
1066
  end
@@ -1094,7 +1094,7 @@ module SimpleRecord
1094
1094
 
1095
1095
  def changes
1096
1096
  ret = {}
1097
- #puts 'in CHANGES=' + @dirty.inspect
1097
+ #puts 'in CHANGES=' + @dirty.inspect
1098
1098
  @dirty.each_pair { |key, value| ret[key] = [value, get_attribute(key)] }
1099
1099
  return ret
1100
1100
  end
@@ -1119,7 +1119,7 @@ module SimpleRecord
1119
1119
  @referencevalue=referencevalue
1120
1120
  end
1121
1121
 
1122
- # Performance optimization if you know the array should be empty
1122
+ # Performance optimization if you know the array should be empty
1123
1123
 
1124
1124
  def init_empty
1125
1125
  @records = []
@@ -1177,7 +1177,7 @@ module SimpleRecord
1177
1177
 
1178
1178
  def find(*params)
1179
1179
  query=[:first, {}]
1180
- #{:conditions=>"id=>1"}
1180
+ #{:conditions=>"id=>1"}
1181
1181
  if params[0]
1182
1182
  if params[0]==:all
1183
1183
  query[0]=:all
@@ -1203,7 +1203,7 @@ module SimpleRecord
1203
1203
 
1204
1204
  end
1205
1205
 
1206
- # This is simply a place holder so we don't keep doing gets to s3 or simpledb if already checked.
1206
+ # This is simply a place holder so we don't keep doing gets to s3 or simpledb if already checked.
1207
1207
  class RemoteNil
1208
1208
 
1209
1209
  end
@@ -58,14 +58,14 @@ module SimpleRecord
58
58
  attr = Attribute.new(type, arg_options)
59
59
  defined_attributes[arg] = attr if defined_attributes[arg].nil?
60
60
 
61
- # define reader method
61
+ # define reader method
62
62
  arg_s = arg.to_s # to get rid of all the to_s calls
63
63
  send(:define_method, arg) do
64
64
  ret = get_attribute(arg)
65
65
  return ret
66
66
  end
67
67
 
68
- # define writer method
68
+ # define writer method
69
69
  send(:define_method, arg_s+"=") do |value|
70
70
  set(arg, value)
71
71
  end
@@ -81,13 +81,13 @@ module SimpleRecord
81
81
  @dirty.has_key?(sdb_att_name(arg_s))
82
82
  end
83
83
 
84
- # define change method
84
+ # define change method
85
85
  send(:define_method, arg_s + "_change") do
86
86
  old_val = @dirty[sdb_att_name(arg_s)]
87
87
  [old_val, get_attribute(arg_s)]
88
88
  end
89
89
 
90
- # define was method
90
+ # define was method
91
91
  send(:define_method, arg_s + "_was") do
92
92
  old_val = @dirty[sdb_att_name(arg_s)]
93
93
  old_val
@@ -149,21 +149,26 @@ module SimpleRecord
149
149
 
150
150
  end
151
151
 
152
+ def virtuals
153
+ @virtuals ||= []
154
+ @virtuals
155
+ end
156
+
152
157
  def has_virtuals(*args)
153
- @@virtuals = args
158
+ virtuals.concat(args)
154
159
  args.each do |arg|
155
160
  #we just create the accessor functions here, the actual instance variable is created during initialize
156
161
  attr_accessor(arg)
157
162
  end
158
163
  end
159
164
 
160
- # One belongs_to association per call. Call multiple times if there are more than one.
161
- #
162
- # This method will also create an {association)_id method that will return the ID of the foreign object
163
- # without actually materializing it.
164
- #
165
- # options:
166
- # :class_name=>"User" - to change the default class to use
165
+ # One belongs_to association per call. Call multiple times if there are more than one.
166
+ #
167
+ # This method will also create an {association)_id method that will return the ID of the foreign object
168
+ # without actually materializing it.
169
+ #
170
+ # options:
171
+ # :class_name=>"User" - to change the default class to use
167
172
  def belongs_to(association_id, options = {})
168
173
  arg = association_id
169
174
  arg_s = arg.to_s
@@ -171,29 +176,29 @@ module SimpleRecord
171
176
  attribute = Attribute.new(:belongs_to, options)
172
177
  defined_attributes[arg] = attribute
173
178
 
174
- # todo: should also handle foreign_key http://74.125.95.132/search?q=cache:KqLkxuXiBBQJ:wiki.rubyonrails.org/rails/show/belongs_to+rails+belongs_to&hl=en&ct=clnk&cd=1&gl=us
175
- # puts "arg_id=#{arg}_id"
176
- # puts "is defined? " + eval("(defined? #{arg}_id)").to_s
177
- # puts 'atts=' + @attributes.inspect
179
+ # todo: should also handle foreign_key http://74.125.95.132/search?q=cache:KqLkxuXiBBQJ:wiki.rubyonrails.org/rails/show/belongs_to+rails+belongs_to&hl=en&ct=clnk&cd=1&gl=us
180
+ # puts "arg_id=#{arg}_id"
181
+ # puts "is defined? " + eval("(defined? #{arg}_id)").to_s
182
+ # puts 'atts=' + @attributes.inspect
178
183
 
179
- # Define reader method
184
+ # Define reader method
180
185
  send(:define_method, arg) do
181
186
  return get_attribute(arg)
182
187
  end
183
188
 
184
189
 
185
- # Define writer method
190
+ # Define writer method
186
191
  send(:define_method, arg.to_s + "=") do |value|
187
192
  set(arg, value)
188
193
  end
189
194
 
190
195
 
191
- # Define ID reader method for reading the associated objects id without getting the entire object
196
+ # Define ID reader method for reading the associated objects id without getting the entire object
192
197
  send(:define_method, arg_id) do
193
198
  get_attribute_sdb(arg_s)
194
199
  end
195
200
 
196
- # Define writer method for setting the _id directly without the associated object
201
+ # Define writer method for setting the _id directly without the associated object
197
202
  send(:define_method, arg_id + "=") do |value|
198
203
  # rb_att_name = arg_s # n2 = name.to_s[0, name.length-3]
199
204
  set(arg_id, value)
@@ -237,14 +242,16 @@ module SimpleRecord
237
242
 
238
243
  end
239
244
 
240
- @@virtuals=[]
241
-
242
- def self.handle_virtuals(attrs)
243
- @@virtuals.each do |virtual|
244
- #we first copy the information for the virtual to an instance variable of the same name
245
- eval("@#{virtual}=attrs['#{virtual}']")
246
- #and then remove the parameter before it is passed to initialize, so that it is NOT sent to SimpleDB
247
- eval("attrs.delete('#{virtual}')")
245
+ def handle_virtuals(attrs)
246
+ puts 'handle_virtuals'
247
+ self.class.virtuals.each do |virtual|
248
+ puts 'virtual=' + virtual.inspect
249
+ #we first copy the information for the virtual to an instance variable of the same name
250
+ send("#{virtual}=", attrs[virtual])
251
+ #eval("@#{virtual}=attrs['#{virtual}']")
252
+ #and then remove the parameter before it is passed to initialize, so that it is NOT sent to SimpleDB
253
+ attrs.delete(virtual)
254
+ #eval("attrs.delete('#{virtual}')")
248
255
  end
249
256
  end
250
257
 
@@ -289,17 +296,17 @@ module SimpleRecord
289
296
  attname = name.to_s
290
297
  attvalue = att_meta.init_value(value)
291
298
  # attvalue = value
292
- #puts 'converted ' + value.inspect + ' to ' + attvalue.inspect
299
+ #puts 'converted ' + value.inspect + ' to ' + attvalue.inspect
293
300
  end
294
301
  end
295
302
  attvalue = strip_array(attvalue)
296
303
  make_dirty(name, attvalue) if dirtify
297
- # puts "ARG=#{attname.to_s} setting to #{attvalue}"
304
+ # puts "ARG=#{attname.to_s} setting to #{attvalue}"
298
305
  sdb_val = ruby_to_sdb(name, attvalue)
299
- # puts "sdb_val=" + sdb_val.to_s
306
+ # puts "sdb_val=" + sdb_val.to_s
300
307
  @attributes[attname] = sdb_val
301
- # attvalue = wrap_if_required(name, attvalue, sdb_val)
302
- # puts 'attvalue2=' + attvalue.to_s
308
+ # attvalue = wrap_if_required(name, attvalue, sdb_val)
309
+ # puts 'attvalue2=' + attvalue.to_s
303
310
 
304
311
  if store_rb_val
305
312
  @attributes_rb[name.to_s] = value
@@ -321,11 +328,11 @@ module SimpleRecord
321
328
  return ret
322
329
  end
323
330
 
324
- # Since SimpleDB supports multiple attributes per value, the values are an array.
325
- # This method will return the value unwrapped if it's the only, otherwise it will return the array.
331
+ # Since SimpleDB supports multiple attributes per value, the values are an array.
332
+ # This method will return the value unwrapped if it's the only, otherwise it will return the array.
326
333
  def get_attribute(name)
327
334
  # puts "get_attribute #{name}"
328
- # Check if this arg is already converted
335
+ # Check if this arg is already converted
329
336
  name_s = name.to_s
330
337
  name = name.to_sym
331
338
  att_meta = get_att_meta(name)
@@ -340,7 +347,7 @@ module SimpleRecord
340
347
  return ret
341
348
  end
342
349
  end
343
- # get it from s3
350
+ # get it from s3
344
351
  unless new_record?
345
352
  if self.class.get_sr_config[:single_clob]
346
353
  begin
@@ -362,7 +369,7 @@ module SimpleRecord
362
369
  else
363
370
  begin
364
371
  ret = s3_bucket.get(s3_lob_id(name))
365
- # puts 'got from s3 ' + ret.inspect
372
+ # puts 'got from s3 ' + ret.inspect
366
373
  SimpleRecord.stats.s3_gets += 1
367
374
  rescue Aws::AwsError => ex
368
375
  if ex.include?(/NoSuchKey/) || ex.include?(/NoSuchBucket/)
@@ -386,9 +393,9 @@ module SimpleRecord
386
393
  return ret unless ret.nil?
387
394
  return nil if ret.is_a? RemoteNil
388
395
  ret = get_attribute_sdb(name)
389
- # p ret
396
+ # p ret
390
397
  ret = sdb_to_ruby(name, ret)
391
- # p ret
398
+ # p ret
392
399
  @attributes_rb[name_s] = ret
393
400
  return ret
394
401
  end
@@ -404,7 +411,7 @@ module SimpleRecord
404
411
  end
405
412
 
406
413
 
407
- # Holds information about an attribute
414
+ # Holds information about an attribute
408
415
  class Attribute
409
416
  attr_accessor :type, :options
410
417
 
@@ -17,6 +17,20 @@ module SimpleRecord
17
17
  # end
18
18
  end
19
19
 
20
+ module ClassMethods
21
+
22
+ def uniques
23
+ @uniques ||= {}
24
+ @uniques
25
+ end
26
+
27
+ # only supporting single attr name right now
28
+ def validates_uniqueness_of(attr)
29
+ uniques[attr] = true
30
+ end
31
+
32
+ end
33
+
20
34
  def valid?
21
35
  # puts 'in rails2 valid?'
22
36
  errors.clear
@@ -26,9 +40,9 @@ module SimpleRecord
26
40
  am_valid?
27
41
  end
28
42
 
29
- # run_callbacks(:validate)
43
+ # run_callbacks(:validate)
30
44
  validate
31
-
45
+ validate_uniques
32
46
 
33
47
  if new_record?
34
48
  # run_callbacks(:validate_on_create)
@@ -51,6 +65,21 @@ module SimpleRecord
51
65
  @attributes[key.to_s]
52
66
  end
53
67
 
68
+ def validate_uniques
69
+ puts 'uniques=' + self.class.uniques.inspect
70
+ self.class.uniques.each_pair do |k, v|
71
+ val = self.send(k)
72
+ puts 'val=' + val.inspect
73
+ if val
74
+ ret = self.class.find(:first, :conditions=>["#{k}=?", val])
75
+ puts 'ret=' + ret.inspect
76
+ if ret
77
+ errors.add(k, "must be unique.")
78
+ end
79
+ end
80
+ end
81
+ end
82
+
54
83
  def validate
55
84
  true
56
85
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: simple_record
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 2.1.10
5
+ version: 2.1.11
6
6
  platform: ruby
7
7
  authors:
8
8
  - Travis Reeder
@@ -12,7 +12,7 @@ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
14
 
15
- date: 2011-07-04 00:00:00 Z
15
+ date: 2011-07-06 00:00:00 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: aws
@@ -75,9 +75,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
75
75
  requirements:
76
76
  - - ">="
77
77
  - !ruby/object:Gem::Version
78
- hash: 2579069880692294424
79
- segments:
80
- - 0
81
78
  version: "0"
82
79
  required_rubygems_version: !ruby/object:Gem::Requirement
83
80
  none: false