ahoward-helene 0.0.3

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.
Files changed (72) hide show
  1. data/Rakefile +274 -0
  2. data/helene.gemspec +26 -0
  3. data/lib/helene.rb +113 -0
  4. data/lib/helene/attempt.rb +46 -0
  5. data/lib/helene/aws.rb +50 -0
  6. data/lib/helene/config.rb +147 -0
  7. data/lib/helene/content_type.rb +15 -0
  8. data/lib/helene/content_type.yml +661 -0
  9. data/lib/helene/error.rb +12 -0
  10. data/lib/helene/logging.rb +55 -0
  11. data/lib/helene/objectpool.rb +220 -0
  12. data/lib/helene/rails.rb +21 -0
  13. data/lib/helene/rightscale/acf/right_acf_interface.rb +379 -0
  14. data/lib/helene/rightscale/awsbase/benchmark_fix.rb +39 -0
  15. data/lib/helene/rightscale/awsbase/right_awsbase.rb +803 -0
  16. data/lib/helene/rightscale/awsbase/support.rb +111 -0
  17. data/lib/helene/rightscale/ec2/right_ec2.rb +1737 -0
  18. data/lib/helene/rightscale/net_fix.rb +160 -0
  19. data/lib/helene/rightscale/right_aws.rb +71 -0
  20. data/lib/helene/rightscale/right_http_connection.rb +507 -0
  21. data/lib/helene/rightscale/s3/right_s3.rb +1094 -0
  22. data/lib/helene/rightscale/s3/right_s3_interface.rb +1180 -0
  23. data/lib/helene/rightscale/sdb/active_sdb.rb +930 -0
  24. data/lib/helene/rightscale/sdb/right_sdb_interface.rb +696 -0
  25. data/lib/helene/rightscale/sqs/right_sqs.rb +388 -0
  26. data/lib/helene/rightscale/sqs/right_sqs_gen2.rb +286 -0
  27. data/lib/helene/rightscale/sqs/right_sqs_gen2_interface.rb +444 -0
  28. data/lib/helene/rightscale/sqs/right_sqs_interface.rb +596 -0
  29. data/lib/helene/s3.rb +34 -0
  30. data/lib/helene/s3/bucket.rb +379 -0
  31. data/lib/helene/s3/grantee.rb +134 -0
  32. data/lib/helene/s3/key.rb +162 -0
  33. data/lib/helene/s3/owner.rb +16 -0
  34. data/lib/helene/sdb.rb +9 -0
  35. data/lib/helene/sdb/base.rb +1204 -0
  36. data/lib/helene/sdb/base/associations.rb +481 -0
  37. data/lib/helene/sdb/base/attributes.rb +90 -0
  38. data/lib/helene/sdb/base/connection.rb +20 -0
  39. data/lib/helene/sdb/base/error.rb +20 -0
  40. data/lib/helene/sdb/base/hooks.rb +82 -0
  41. data/lib/helene/sdb/base/literal.rb +52 -0
  42. data/lib/helene/sdb/base/logging.rb +23 -0
  43. data/lib/helene/sdb/base/transactions.rb +53 -0
  44. data/lib/helene/sdb/base/type.rb +137 -0
  45. data/lib/helene/sdb/base/types.rb +123 -0
  46. data/lib/helene/sdb/base/validations.rb +256 -0
  47. data/lib/helene/sdb/cast.rb +114 -0
  48. data/lib/helene/sdb/connection.rb +36 -0
  49. data/lib/helene/sdb/error.rb +5 -0
  50. data/lib/helene/sdb/interface.rb +412 -0
  51. data/lib/helene/sdb/sentinel.rb +15 -0
  52. data/lib/helene/sleepcycle.rb +29 -0
  53. data/lib/helene/superhash.rb +297 -0
  54. data/lib/helene/util.rb +132 -0
  55. data/test/auth.rb +31 -0
  56. data/test/helper.rb +98 -0
  57. data/test/integration/begin.rb +0 -0
  58. data/test/integration/ensure.rb +8 -0
  59. data/test/integration/s3/bucket.rb +106 -0
  60. data/test/integration/sdb/associations.rb +45 -0
  61. data/test/integration/sdb/creating.rb +13 -0
  62. data/test/integration/sdb/emptiness.rb +56 -0
  63. data/test/integration/sdb/hooks.rb +19 -0
  64. data/test/integration/sdb/limits.rb +27 -0
  65. data/test/integration/sdb/saving.rb +21 -0
  66. data/test/integration/sdb/selecting.rb +39 -0
  67. data/test/integration/sdb/types.rb +31 -0
  68. data/test/integration/sdb/validations.rb +60 -0
  69. data/test/integration/setup.rb +27 -0
  70. data/test/integration/teardown.rb +21 -0
  71. data/test/loader.rb +39 -0
  72. metadata +139 -0
