appoxy-simple_record 1.0.10 → 1.0.15

Sign up to get free protection for your applications and to get access to all the features.
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: