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.
- data/Rakefile +274 -0
- data/helene.gemspec +26 -0
- data/lib/helene.rb +113 -0
- data/lib/helene/attempt.rb +46 -0
- data/lib/helene/aws.rb +50 -0
- data/lib/helene/config.rb +147 -0
- data/lib/helene/content_type.rb +15 -0
- data/lib/helene/content_type.yml +661 -0
- data/lib/helene/error.rb +12 -0
- data/lib/helene/logging.rb +55 -0
- data/lib/helene/objectpool.rb +220 -0
- data/lib/helene/rails.rb +21 -0
- data/lib/helene/rightscale/acf/right_acf_interface.rb +379 -0
- data/lib/helene/rightscale/awsbase/benchmark_fix.rb +39 -0
- data/lib/helene/rightscale/awsbase/right_awsbase.rb +803 -0
- data/lib/helene/rightscale/awsbase/support.rb +111 -0
- data/lib/helene/rightscale/ec2/right_ec2.rb +1737 -0
- data/lib/helene/rightscale/net_fix.rb +160 -0
- data/lib/helene/rightscale/right_aws.rb +71 -0
- data/lib/helene/rightscale/right_http_connection.rb +507 -0
- data/lib/helene/rightscale/s3/right_s3.rb +1094 -0
- data/lib/helene/rightscale/s3/right_s3_interface.rb +1180 -0
- data/lib/helene/rightscale/sdb/active_sdb.rb +930 -0
- data/lib/helene/rightscale/sdb/right_sdb_interface.rb +696 -0
- data/lib/helene/rightscale/sqs/right_sqs.rb +388 -0
- data/lib/helene/rightscale/sqs/right_sqs_gen2.rb +286 -0
- data/lib/helene/rightscale/sqs/right_sqs_gen2_interface.rb +444 -0
- data/lib/helene/rightscale/sqs/right_sqs_interface.rb +596 -0
- data/lib/helene/s3.rb +34 -0
- data/lib/helene/s3/bucket.rb +379 -0
- data/lib/helene/s3/grantee.rb +134 -0
- data/lib/helene/s3/key.rb +162 -0
- data/lib/helene/s3/owner.rb +16 -0
- data/lib/helene/sdb.rb +9 -0
- data/lib/helene/sdb/base.rb +1204 -0
- data/lib/helene/sdb/base/associations.rb +481 -0
- data/lib/helene/sdb/base/attributes.rb +90 -0
- data/lib/helene/sdb/base/connection.rb +20 -0
- data/lib/helene/sdb/base/error.rb +20 -0
- data/lib/helene/sdb/base/hooks.rb +82 -0
- data/lib/helene/sdb/base/literal.rb +52 -0
- data/lib/helene/sdb/base/logging.rb +23 -0
- data/lib/helene/sdb/base/transactions.rb +53 -0
- data/lib/helene/sdb/base/type.rb +137 -0
- data/lib/helene/sdb/base/types.rb +123 -0
- data/lib/helene/sdb/base/validations.rb +256 -0
- data/lib/helene/sdb/cast.rb +114 -0
- data/lib/helene/sdb/connection.rb +36 -0
- data/lib/helene/sdb/error.rb +5 -0
- data/lib/helene/sdb/interface.rb +412 -0
- data/lib/helene/sdb/sentinel.rb +15 -0
- data/lib/helene/sleepcycle.rb +29 -0
- data/lib/helene/superhash.rb +297 -0
- data/lib/helene/util.rb +132 -0
- data/test/auth.rb +31 -0
- data/test/helper.rb +98 -0
- data/test/integration/begin.rb +0 -0
- data/test/integration/ensure.rb +8 -0
- data/test/integration/s3/bucket.rb +106 -0
- data/test/integration/sdb/associations.rb +45 -0
- data/test/integration/sdb/creating.rb +13 -0
- data/test/integration/sdb/emptiness.rb +56 -0
- data/test/integration/sdb/hooks.rb +19 -0
- data/test/integration/sdb/limits.rb +27 -0
- data/test/integration/sdb/saving.rb +21 -0
- data/test/integration/sdb/selecting.rb +39 -0
- data/test/integration/sdb/types.rb +31 -0
- data/test/integration/sdb/validations.rb +60 -0
- data/test/integration/setup.rb +27 -0
- data/test/integration/teardown.rb +21 -0
- data/test/loader.rb +39 -0
- metadata +139 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
module Helene
|
2
|
+
module Sdb
|
3
|
+
module Sentinel
|
4
|
+
Nil = 'nil' unless defined?(Sentinel::Nil)
|
5
|
+
Set = '[]' unless defined?(Sentinel::Set)
|
6
|
+
|
7
|
+
class << Sentinel
|
8
|
+
def Nil() Nil end
|
9
|
+
def nil() Nil end
|
10
|
+
def Set() Set end
|
11
|
+
def set() Set end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Helene
|
2
|
+
class SleepCycle < ::Array
|
3
|
+
Min = 0.01 unless defined?(Min)
|
4
|
+
Max = 1.28 unless defined?(Max)
|
5
|
+
|
6
|
+
attr_accessor :min
|
7
|
+
attr_accessor :max
|
8
|
+
attr_accessor :pos
|
9
|
+
|
10
|
+
def initialize(*args)
|
11
|
+
options = args.extract_options!.to_options!
|
12
|
+
@min = options[:min] || Min
|
13
|
+
@max = options[:max] || Max
|
14
|
+
m = @min
|
15
|
+
while m < @max; push(m) and m *= 2; end
|
16
|
+
@pos = 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def next
|
20
|
+
self[@pos]
|
21
|
+
ensure
|
22
|
+
@pos = ((@pos + 1) % size)
|
23
|
+
end
|
24
|
+
|
25
|
+
def reset
|
26
|
+
@pos = 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
module Helene
|
2
|
+
class SuperHash
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_reader :parents
|
6
|
+
|
7
|
+
def initialize parents = [], default = nil
|
8
|
+
@hash = Hash.new default
|
9
|
+
@parents =
|
10
|
+
case parents
|
11
|
+
when NilClass
|
12
|
+
[]
|
13
|
+
when Array
|
14
|
+
parents.flatten
|
15
|
+
else
|
16
|
+
[parents]
|
17
|
+
end
|
18
|
+
@parents.each do |parent|
|
19
|
+
raise ArgumentError, parent.class.name unless parent.respond_to?('key?')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# methods that are not overrides of Hash methods
|
24
|
+
|
25
|
+
def inherits_key? k
|
26
|
+
!(@hash.key? k) && (!! @parents.find {|parent| parent.key? k } )
|
27
|
+
end
|
28
|
+
|
29
|
+
def own
|
30
|
+
@hash
|
31
|
+
end
|
32
|
+
|
33
|
+
def own_keys
|
34
|
+
@hash.keys
|
35
|
+
end
|
36
|
+
|
37
|
+
def owns_key? k
|
38
|
+
@hash.key? k
|
39
|
+
end
|
40
|
+
|
41
|
+
# methods that override Hash methods
|
42
|
+
|
43
|
+
def ==(other)
|
44
|
+
return false unless other.respond_to? :size and
|
45
|
+
size == other.size and
|
46
|
+
other.respond_to? :[]
|
47
|
+
each { |key, value| return false unless self[key] == other[key] }
|
48
|
+
return true
|
49
|
+
end
|
50
|
+
|
51
|
+
def [](key)
|
52
|
+
fetch(key) {default}
|
53
|
+
end
|
54
|
+
|
55
|
+
def []=(key, value)
|
56
|
+
@hash[key] = value
|
57
|
+
end
|
58
|
+
alias store []=
|
59
|
+
|
60
|
+
def clear
|
61
|
+
delete_if {true}
|
62
|
+
end
|
63
|
+
|
64
|
+
def default
|
65
|
+
@hash.default
|
66
|
+
end
|
67
|
+
|
68
|
+
def default=(value)
|
69
|
+
@hash.default = value
|
70
|
+
end
|
71
|
+
|
72
|
+
def delete(key)
|
73
|
+
if key? key
|
74
|
+
@hash.delete(key) do
|
75
|
+
value = fetch(key)
|
76
|
+
@hash[key] = default
|
77
|
+
value
|
78
|
+
end
|
79
|
+
else
|
80
|
+
block_given? ? (yield key) : default
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def delete_if
|
85
|
+
each do |key, value|
|
86
|
+
if yield key, value
|
87
|
+
@hash.delete(key) { @hash[key] = default }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def each
|
93
|
+
keys.each { |k| yield k, fetch(k) }
|
94
|
+
self
|
95
|
+
end
|
96
|
+
alias each_pair each
|
97
|
+
|
98
|
+
def each_key
|
99
|
+
keys.each { |k| yield k }
|
100
|
+
self
|
101
|
+
end
|
102
|
+
|
103
|
+
def each_value
|
104
|
+
keys.each { |k| yield fetch(k) }
|
105
|
+
self
|
106
|
+
end
|
107
|
+
|
108
|
+
def empty?
|
109
|
+
@hash.empty? && ( not @parents.find {|parent| not parent.empty?} )
|
110
|
+
end
|
111
|
+
|
112
|
+
def fetch(*args)
|
113
|
+
case args.size
|
114
|
+
when 1
|
115
|
+
key, = args
|
116
|
+
@hash.fetch(key) {
|
117
|
+
@parents.each do |parent|
|
118
|
+
begin
|
119
|
+
return parent.fetch(key)
|
120
|
+
rescue IndexError
|
121
|
+
end
|
122
|
+
end
|
123
|
+
if block_given?
|
124
|
+
yield key
|
125
|
+
else
|
126
|
+
raise IndexError, "key not found"
|
127
|
+
end
|
128
|
+
}
|
129
|
+
when 2
|
130
|
+
if block_given?
|
131
|
+
raise ArgumentError, "wrong # of arguments"
|
132
|
+
end
|
133
|
+
key, default_object = args
|
134
|
+
@hash.fetch(key) {
|
135
|
+
@parents.each do |parent|
|
136
|
+
begin
|
137
|
+
return parent.fetch(key)
|
138
|
+
rescue IndexError
|
139
|
+
end
|
140
|
+
end
|
141
|
+
return default_object
|
142
|
+
}
|
143
|
+
else
|
144
|
+
raise ArgumentError, "wrong # of arguments(#{args.size} for 2)"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def has_value? val
|
149
|
+
each { |k,v| return true if val == v }
|
150
|
+
return false
|
151
|
+
end
|
152
|
+
alias value? has_value?
|
153
|
+
|
154
|
+
def index val
|
155
|
+
each { |k,v| return k if val == v }
|
156
|
+
return false
|
157
|
+
end
|
158
|
+
|
159
|
+
def indexes(*ks)
|
160
|
+
ks.collect { |k| index k }
|
161
|
+
end
|
162
|
+
alias indices indexes
|
163
|
+
|
164
|
+
def invert
|
165
|
+
h = {}
|
166
|
+
keys.each { |k| h[fetch(k)] = k }
|
167
|
+
h
|
168
|
+
end
|
169
|
+
|
170
|
+
def key? k
|
171
|
+
(@hash.key? k) || (!! @parents.find {|parent| parent.key?(k)} )
|
172
|
+
end
|
173
|
+
alias has_key? key?
|
174
|
+
alias include? key?
|
175
|
+
alias member? key?
|
176
|
+
|
177
|
+
def keys
|
178
|
+
(@hash.keys + (@parents.collect { |parent| parent.keys }).flatten).uniq
|
179
|
+
end
|
180
|
+
|
181
|
+
def rehash
|
182
|
+
@hash.rehash
|
183
|
+
@parents.each { |parent| parent.rehash if parent.respond_to? :rehash }
|
184
|
+
self
|
185
|
+
end
|
186
|
+
|
187
|
+
def reject
|
188
|
+
dup.delete_if { |k, v| yield k, v } ## or is '&Proc.new' faster?
|
189
|
+
end
|
190
|
+
|
191
|
+
def reject!
|
192
|
+
changed = false
|
193
|
+
|
194
|
+
each do |key, value|
|
195
|
+
if yield key, value
|
196
|
+
changed = true
|
197
|
+
@hash.delete(key) { @hash[key] = default }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
changed ? self : nil
|
202
|
+
end
|
203
|
+
|
204
|
+
def replace hash
|
205
|
+
@hash.replace hash
|
206
|
+
@parents.replace []
|
207
|
+
end
|
208
|
+
|
209
|
+
class ParentImmutableError < StandardError; end
|
210
|
+
|
211
|
+
def shift
|
212
|
+
if @hash.empty?
|
213
|
+
raise ParentImmutableError, "Attempted to shift data out of parent"
|
214
|
+
else
|
215
|
+
@hash.shift
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def size
|
220
|
+
keys.size
|
221
|
+
end
|
222
|
+
alias length size
|
223
|
+
|
224
|
+
def sort
|
225
|
+
if block_given?
|
226
|
+
to_a.sort { |x, y| yield x, y } ## or is '&Proc.new' faster?
|
227
|
+
else
|
228
|
+
to_a.sort
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def to_a
|
233
|
+
to_hash.to_a
|
234
|
+
end
|
235
|
+
|
236
|
+
def to_hash
|
237
|
+
h = {}
|
238
|
+
keys.each { |k| h[k] = fetch(k) }
|
239
|
+
h
|
240
|
+
end
|
241
|
+
|
242
|
+
def to_s
|
243
|
+
to_hash.to_s
|
244
|
+
end
|
245
|
+
|
246
|
+
def update h
|
247
|
+
@hash.update h
|
248
|
+
self
|
249
|
+
end
|
250
|
+
|
251
|
+
def values
|
252
|
+
keys.collect { |k| self[k] }
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
class Class
|
259
|
+
private
|
260
|
+
def class_superhash(*vars)
|
261
|
+
for var in vars
|
262
|
+
class_eval %{
|
263
|
+
@#{var} = Hash.new
|
264
|
+
def self.#{var}
|
265
|
+
@#{var} ||= SuperHash.new(superclass.#{var})
|
266
|
+
end
|
267
|
+
}
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# A superhash of key-value pairs in which the value is a superhash
|
272
|
+
# which inherits from the key-indexed superhash in the superclass.
|
273
|
+
def class_superhash2(*vars)
|
274
|
+
for var in vars
|
275
|
+
class_eval %{
|
276
|
+
@#{var} = Hash.new
|
277
|
+
def self.#{var}(arg = nil)
|
278
|
+
@#{var} ||= SuperHash.new(superclass.#{var})
|
279
|
+
if arg
|
280
|
+
if self == #{self.name}
|
281
|
+
unless @#{var}.has_key? arg
|
282
|
+
@#{var}[arg] = Hash.new
|
283
|
+
end
|
284
|
+
else
|
285
|
+
unless @#{var}.owns_key? arg
|
286
|
+
@#{var}[arg] = SuperHash.new(superclass.#{var}(arg))
|
287
|
+
end
|
288
|
+
end
|
289
|
+
@#{var}[arg]
|
290
|
+
else
|
291
|
+
@#{var}
|
292
|
+
end
|
293
|
+
end
|
294
|
+
}
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
data/lib/helene/util.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
module Helene
|
2
|
+
module Util
|
3
|
+
def homedir
|
4
|
+
homedir =
|
5
|
+
catch :home do
|
6
|
+
["HOME", "USERPROFILE"].each do |key|
|
7
|
+
throw(:home, ENV[key]) if ENV[key]
|
8
|
+
end
|
9
|
+
if ENV["HOMEDRIVE"] and ENV["HOMEPATH"]
|
10
|
+
throw(:home, "#{ ENV['HOMEDRIVE'] }:#{ ENV['HOMEPATH'] }")
|
11
|
+
end
|
12
|
+
File.expand_path("~") rescue(File::ALT_SEPARATOR ? "C:/" : "/")
|
13
|
+
end
|
14
|
+
File.expand_path homedir
|
15
|
+
end
|
16
|
+
|
17
|
+
def unindent! s
|
18
|
+
indent = nil
|
19
|
+
s.each do |line|
|
20
|
+
next if line =~ %r/^\s*$/
|
21
|
+
indent = line[%r/^\s*/] and break
|
22
|
+
end
|
23
|
+
s.gsub! %r/^#{ indent }/, "" if indent
|
24
|
+
s
|
25
|
+
end
|
26
|
+
|
27
|
+
def unindent s
|
28
|
+
unindent! "#{ s }"
|
29
|
+
end
|
30
|
+
|
31
|
+
def indent! s, n = 2
|
32
|
+
n = Integer n
|
33
|
+
margin = ' ' * n
|
34
|
+
unindent! s
|
35
|
+
s.gsub! %r/^/, margin
|
36
|
+
s
|
37
|
+
end
|
38
|
+
|
39
|
+
def indent s, n = 2
|
40
|
+
indent!(s.to_s.dup, n)
|
41
|
+
end
|
42
|
+
|
43
|
+
def inline! s
|
44
|
+
s.gsub! %r/\n/, ' '
|
45
|
+
s.squeeze! ' '
|
46
|
+
s
|
47
|
+
end
|
48
|
+
|
49
|
+
def inline s
|
50
|
+
inline!(s.dup)
|
51
|
+
end
|
52
|
+
|
53
|
+
def random_string options = {}
|
54
|
+
options.to_options!
|
55
|
+
|
56
|
+
Kernel.srand
|
57
|
+
|
58
|
+
default_chars = ( ('a' .. 'z').to_a + ('A' .. 'Z').to_a + (0 .. 9).to_a )
|
59
|
+
%w( 0 O l ).each{|char| default_chars.delete(char)}
|
60
|
+
|
61
|
+
default_size = 6
|
62
|
+
|
63
|
+
chars = options[:chars] || default_chars
|
64
|
+
size = Integer(options[:size] || default_size)
|
65
|
+
|
66
|
+
Array.new(size).map{ chars[rand(2**32)%chars.size, 1] }.join
|
67
|
+
end
|
68
|
+
|
69
|
+
def snake_case(camel_cased_word)
|
70
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
71
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
72
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
73
|
+
tr("-", "_").
|
74
|
+
downcase
|
75
|
+
end
|
76
|
+
|
77
|
+
def camel_case(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
78
|
+
if first_letter_in_uppercase
|
79
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
80
|
+
else
|
81
|
+
camel_case(lower_case_and_underscored_word).sub(%r/^(.)/){ $1.downcase }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def normalize!(s)
|
86
|
+
s.to_s.gsub!(%r/\s/, ' ')
|
87
|
+
s
|
88
|
+
end
|
89
|
+
|
90
|
+
def number_for(arg)
|
91
|
+
arg = arg.to_s
|
92
|
+
arg.gsub! %r/^[0\s]+/, ''
|
93
|
+
Integer(arg) rescue Float(arg)
|
94
|
+
end
|
95
|
+
|
96
|
+
def compress(data)
|
97
|
+
writer = Zlib::GzipWriter.new(StringIO.new(result=''))
|
98
|
+
writer.write(data.to_s)
|
99
|
+
writer.close
|
100
|
+
result
|
101
|
+
end
|
102
|
+
|
103
|
+
def decompress(data)
|
104
|
+
Zlib::GzipReader.new(StringIO.new(data.to_s)).read
|
105
|
+
end
|
106
|
+
|
107
|
+
def encode(data)
|
108
|
+
Base64.encode64(compress(data))
|
109
|
+
end
|
110
|
+
|
111
|
+
def decode(data)
|
112
|
+
decompress(Base64.decode64(data.to_s))
|
113
|
+
end
|
114
|
+
|
115
|
+
def uuid
|
116
|
+
UUID.timestamp_create().to_s
|
117
|
+
end
|
118
|
+
|
119
|
+
def emsg(e)
|
120
|
+
m = e.message
|
121
|
+
c = c.class
|
122
|
+
b = (e.backtrace||[]).join("\n")
|
123
|
+
"#{ m }(#{ c })#{ b }"
|
124
|
+
end
|
125
|
+
|
126
|
+
def content_type_for(basename)
|
127
|
+
ContentType.for(basename)
|
128
|
+
end
|
129
|
+
|
130
|
+
extend self
|
131
|
+
end
|
132
|
+
end
|