@@ -0,0 +1,481 @@
1
+ module Helene
2
+ module Sdb
3
+ class Base
4
+ class Association
5
+ def Association.attr(name)
6
+ module_eval <<-__
7
+ def #{ name }(*value) (value.empty? ? (@#{ name }||=nil) : (self.#{ name }=value.first)) end
8
+ def #{ name }=(value) @#{ name } = value end
9
+ def #{ name }?() !!self.#{ name } end
10
+ __
11
+ end
12
+
13
+
14
+ attr :base
15
+ attr :name
16
+ attr :options
17
+ attr :class_name
18
+ attr :foreign_key
19
+ attr :foreign_keys
20
+ attr :dependent
21
+ attr :conditions
22
+
23
+ def initialize(base, name, options = {}, &block)
24
+ @base = base
25
+ @name = name.to_s
26
+ @options = options.to_options!
27
+
28
+ instance_eval(&block) if block
29
+ @class_name ||= (options[:class_name] || @name.camelize.singularize).to_s
30
+ @dependent ||= (options[:dependent] || :nullify).to_s.to_sym
31
+
32
+ @conditions = (options[:conditions] || {}).to_options!
33
+ @foreign_keys = options[:foreign_keys]
34
+
35
+ association = self
36
+ @base.module_eval do
37
+ define_method("#{ name }_association"){ association }
38
+ end
39
+ end
40
+
41
+ def conditions_for(conditions)
42
+ self.conditions.dup.update(conditions.to_options)
43
+ end
44
+
45
+ def associated_class
46
+ @associated_class ||= class_name.constantize
47
+ end
48
+
49
+ def initialize_record(record)
50
+ :abstract
51
+ end
52
+
53
+ class HasMany < Association
54
+ attr :list
55
+ attr :polymorphic
56
+ attr :foreign_type
57
+ attr :foreign_key
58
+
59
+ def initialize(base, name, options = {}, &block)
60
+ super
61
+
62
+ if @foreign_keys
63
+ if @foreign_keys == true
64
+ @foreign_keys = associated_class.name.foreign_key.pluralize.to_sym
65
+ else
66
+ @foreign_keys = @foreign_keys.to_s.to_sym
67
+ end
68
+ else
69
+ @polymorphic ||= options[:polymorphic]
70
+
71
+ if @polymorphic
72
+ @foreign_type ||= "#{ @polymorphic }_type"
73
+ @foreign_key ||= "#{ @polymorphic }_id"
74
+ end
75
+
76
+ if options.has_key?(:foreign_key)
77
+ @foreign_key = options[:foreign_key]
78
+ else
79
+ @foreign_key ||= @base.name.foreign_key.to_s
80
+ end
81
+ end
82
+
83
+ lineno, code = __LINE__ + 1, <<-__
84
+ def #{ name }(*args, &block)
85
+ association = #{ name }_association()
86
+ @#{ name } ||= nil
87
+ options = args.extract_options!.to_options!
88
+ forcing = options.delete(:force)
89
+ @#{ name } = nil if forcing
90
+ @#{ name } ||= association.list_for(self, *args, &block)
91
+ end
92
+
93
+ def #{ name }=(*values)
94
+ value = values.first
95
+
96
+ list = #{ name }()
97
+ list.clear!
98
+
99
+ case value
100
+ when Hash
101
+ list.build(value)
102
+ when Array
103
+ list.associate(*value)
104
+ when Base
105
+ list.associate(value)
106
+ else
107
+ list.associate(*values.flatten)
108
+ end
109
+ end
110
+ __
111
+ filename = __FILE__
112
+ eval code, @base.module_eval('binding'), filename, lineno
113
+ end
114
+
115
+ def list_for(record, *args, &block)
116
+ List.new(record, self, *args, &block)
117
+ end
118
+
119
+ class List < ::Array
120
+ attr :parent
121
+ attr :association
122
+
123
+ def initialize(parent, association, *args, &block)
124
+ @parent = parent
125
+ @association = association
126
+ reload
127
+ end
128
+
129
+ def reload
130
+ if foreign_keys
131
+ ids = Array(parent.send(foreign_keys))
132
+ records = ids.empty? ? [] : associated_class.select(ids)
133
+ else
134
+ conditions = {}
135
+
136
+ foreign_type = association.foreign_type
137
+ foreign_key = association.foreign_key
138
+
139
+ if foreign_type
140
+ conditions[foreign_type] = parent_type
141
+ end
142
+
143
+ conditions[foreign_key] = parent_id
144
+
145
+ records = associated_class.select(:all, :conditions => conditions_for(conditions))
146
+ end
147
+ replace records
148
+ self
149
+ end
150
+
151
+ def parent_class
152
+ associated_class
153
+ end
154
+
155
+ def parent_type
156
+ parent_class.name
157
+ end
158
+
159
+ def parent_id
160
+ parent.id
161
+ end
162
+
163
+ %w[ foreign_keys foreign_type foreign_key associated_class dependent conditions_for ].each do |attr|
164
+ module_eval <<-__
165
+ def #{ attr }(*a, &b) association.send('#{ attr }', *a, &b) end
166
+ def #{ attr }=(*a, &b) association.send('#{ attr }=', *a, &b) end
167
+ __
168
+ end
169
+
170
+ def destroy_all
171
+ parent.transaction do
172
+ each do |record|
173
+ record.destroy
174
+ if foreign_keys
175
+ ids = Array(parent.send(foreign_keys))
176
+ ids -= Array(record.id)
177
+ parent.put_attributes(foreign_keys => ids)
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ def delete_all
184
+ parent.transaction do
185
+ each do |record|
186
+ record.delete
187
+ if foreign_keys
188
+ ids = Array(parent.send(foreign_keys))
189
+ ids -= Array(record.id)
190
+ parent.put_attributes(foreign_keys => ids)
191
+ end
192
+ end
193
+ end
194
+ end
195
+
196
+ def nullify_all
197
+ parent.transaction do
198
+ unless foreign_keys
199
+ each do |record|
200
+ record.send("#{ foreign_key }=", nil)
201
+ record.send("#{ foreign_type }=", nil) if foreign_type
202
+ end
203
+ else
204
+ parent.put_attributes(foreign_keys => [])
205
+ end
206
+ end
207
+ end
208
+
209
+ # TODO - use batch_delete!
210
+ #
211
+ def clear!
212
+ case dependent
213
+ when :destroy
214
+ destroy_all
215
+ when :delete
216
+ delete_all
217
+ when :nullify, nil
218
+ nullify_all
219
+ end
220
+ clear
221
+ end
222
+
223
+ def build(attributes = {})
224
+ unless foreign_keys
225
+ record = parent_class.new(attributes)
226
+ record.send("#{ foreign_type }=", parent_type) if foreign_type
227
+ record.send("#{ foreign_key }=", parent_id)
228
+ self.push(record)
229
+ else
230
+ record = parent_class.new(attributes)
231
+ ids = Array(parent.send(foreign_keys))
232
+ ids += Array(record.id)
233
+ parent.send("#{ foreign_keys }=", ids)
234
+ #parent.put_attributes(foreign_keys => ids)
235
+ self.push(record)
236
+ end
237
+ record
238
+ end
239
+
240
+ def associate(*records)
241
+ unless foreign_keys
242
+ Array(records).flatten.each do |record|
243
+ record.send("#{ foreign_type }=", parent_type) if foreign_type
244
+ record.send("#{ foreign_key }=", parent_id)
245
+ self.push(record)
246
+ end
247
+ else
248
+ ids = Array(parent.send(foreign_keys))
249
+ ids += records.map{|record| record.id}
250
+ parent.send("#{ foreign_keys }=", ids)
251
+ #parent.put_attributes(foreign_keys => ids)
252
+ end
253
+ end
254
+
255
+ def <<(record)
256
+ associate(record)
257
+ end
258
+
259
+ def create(attributes = {})
260
+ created = nil
261
+ parent.transaction do
262
+ created = build(attributes).save
263
+ parent.save if foreign_keys
264
+ end
265
+ created
266
+ end
267
+
268
+ def create!(attributes = {})
269
+ created = nil
270
+ parent.transaction do
271
+ created = build(attributes).save!
272
+ parent.save! if foreign_keys
273
+ end
274
+ created
275
+ end
276
+
277
+ def save
278
+ map!{|record| record.save}
279
+ self
280
+ end
281
+
282
+ def save!
283
+ map!{|record| record.save!}
284
+ self
285
+ end
286
+
287
+ def valid?
288
+ map{|record| record.valid?}.all?
289
+ end
290
+
291
+ def validate!
292
+ map{|record| record.validate!}
293
+ end
294
+ end
295
+ end
296
+
297
+ class BelongsTo < Association
298
+ attr :polymorphic
299
+ attr :foreign_type
300
+
301
+ def initialize(base, name, options = {}, &block)
302
+ super
303
+
304
+ @polymorphic ||= options[:polymorphic]
305
+
306
+ if @polymorphic
307
+ @foreign_type ||= "#{ @polymorphic }_type"
308
+ @foreign_key ||= "#{ @polymorphic }_id"
309
+ end
310
+
311
+ @foreign_key ||= options[:foreign_key] || class_name.foreign_key
312
+
313
+ lineno, code = __LINE__ + 1, <<-__
314
+ def #{ name }(*args, &block)
315
+ @#{ name }_record ||= nil
316
+ options = args.extract_options!.to_options!
317
+ forcing = options.delete(:force)
318
+ @#{ name }_record = nil if forcing
319
+ @#{ name }_record ||= #{ name }_association.get(self, *args, &block)
320
+ end
321
+
322
+ def #{ name }=(value)
323
+ record =
324
+ case value
325
+ when Hash
326
+ build_#{ name }(value)
327
+ when Base
328
+ value
329
+ end
330
+ #{ name }_association.set(self, record)
331
+ end
332
+
333
+ def build_#{ name }(attributes = {})
334
+ record = #{ class_name }.new(attributes)
335
+ self.#{ name } = record
336
+ record
337
+ end
338
+
339
+ def create_#{ name }(attributes = {})
340
+ record = build_#{ name }(attributes)
341
+ record.save
342
+ record
343
+ end
344
+ __
345
+ filename = __FILE__
346
+ eval code, @base.module_eval('binding'), filename, lineno
347
+ end
348
+
349
+ def get(record, *args, &block)
350
+ find_associated_object_for(record)
351
+ end
352
+
353
+ def find_associated_object_for(record)
354
+ return nil unless record[foreign_key]
355
+ conditions = {}
356
+ if foreign_type
357
+ conditions[foreign_type] = class_name
358
+ end
359
+ conditions[:id] = record[foreign_key]
360
+ associated = associated_class.find(:first, :conditions => conditions_for(conditions))
361
+ end
362
+
363
+ def set(record, value)
364
+ record[foreign_key] = value.is_a?(Base) ? value.id : value
365
+ value
366
+ end
367
+ end
368
+
369
+ class HasOne < Association
370
+ attr :polymorphic
371
+ attr :foreign_type
372
+ attr :pluralized
373
+
374
+ def initialize(base, name, options = {}, &block)
375
+ super
376
+
377
+ @polymorphic ||= options[:polymorphic]
378
+
379
+ if @polymorphic
380
+ @foreign_type ||= "#{ @polymorphic }_type"
381
+ @foreign_key ||= "#{ @polymorphic }_id"
382
+ end
383
+
384
+ @foreign_key ||= (options[:foreign_key] || @base.name.foreign_key).to_s
385
+
386
+ @pluralized = pluralized = name.to_s.pluralize
387
+
388
+ @base.module_eval {
389
+ unless instance_methods.include?(pluralized)
390
+ has_many(pluralized, options, &block)
391
+ end
392
+ }
393
+
394
+ lineno, code = __LINE__ + 1, <<-__
395
+ def #{ name }(*args, &block)
396
+ @#{ name } ||= nil
397
+ options = args.extract_options!.to_options!
398
+ forcing = options.delete(:force)
399
+ @#{ name } = nil if forcing
400
+ @#{ name } ||= #{ pluralized }().first
401
+ end
402
+
403
+ def #{ name }=(value)
404
+ if old = #{ name }()
405
+ case #{ dependent.inspect }
406
+ when :destroy
407
+ old.destroy
408
+ when :delete
409
+ old.delete
410
+ when :nullify, nil
411
+ old.send("#{ foreign_key }=", nil)
412
+ old.send("#{ foreign_type }=", nil) if #{ !!foreign_type }
413
+ end
414
+ end
415
+
416
+ list = #{ pluralized }()
417
+
418
+ case value
419
+ when Hash
420
+ list.build(value)
421
+ when Base
422
+ list.associate(value)
423
+ when Array
424
+ list.associate(*value)
425
+ end
426
+ end
427
+
428
+ def build_#{ name }(attributes = {})
429
+ record = #{ class_name }.new(attributes)
430
+ self.#{ name } = record
431
+ record
432
+ end
433
+
434
+ def create_#{ name }(attributes = {})
435
+ record = build_#{ name }(attributes)
436
+ record.save
437
+ record
438
+ end
439
+ __
440
+ filename = __FILE__
441
+ eval code, @base.module_eval('binding'), filename, lineno
442
+ end
443
+ end
444
+
445
+
446
+ class << Base
447
+ def associations()
448
+ @associations ||= Array.fields
449
+ end
450
+
451
+ def association(type, *args, &block)
452
+ association =
453
+ case type.to_s.to_sym
454
+ when :has_many
455
+ Association::HasMany.new(self, *args, &block)
456
+ when :belongs_to
457
+ Association::BelongsTo.new(self, *args, &block)
458
+ when :has_one
459
+ Association::HasOne.new(self, *args, &block)
460
+ end
461
+ associations[association.name] = association
462
+ end
463
+ alias_method 'associate', 'association'
464
+ alias_method 'associates', 'association'
465
+
466
+ def has_many(*args, &block)
467
+ associates(:has_many, *args, &block)
468
+ end
469
+ def belongs_to(*args, &block)
470
+ associates(:belongs_to, *args, &block)
471
+ end
472
+ def has_one(*args, &block)
473
+ associates(:has_one, *args, &block)
474
+ end
475
+ end
476
+
477
+ end
478
+ end
479
+ end
480
+ end
481
+