appoxy-simple_record 1.0.10 → 1.0.15

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.
File without changes
@@ -0,0 +1,901 @@
1
+ # Usage:
2
+ # require 'simple_record'
3
+ #
4
+ # class MyModel < SimpleRecord::Base
5
+ #
6
+ # has_attributes :name, :age
7
+ # are_ints :age
8
+ #
9
+ # end
10
+ #
11
+ # AWS_ACCESS_KEY_ID='XXXXX'
12
+ # AWS_SECRET_ACCESS_KEY='YYYYY'
13
+ # RightAws::ActiveSdb.establish_connection(AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY)
14
+ # # Save an object
15
+ # mm = MyModel.new
16
+ # mm.name = "Travis"
17
+ # mm.age = 32
18
+ # mm.save
19
+ # id = mm.id
20
+ # # Get the object back
21
+ # mm2 = MyModel.select(id)
22
+ # puts 'got=' + mm2.name + ' and he/she is ' + mm.age.to_s + ' years old'
23
+
24
+
25
+
26
+ require 'right_aws'
27
+ require 'sdb/active_sdb'
28
+
29
+ module SimpleRecord
30
+
31
+ VERSION = '1.0.9'
32
+
33
+ class Base < RightAws::ActiveSdb::Base
34
+
35
+ attr_accessor :errors
36
+ @@domain_prefix = ''
37
+ @domain_name_for_class = nil
38
+
39
+ @@cache_store = nil
40
+ # Set the cache to use
41
+ def self.cache_store=(cache)
42
+ @@cache_store = cache
43
+ end
44
+ def self.cache_store
45
+ return @@cache_store
46
+ end
47
+
48
+ # If you want a domain prefix for all your models, set it here.
49
+ def self.set_domain_prefix(prefix)
50
+ @@domain_prefix = prefix
51
+ end
52
+
53
+ # Same as set_table_name
54
+ def self.set_table_name(table_name)
55
+ set_domain_name table_name
56
+ end
57
+
58
+ # Sets the domain name for this class
59
+ def self.set_domain_name(table_name)
60
+ # puts 'setting domain name for class ' + self.inspect + '=' + table_name
61
+ @domain_name_for_class = table_name
62
+ super
63
+ end
64
+
65
+ def self.get_domain_name
66
+ # puts 'returning domain_name=' + @domain_name_for_class.to_s
67
+ return @domain_name_for_class
68
+ end
69
+
70
+
71
+ def domain
72
+ super # super.domain
73
+ end
74
+
75
+ def self.domain
76
+ return self.get_domain_name unless self.get_domain_name.nil?
77
+ d = super
78
+ domain_name_for_class = @@domain_prefix + d.to_s
79
+ self.set_domain_name(domain_name_for_class)
80
+ domain_name_for_class
81
+ end
82
+
83
+ #this bit of code creates a "run_blank" function for everything value in the @@callbacks array.
84
+ #this function can then be inserted in the appropriate place in the save, new, destroy, etc overrides
85
+ #basically, this is how we recreate the callback functions
86
+ @@callbacks=["before_save", "before_create", "after_create", "before_update", "after_update", "after_save", "after_destroy"]
87
+ @@callbacks.each do |callback|
88
+ #we first have to make an initialized array for each of the callbacks, to prevent problems if they are not called
89
+ eval %{
90
+ @@#{callback}_names=[]
91
+
92
+ def self.#{callback}(*args)
93
+ args.each do |arg|
94
+ @@#{callback}_names << arg.to_s if @@#{callback}_names.index(arg.to_s).nil?
95
+ end
96
+ # asdf @@#{callback}_names=args.map{|arg| arg.to_s}
97
+ end
98
+
99
+ def run_#{callback}
100
+ @@#{callback}_names.each { |name|
101
+ unless eval(name)
102
+ return false
103
+ end
104
+ }
105
+ return true
106
+ end
107
+ }
108
+ end
109
+
110
+ def self.has_attributes(*args)
111
+ @@attributes = args
112
+ args.each do |arg|
113
+ # define reader method
114
+ send :define_method, arg do
115
+ ret = nil
116
+ if self[arg.to_s].class==Array
117
+ if self[arg.to_s].length==1
118
+ ret = self[arg.to_s][0]
119
+ else
120
+ ret = self[arg.to_s]
121
+ end
122
+ else
123
+ ret = self[arg.to_s]
124
+ end
125
+ return nil if ret.nil?
126
+ return un_offset_if_int(arg, ret)
127
+ end
128
+
129
+ # define writer method
130
+ method_name = (arg.to_s+"=")
131
+ send(:define_method, method_name) do |value|
132
+ self[arg.to_s]=value# end
133
+ end
134
+ end
135
+ end
136
+
137
+ @@ints = []
138
+ def self.are_ints(*args)
139
+ # puts 'calling are_ints: ' + args.inspect
140
+ args.each do |arg|
141
+ # todo: maybe @@ints and @@dates should be maps for quicker lookups
142
+ @@ints << arg if @@ints.index(arg).nil?
143
+ end
144
+ # @@ints = args
145
+ # puts 'ints=' + @@ints.inspect
146
+ end
147
+
148
+ @@dates = []
149
+ def self.are_dates(*args)
150
+ args.each do |arg|
151
+ @@dates << arg if @@dates.index(arg).nil?
152
+ end
153
+ # @@dates = args
154
+ # puts 'dates=' + @@dates.inspect
155
+ end
156
+
157
+ @@booleans = []
158
+ def self.are_booleans(*args)
159
+ args.each do |arg|
160
+ @@booleans << arg if @@booleans.index(arg).nil?
161
+ end
162
+ end
163
+
164
+ @@virtuals=[]
165
+ def self.has_virtuals(*args)
166
+ @@virtuals = args
167
+ args.each do |arg|
168
+ #we just create the accessor functions here, the actual instance variable is created during initialize
169
+ attr_accessor(arg)
170
+ end
171
+ end
172
+
173
+ @@belongs_to_map = {}
174
+ # One belongs_to association per call. Call multiple times if there are more than one.
175
+ #
176
+ # This method will also create an {association)_id method that will return the ID of the foreign object
177
+ # without actually materializing it.
178
+ def self.belongs_to(association_id, options = {})
179
+ @@belongs_to_map[association_id] = options
180
+ arg = association_id
181
+ arg_id = arg.to_s + '_id'
182
+
183
+ # 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
184
+ # puts "arg_id=#{arg}_id"
185
+ # puts "is defined? " + eval("(defined? #{arg}_id)").to_s
186
+ # puts 'atts=' + @attributes.inspect
187
+
188
+ # Define reader method
189
+ send(:define_method, arg) do
190
+ options2 = @@belongs_to_map[arg]
191
+ class_name = options2[:class_name] || arg.to_s[0...1].capitalize + arg.to_s[1...arg.to_s.length]
192
+ # puts "attr=" + @attributes[arg_id].inspect
193
+ # puts 'val=' + @attributes[arg_id][0].inspect unless @attributes[arg_id].nil?
194
+ ret = nil
195
+ arg_id = arg.to_s + '_id'
196
+ if !@attributes[arg_id].nil? && @attributes[arg_id].size > 0 && @attributes[arg_id][0] != nil && @attributes[arg_id][0] != ''
197
+ if !@@cache_store.nil?
198
+ arg_id_val = @attributes[arg_id][0]
199
+ cache_key = self.class.cache_key(class_name, arg_id_val)
200
+ # puts 'cache_key=' + cache_key
201
+ ret = @@cache_store.read(cache_key)
202
+ # puts 'belongs_to incache=' + ret.inspect
203
+ end
204
+ if ret.nil?
205
+ to_eval = "#{class_name}.find(@attributes['#{arg_id}'][0], :auto_load=>true)"
206
+ # puts 'to eval=' + to_eval
207
+ begin
208
+ ret = eval(to_eval) # (defined? #{arg}_id)
209
+ rescue RightAws::ActiveSdb::ActiveSdbError
210
+ if $!.message.include? "Couldn't find"
211
+ ret = nil
212
+ else
213
+ raise $!
214
+ end
215
+ end
216
+
217
+ end
218
+ end
219
+ # puts 'ret=' + ret.inspect
220
+ return ret
221
+ end
222
+
223
+ # Define reader ID method
224
+ send(:define_method, arg_id) do
225
+ if !@attributes[arg_id].nil? && @attributes[arg_id].size > 0 && @attributes[arg_id][0] != nil && @attributes[arg_id][0] != ''
226
+ return @attributes[arg_id][0]
227
+ end
228
+ return nil
229
+ end
230
+
231
+ # Define writer method
232
+ send(:define_method, arg.to_s + "=") do |value|
233
+ arg_id = arg.to_s + '_id'
234
+ if value.nil?
235
+ self[arg_id]=nil unless self[arg_id].nil? # if it went from something to nil, then we have to remember and remove attribute on save
236
+ else
237
+ self[arg_id]=value.id
238
+ end
239
+ end
240
+
241
+ send(:define_method, "create_"+arg.to_s) do |*params|
242
+ newsubrecord=eval(arg.to_s.classify).new(*params)
243
+ newsubrecord.save
244
+ arg_id = arg.to_s + '_id'
245
+ self[arg_id]=newsubrecord.id
246
+ end
247
+ end
248
+
249
+ def self.has_many(*args)
250
+ args.each do |arg|
251
+ #okay, this creates an instance method with the pluralized name of the symbol passed to belongs_to
252
+ send(:define_method, arg) do
253
+ #when called, the method creates a new, very temporary instance of the Activerecordtosdb_subrecord class
254
+ #It is passed the three initializers it needs:
255
+ #note the first parameter is just a string by time new gets it, like "user"
256
+ #the second and third parameters are still a variable when new gets it, like user_id
257
+ return eval(%{Activerecordtosdb_subrecord_array.new('#{arg}', self.class.name ,id)})
258
+ end
259
+ end
260
+ #Disclaimer: this whole funciton just seems crazy to me, and a bit inefficient. But it was the clearest way I could think to do it code wise.
261
+ #It's bad programming form (imo) to have a class method require something that isn't passed to it through it's variables.
262
+ #I couldn't pass the id when calling find, since the original find doesn't work that way, so I was left with this.
263
+ end
264
+
265
+ def self.has_one(*args)
266
+
267
+ end
268
+
269
+ has_attributes :created, :updated
270
+ before_create :set_created, :set_updated
271
+ before_update :set_updated
272
+ are_dates :created, :updated
273
+
274
+ def set_created
275
+ # puts 'SETTING CREATED'
276
+ # @created = DateTime.now
277
+ self[:created] = DateTime.now
278
+ # @tester = 'some test value'
279
+ # self[:tester] = 'some test value'
280
+ end
281
+
282
+ def set_updated
283
+ # puts 'SETTING UPDATED'
284
+ # @updated = DateTime.now
285
+ self[:updated] = DateTime.now
286
+ # @tester = 'some test value updated'
287
+ end
288
+
289
+ def initialize(*params)
290
+ if params[0]
291
+ #we have to handle the virtuals. Right now, this assumes that all parameters are passed from inside an array
292
+ #this is the usually the case when the parameters are passed passed via POST and obtained from the params array
293
+ @@virtuals.each do |virtual|
294
+ #we first copy the information for the virtual to an instance variable of the same name
295
+ eval("@#{virtual}=params[0]['#{virtual}']")
296
+ #and then remove the parameter before it is passed to initialize, so that it is NOT sent to SimpleDB
297
+ eval("params[0].delete('#{virtual}')")
298
+ end
299
+ super(*params)
300
+ else
301
+ super()
302
+ end
303
+ @errors=SimpleRecord_errors.new
304
+ end
305
+
306
+
307
+ @@offset = 9223372036854775808
308
+ @@padding = 20
309
+ @@date_format = "%Y-%m-%dT%H:%M:%S"; # Time to second precision
310
+
311
+ def self.pad_and_offset(x)
312
+ # todo: add Float, etc
313
+ # puts 'padding=' + x.class.name + " -- " + x.inspect
314
+ if x.kind_of? Integer
315
+ x += @@offset
316
+ x_str = x.to_s
317
+ # pad
318
+ x_str = '0' + x_str while x_str.size < 20
319
+ return x_str
320
+ elsif x.respond_to?(:iso8601)
321
+ # puts x.class.name + ' responds to iso8601'
322
+ #
323
+ # There is an issue here where Time.iso8601 on an incomparable value to DateTime.iso8601.
324
+ # Amazon suggests: 2008-02-10T16:52:01.000-05:00
325
+ # "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
326
+ #
327
+ if x.is_a? DateTime
328
+ x_str = x.new_offset(0).strftime(@@date_format)
329
+ else
330
+ x_str = x.getutc.strftime(@@date_format)
331
+ end
332
+ # puts 'utc=' + x_str
333
+ return x_str
334
+ else
335
+ return x
336
+ end
337
+ end
338
+
339
+ def domain_ok(ex)
340
+ if (ex.message().index("NoSuchDomain") != nil)
341
+ puts "Creating new SimpleDB Domain: " + domain
342
+ self.class.create_domain
343
+ return true
344
+ end
345
+ return false
346
+ end
347
+
348
+ @create_domain_called = false
349
+
350
+ def save(*params)
351
+ # puts 'SAVING: ' + self.inspect
352
+ is_create = self[:id].nil?
353
+ ok = pre_save(*params)
354
+ if ok
355
+ begin
356
+ # puts 'is frozen? ' + self.frozen?.to_s + ' - ' + self.inspect
357
+ to_delete = get_atts_to_delete
358
+ if super(*params)
359
+ # puts 'SAVED super'
360
+ self.class.cache_results(self)
361
+ delete_niled(to_delete)
362
+ if run_after_save && is_create ? run_after_create : run_after_update
363
+ return true
364
+ else
365
+ #I thought about calling destroy here, but rails doesn't behave that way, so neither will I
366
+ return false
367
+ end
368
+ else
369
+ return false
370
+ end
371
+ rescue RightAws::AwsError
372
+ # puts "RESCUED in save: " + $!
373
+ if (domain_ok($!))
374
+ if !@create_domain_called
375
+ @create_domain_called = true
376
+ save(*params)
377
+ else
378
+ raise $!
379
+ end
380
+ else
381
+ raise $!
382
+ end
383
+ end
384
+ else
385
+ #@debug = "not saved"
386
+ return false
387
+ end
388
+ end
389
+
390
+ def pad_and_offset_ints_to_sdb()
391
+ if !@@ints.nil?
392
+ for i in @@ints
393
+ # puts 'int encoding: ' + i.to_s
394
+ if !self[i.to_s].nil?
395
+ # puts 'before: ' + self[i.to_s].inspect
396
+ # puts @attributes.inspect
397
+ # puts @attributes[i.to_s].inspect
398
+ arr = @attributes[i.to_s]
399
+ arr.collect!{ |x| self.class.pad_and_offset(x) }
400
+ @attributes[i.to_s] = arr
401
+ # puts 'after: ' + @attributes[i.to_s].inspect
402
+ else
403
+ # puts 'was nil'
404
+ end
405
+ end
406
+ end
407
+ end
408
+ def convert_dates_to_sdb()
409
+ if !@@dates.nil?
410
+ for i in @@dates
411
+ # puts 'int encoding: ' + i.to_s
412
+ if !self[i.to_s].nil?
413
+ # puts 'before: ' + self[i.to_s].inspect
414
+ # puts @attributes.inspect
415
+ # puts @attributes[i.to_s].inspect
416
+ arr = @attributes[i.to_s]
417
+ #puts 'padding date=' + i.to_s
418
+ arr.collect!{ |x| self.class.pad_and_offset(x) }
419
+ @attributes[i.to_s] = arr
420
+ # puts 'after: ' + @attributes[i.to_s].inspect
421
+ else
422
+ # puts 'was nil'
423
+ end
424
+ end
425
+ end
426
+ end
427
+
428
+ def pre_save(*params)
429
+ if respond_to?('validate')
430
+ validate
431
+ # puts 'AFTER VALIDATIONS, ERRORS=' + errors.inspect
432
+ if (!@errors.nil? && @errors.length > 0 )
433
+ # puts 'THERE ARE ERRORS, returning false'
434
+ return false
435
+ end
436
+ end
437
+
438
+ is_create = self[:id].nil?
439
+ ok = respond_to?('before_save') ? before_save : true
440
+ if ok
441
+ if is_create && respond_to?('before_create')
442
+ ok = before_create
443
+ elsif !is_create && respond_to?('before_update')
444
+ ok = before_update
445
+ end
446
+ end
447
+ if ok
448
+ ok = run_before_save && is_create ? run_before_create : run_before_update
449
+ end
450
+ if ok
451
+ # puts 'ABOUT TO SAVE: ' + self.inspect
452
+ # First we gotta pad and offset
453
+ pad_and_offset_ints_to_sdb()
454
+ convert_dates_to_sdb()
455
+ end
456
+ ok
457
+ end
458
+
459
+ def save_attributes(*params)
460
+ ret = super(*params)
461
+ if ret
462
+ self.class.cache_results(self)
463
+ end
464
+ ret
465
+ end
466
+
467
+ def get_atts_to_delete
468
+ to_delete = []
469
+ @attributes.each do |key, value|
470
+ # puts 'value=' + value.inspect
471
+ if value.nil? || (value.is_a?(Array) && value.size == 0)
472
+ to_delete << key
473
+ end
474
+ end
475
+ return to_delete
476
+ end
477
+
478
+ # Run pre_save on each object, then runs batch_put_attributes
479
+ # Returns
480
+ def self.batch_save(objects)
481
+ results = []
482
+ to_save = []
483
+ if objects && objects.size > 0
484
+ objects.each do |o|
485
+ ok = o.pre_save
486
+ raise "Pre save failed on object [" + o.inspect + "]" if !ok
487
+ results << ok
488
+ next if !ok
489
+ o.pre_save2
490
+ to_save << RightAws::SdbInterface::Item.new(o.id, o.attributes, true)
491
+ end
492
+ end
493
+ connection.batch_put_attributes(domain, to_save)
494
+ results
495
+ end
496
+
497
+ #
498
+ # Usage: ClassName.delete id
499
+ # todo: move to RightAWS
500
+ #
501
+ def self.delete(id)
502
+ connection.delete_attributes(domain, id)
503
+ end
504
+
505
+ def delete_niled(to_delete)
506
+ if to_delete.size > 0
507
+ # puts 'Deleting attributes=' + to_delete.inspect
508
+ delete_attributes to_delete
509
+ end
510
+ end
511
+
512
+ def un_offset_if_int(arg, x)
513
+ if !@@ints.nil?
514
+ for i in @@ints
515
+ # puts 'unpadding: ' + i.to_s
516
+ # unpad and unoffset
517
+ if i == arg
518
+ # puts 'unoffsetting ' + x.to_s
519
+ x = un_offset_int(x)
520
+ end
521
+ end
522
+ end
523
+ if !@@dates.nil?
524
+ for d in @@dates
525
+ # puts 'converting created: ' + self['created'].inspect
526
+ if d == arg
527
+ x = to_date(x)
528
+ end
529
+ # if !self[d].nil?
530
+ # self[d].collect!{ |d2|
531
+ # if d2.is_a?(String)
532
+ # DateTime.parse(d2)
533
+ # else
534
+ # d2
535
+ # end
536
+ # }
537
+ # end
538
+ # puts 'after=' + self['created'].inspect
539
+ end
540
+ end
541
+ if !@@booleans.nil?
542
+ for b in @@booleans
543
+ # puts 'converting created: ' + self['created'].inspect
544
+ if b == arg
545
+ x = to_bool(x)
546
+ end
547
+ # if !self[d].nil?
548
+ # self[d].collect!{ |d2|
549
+ # if d2.is_a?(String)
550
+ # DateTime.parse(d2)
551
+ # else
552
+ # d2
553
+ # end
554
+ # }
555
+ # end
556
+ # puts 'after=' + self['created'].inspect
557
+ end
558
+ end
559
+ x
560
+ end
561
+
562
+
563
+ def to_date(x)
564
+ if x.is_a?(String)
565
+ DateTime.parse(x)
566
+ else
567
+ x
568
+ end
569
+
570
+ end
571
+
572
+ def to_bool(x)
573
+ if x.is_a?(String)
574
+ x == "true"
575
+ else
576
+ x
577
+ end
578
+ end
579
+
580
+
581
+ def un_offset_int(x)
582
+ if x.is_a?(String)
583
+ x2 = x.to_i
584
+ # puts 'to_i=' + x2.to_s
585
+ x2 -= @@offset
586
+ # puts 'after subtracting offset='+ x2.to_s
587
+ x2
588
+ else
589
+ x
590
+ end
591
+ end
592
+
593
+ def unpad(i, attributes)
594
+ if !attributes[i].nil?
595
+ # puts 'before=' + self[i].inspect
596
+ attributes[i].collect!{ |x|
597
+ un_offset_int(x)
598
+
599
+ }
600
+ # for x in self[i]
601
+ # x = self[i][0].to_i
602
+ # x -= @@offset
603
+ # self[i] = x
604
+ # end
605
+ end
606
+ end
607
+
608
+ def unpad_self
609
+ if !@@ints.nil?
610
+ for i in @@ints
611
+ # puts 'unpadding: ' + i.to_s
612
+ # unpad and unoffset
613
+
614
+ unpad(i, @attributes)
615
+ end
616
+ end
617
+ end
618
+
619
+ def reload
620
+ super()
621
+ # puts 'decoding...'
622
+
623
+ =begin
624
+ This is done on getters now
625
+ if !@@dates.nil?
626
+ for d in @@dates
627
+ # puts 'converting created: ' + self['created'].inspect
628
+ if !self[d].nil?
629
+ self[d].collect!{ |d2|
630
+ if d2.is_a?(String)
631
+ DateTime.parse(d2)
632
+ else
633
+ d2
634
+ end
635
+ }
636
+ end
637
+ # puts 'after=' + self['created'].inspect
638
+ end
639
+ end
640
+ =end
641
+
642
+ # unpad_self
643
+ end
644
+
645
+ def update_attributes(*params)
646
+ return save_attributes(*params)
647
+ end
648
+
649
+ def destroy(*params)
650
+ if super(*params)
651
+ if run_after_destroy
652
+ return true
653
+ else
654
+ return false
655
+ end
656
+ else
657
+ return false
658
+ end
659
+ end
660
+
661
+ def self.quote_regexp(a, re)
662
+ a =~ re
663
+ #was there a match?
664
+ if $&
665
+ before=$`
666
+ middle=$&
667
+ after=$'
668
+
669
+ before =~ /'$/ #is there already a quote immediately before the match?
670
+ unless $&
671
+ return "#{before}'#{middle}'#{quote_regexp(after, re)}" #if not, put quotes around the match
672
+ else
673
+ return "#{before}#{middle}#{quote_regexp(after, re)}" #if so, assume it is quoted already and move on
674
+ end
675
+ else
676
+ #no match, just return the string
677
+ return a
678
+ end
679
+ end
680
+
681
+ def self.find(*params)
682
+ reload=true
683
+ first=false
684
+ all=false
685
+ select=false
686
+ select_attributes=[]
687
+
688
+ if params.size > 0
689
+ all = params[0] == :all
690
+ first = params[0] == :first
691
+ end
692
+
693
+
694
+ # Pad and Offset number attributes
695
+ options = params[1]
696
+ puts 'options=' + options.inspect
697
+ convert_condition_params(options)
698
+ puts 'after collect=' + options.inspect
699
+
700
+ results = all ? [] : nil
701
+ begin
702
+ results=super(*params)
703
+ cache_results(results)
704
+ rescue RightAws::AwsError, RightAws::ActiveSdb::ActiveSdbError
705
+ puts "RESCUED: " + $!
706
+ if ($!.message().index("NoSuchDomain") != nil)
707
+ # this is ok
708
+ elsif ($!.message() =~ @@regex_no_id)
709
+ results = nil
710
+ else
711
+ raise $!
712
+ end
713
+ end
714
+ return results
715
+ end
716
+
717
+ @@regex_no_id = /.*Couldn't find.*with ID.*/
718
+ def self.select(*params)
719
+ first=false
720
+ all=false
721
+ select=false
722
+ select_attributes=[]
723
+
724
+ if params.size > 0
725
+ all = params[0] == :all
726
+ first = params[0] == :first
727
+ end
728
+
729
+ options = params[1]
730
+ convert_condition_params(options)
731
+
732
+ results = all ? [] : nil
733
+ begin
734
+ results=super(*params)
735
+ cache_results(results)
736
+ rescue RightAws::AwsError, RightAws::ActiveSdb::ActiveSdbError
737
+ if ($!.message().index("NoSuchDomain") != nil)
738
+ # this is ok
739
+ elsif ($!.message() =~ @@regex_no_id)
740
+ results = nil
741
+ else
742
+ raise $!
743
+ end
744
+ end
745
+ return results
746
+
747
+ end
748
+
749
+ def self.convert_condition_params(options)
750
+ if !options.nil? && options.size > 0
751
+ conditions = options[:conditions]
752
+ if !conditions.nil? && conditions.size > 1
753
+ # all after first are values
754
+ conditions.collect! { |x|
755
+ self.pad_and_offset(x)
756
+ }
757
+ end
758
+ end
759
+ end
760
+
761
+ def self.cache_results(results)
762
+ if !@@cache_store.nil? && !results.nil?
763
+ if results.is_a?(Array)
764
+ # todo: cache each result
765
+ else
766
+ class_name = results.class.name
767
+ id = results.id
768
+ cache_key = self.cache_key(class_name, id)
769
+ # puts 'caching result at ' + cache_key + ': ' + results.inspect
770
+ @@cache_store.write(cache_key, results, :expires_in =>10*60)
771
+ end
772
+ end
773
+ end
774
+
775
+ def self.cache_key(class_name, id)
776
+ return class_name + "/" + id.to_s
777
+ end
778
+
779
+
780
+
781
+ @@debug=""
782
+ def self.debug
783
+ @@debug
784
+ end
785
+
786
+ def self.sanitize_sql(*params)
787
+ return ActiveRecord::Base.sanitize_sql(*params)
788
+ end
789
+
790
+ def self.table_name
791
+ return @@domain_prefix + self.class.name.tableize
792
+ end
793
+
794
+ end
795
+
796
+ class SimpleRecord_errors
797
+ def initialize(*params)
798
+ super(*params)
799
+ @errors=[]
800
+ end
801
+
802
+ def add_to_base(value)
803
+ @errors+=[value]
804
+ end
805
+
806
+ def add(attribute, value)
807
+ @errors+=["#{attribute.to_s} #{value}"]
808
+ end
809
+
810
+ def count
811
+ return length
812
+ end
813
+
814
+ def length
815
+ return @errors.length
816
+ end
817
+
818
+ def size
819
+ return length
820
+ end
821
+
822
+ def full_messages
823
+ return @errors
824
+ end
825
+ end
826
+
827
+ class Activerecordtosdb_subrecord_array
828
+ def initialize(subname, referencename, referencevalue)
829
+ @subname=subname.classify
830
+ @referencename=referencename.tableize.singularize + "_id"
831
+ @referencevalue=referencevalue
832
+ end
833
+
834
+ # Performance optimization if you know the array should be empty
835
+
836
+ def init_empty
837
+ @records = []
838
+ end
839
+
840
+ def load
841
+ if @records.nil?
842
+ @records = find_all
843
+ end
844
+ return @records
845
+ end
846
+
847
+ def [](key)
848
+ return load[key]
849
+ end
850
+
851
+ def <<(ob)
852
+ return load << ob
853
+ end
854
+
855
+ def each(*params, &block)
856
+ return load.each(*params){|record| block.call(record)}
857
+ end
858
+
859
+ def find_all(*params)
860
+ find(:all, *params)
861
+ end
862
+
863
+ def build(*params)
864
+ params[0][@referencename]=@referencevalue
865
+ eval(@subname).new(*params)
866
+ end
867
+
868
+ def create(*params)
869
+ params[0][@referencename]=@referencevalue
870
+ record = eval(@subname).new(*params)
871
+ record.save
872
+ end
873
+
874
+ def find(*params)
875
+ query=[:first, {}]
876
+ #{:conditions=>"id=>1"}
877
+ if params[0]
878
+ if params[0]==:all
879
+ query[0]=:all
880
+ end
881
+ end
882
+
883
+ if params[1]
884
+ query[1]=params[1]
885
+ if query[1][:conditions]
886
+ query[1][:conditions]=SimpleRecord::Base.sanitize_sql(query[1][:conditions])+" AND "+ SimpleRecord::Base.sanitize_sql(["#{@referencename} = ?", @referencevalue])
887
+ #query[1][:conditions]=Activerecordtosdb.sanitize_sql(query[1][:conditions])+" AND id='#{@id}'"
888
+ else
889
+ query[1][:conditions]=["#{@referencename} = ?", @referencevalue]
890
+ #query[1][:conditions]="id='#{@id}'"
891
+ end
892
+ else
893
+ query[1][:conditions]=["#{@referencename} = ?", @referencevalue]
894
+ #query[1][:conditions]="id='#{@id}'"
895
+ end
896
+
897
+ return eval(@subname).find(*query)
898
+ end
899
+
900
+ end
901
+ end
@@ -1,6 +1,6 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../lib/simple_record")
2
-
3
- class MyChildModel < SimpleRecord::Base
4
- belongs_to :my_model
5
- has_attributes :name
1
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/simple_record")
2
+
3
+ class MyChildModel < SimpleRecord::Base
4
+ belongs_to :my_model
5
+ has_attributes :name
6
6
  end
data/test/my_model.rb CHANGED
@@ -1,11 +1,11 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../lib/simple_record")
2
-
3
- class MyModel < SimpleRecord::Base
4
-
5
- has_attributes :created, :updated, :name, :age, :cool, :birthday
6
- are_ints :age
7
- are_booleans :cool
8
- are_dates :created, :updated, :birthday
9
-
10
-
1
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/simple_record")
2
+
3
+ class MyModel < SimpleRecord::Base
4
+
5
+ has_attributes :created, :updated, :name, :age, :cool, :birthday
6
+ are_ints :age
7
+ are_booleans :cool
8
+ are_dates :created, :updated, :birthday
9
+
10
+
11
11
  end
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appoxy-simple_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.10
4
+ version: 1.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Travis Reeder
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-06-06 00:00:00 -07:00
13
+ date: 2009-06-16 00:00:00 -07:00
14
14
  default_executable: simple_record
15
15
  dependencies: []
16
16
 
@@ -21,9 +21,10 @@ executables:
21
21
  extensions: []
22
22
 
23
23
  extra_rdoc_files:
24
- - README.txt
24
+ - README.markdown
25
25
  files:
26
- - README.txt
26
+ - lib/simple_record.rb
27
+ - README.markdown
27
28
  has_rdoc: true
28
29
  homepage: http://github.com/appoxy/simple_record/
29
30
  post_install_message: