right_aws 1.9.0 → 3.1.0
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/History.txt +164 -13
- data/Manifest.txt +28 -1
- data/README.txt +12 -10
- data/Rakefile +56 -29
- data/lib/acf/right_acf_interface.rb +343 -172
- data/lib/acf/right_acf_invalidations.rb +144 -0
- data/lib/acf/right_acf_origin_access_identities.rb +230 -0
- data/lib/acf/right_acf_streaming_interface.rb +229 -0
- data/lib/acw/right_acw_interface.rb +248 -0
- data/lib/as/right_as_interface.rb +698 -0
- data/lib/awsbase/right_awsbase.rb +755 -115
- data/lib/awsbase/support.rb +2 -78
- data/lib/awsbase/version.rb +9 -0
- data/lib/ec2/right_ec2.rb +274 -1294
- data/lib/ec2/right_ec2_ebs.rb +514 -0
- data/lib/ec2/right_ec2_images.rb +444 -0
- data/lib/ec2/right_ec2_instances.rb +797 -0
- data/lib/ec2/right_ec2_monitoring.rb +70 -0
- data/lib/ec2/right_ec2_placement_groups.rb +108 -0
- data/lib/ec2/right_ec2_reserved_instances.rb +243 -0
- data/lib/ec2/right_ec2_security_groups.rb +496 -0
- data/lib/ec2/right_ec2_spot_instances.rb +422 -0
- data/lib/ec2/right_ec2_tags.rb +139 -0
- data/lib/ec2/right_ec2_vpc.rb +598 -0
- data/lib/ec2/right_ec2_vpc2.rb +382 -0
- data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
- data/lib/elb/right_elb_interface.rb +573 -0
- data/lib/emr/right_emr_interface.rb +728 -0
- data/lib/iam/right_iam_access_keys.rb +71 -0
- data/lib/iam/right_iam_groups.rb +195 -0
- data/lib/iam/right_iam_interface.rb +341 -0
- data/lib/iam/right_iam_mfa_devices.rb +67 -0
- data/lib/iam/right_iam_users.rb +251 -0
- data/lib/rds/right_rds_interface.rb +1657 -0
- data/lib/right_aws.rb +30 -13
- data/lib/route_53/right_route_53_interface.rb +641 -0
- data/lib/s3/right_s3.rb +108 -41
- data/lib/s3/right_s3_interface.rb +349 -118
- data/lib/sdb/active_sdb.rb +388 -54
- data/lib/sdb/right_sdb_interface.rb +323 -64
- data/lib/sns/right_sns_interface.rb +286 -0
- data/lib/sqs/right_sqs.rb +1 -2
- data/lib/sqs/right_sqs_gen2.rb +73 -17
- data/lib/sqs/right_sqs_gen2_interface.rb +146 -73
- data/lib/sqs/right_sqs_interface.rb +12 -22
- data/right_aws.gemspec +91 -0
- data/test/README.mdown +39 -0
- data/test/acf/test_right_acf.rb +11 -19
- data/test/awsbase/test_helper.rb +2 -0
- data/test/awsbase/test_right_awsbase.rb +11 -0
- data/test/ec2/test_right_ec2.rb +32 -1
- data/test/elb/test_helper.rb +2 -0
- data/test/elb/test_right_elb.rb +43 -0
- data/test/rds/test_helper.rb +2 -0
- data/test/rds/test_right_rds.rb +120 -0
- data/test/route_53/fixtures/a_record.xml +18 -0
- data/test/route_53/fixtures/alias_record.xml +18 -0
- data/test/route_53/test_helper.rb +2 -0
- data/test/route_53/test_right_route_53.rb +141 -0
- data/test/s3/test_right_s3.rb +176 -42
- data/test/s3/test_right_s3_stubbed.rb +6 -4
- data/test/sdb/test_active_sdb.rb +120 -19
- data/test/sdb/test_batch_put_attributes.rb +54 -0
- data/test/sdb/test_right_sdb.rb +71 -16
- data/test/sns/test_helper.rb +2 -0
- data/test/sns/test_right_sns.rb +153 -0
- data/test/sqs/test_right_sqs.rb +0 -6
- data/test/sqs/test_right_sqs_gen2.rb +104 -49
- data/test/ts_right_aws.rb +1 -0
- metadata +181 -22
@@ -32,7 +32,8 @@ module RightAws
|
|
32
32
|
DEFAULT_HOST = 'sdb.amazonaws.com'
|
33
33
|
DEFAULT_PORT = 443
|
34
34
|
DEFAULT_PROTOCOL = 'https'
|
35
|
-
|
35
|
+
DEFAULT_PATH = '/'
|
36
|
+
API_VERSION = '2009-04-15'
|
36
37
|
DEFAULT_NIL_REPRESENTATION = 'nil'
|
37
38
|
|
38
39
|
@@bench = AwsBenchmarkingBlock.new
|
@@ -47,24 +48,25 @@ module RightAws
|
|
47
48
|
# { :server => 'sdb.amazonaws.com' # Amazon service host: 'sdb.amazonaws.com'(default)
|
48
49
|
# :port => 443 # Amazon service port: 80 or 443(default)
|
49
50
|
# :protocol => 'https' # Amazon service protocol: 'http' or 'https'(default)
|
50
|
-
# :signature_version => '0' # The signature version : '0' or '
|
51
|
-
# :multi_thread => true|false # Multi-threaded (connection per each thread): true or false(default)
|
51
|
+
# :signature_version => '0' # The signature version : '0','1 or '2'(default)
|
52
52
|
# :logger => Logger Object # Logger instance: logs to STDOUT if omitted
|
53
53
|
# :nil_representation => 'mynil'} # interpret Ruby nil as this string value; i.e. use this string in SDB to represent Ruby nils (default is the string 'nil')
|
54
54
|
#
|
55
55
|
# Example:
|
56
56
|
#
|
57
|
-
# sdb = RightAws::SdbInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX', {:
|
57
|
+
# sdb = RightAws::SdbInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX', {:logger => Logger.new('/tmp/x.log')}) #=> #<RightSdb:0xa6b8c27c>
|
58
58
|
#
|
59
59
|
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/
|
60
60
|
#
|
61
61
|
def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
|
62
62
|
@nil_rep = params[:nil_representation] ? params[:nil_representation] : DEFAULT_NIL_REPRESENTATION
|
63
63
|
params.delete(:nil_representation)
|
64
|
-
init({ :name
|
65
|
-
:default_host
|
66
|
-
:default_port
|
67
|
-
:
|
64
|
+
init({ :name => 'SDB',
|
65
|
+
:default_host => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).host : DEFAULT_HOST,
|
66
|
+
:default_port => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).port : DEFAULT_PORT,
|
67
|
+
:default_service => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).path : DEFAULT_PATH,
|
68
|
+
:default_protocol => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).scheme : DEFAULT_PROTOCOL,
|
69
|
+
:default_api_version => ENV['SDB_API_VERSION'] || API_VERSION },
|
68
70
|
aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'],
|
69
71
|
aws_secret_access_key || ENV['AWS_SECRET_ACCESS_KEY'],
|
70
72
|
params)
|
@@ -73,69 +75,55 @@ module RightAws
|
|
73
75
|
#-----------------------------------------------------------------
|
74
76
|
# Requests
|
75
77
|
#-----------------------------------------------------------------
|
78
|
+
|
76
79
|
def generate_request(action, params={}) #:nodoc:
|
77
|
-
|
78
|
-
params.delete_if {|key,value| value.nil? }
|
79
|
-
#params_string = params.to_a.collect{|key,val| key + "=#{CGI::escape(val.to_s)}" }.join("&")
|
80
|
-
# prepare service data
|
81
|
-
service_hash = {"Action" => action,
|
82
|
-
"AWSAccessKeyId" => @aws_access_key_id,
|
83
|
-
"Version" => API_VERSION,
|
84
|
-
"Timestamp" => Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
|
85
|
-
"SignatureVersion" => signature_version }
|
86
|
-
service_hash.update(params)
|
87
|
-
# prepare string to sight
|
88
|
-
string_to_sign = case signature_version
|
89
|
-
when '0' then service_hash["Action"] + service_hash["Timestamp"]
|
90
|
-
when '1' then service_hash.sort{|a,b| (a[0].to_s.downcase)<=>(b[0].to_s.downcase)}.to_s
|
91
|
-
end
|
92
|
-
service_hash.update('Signature' => AwsUtils::sign(@aws_secret_access_key, string_to_sign))
|
93
|
-
service_string = service_hash.to_a.collect{|key,val| key + "=#{CGI::escape(val.to_s)}" }.join("&")
|
94
|
-
#
|
95
|
-
# use POST method if the length of the query string is too large
|
96
|
-
# see http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/MakingRESTRequests.html
|
97
|
-
if service_string.size > 2000
|
98
|
-
request = Net::HTTP::Post.new("/")
|
99
|
-
request.body = service_string
|
100
|
-
else
|
101
|
-
#params_string = "&#{params_string}" unless params_string.blank?
|
102
|
-
request = Net::HTTP::Get.new("/?#{service_string}")
|
103
|
-
end
|
104
|
-
# prepare output hash
|
105
|
-
{ :request => request,
|
106
|
-
:server => @params[:server],
|
107
|
-
:port => @params[:port],
|
108
|
-
:protocol => @params[:protocol] }
|
80
|
+
generate_request_impl(:get, action, params )
|
109
81
|
end
|
110
82
|
|
111
83
|
# Sends request to Amazon and parses the response
|
112
84
|
# Raises AwsError if any banana happened
|
113
85
|
def request_info(request, parser) #:nodoc:
|
114
|
-
|
115
|
-
thread[:sdb_connection] ||= Rightscale::HttpConnection.new(:exception => AwsError, :logger => @logger)
|
116
|
-
request_info_impl(thread[:sdb_connection], @@bench, request, parser)
|
86
|
+
request_info_impl(:sdb_connection, @@bench, request, parser)
|
117
87
|
end
|
118
88
|
|
119
89
|
# Prepare attributes for putting.
|
120
90
|
# (used by put_attributes)
|
121
|
-
def pack_attributes(
|
91
|
+
def pack_attributes(items_or_attributes, replace = false, batch = false) #:nodoc:
|
92
|
+
if batch
|
93
|
+
index = 0
|
94
|
+
items_or_attributes.inject({}){|result, (item_name, attributes)|
|
95
|
+
item_prefix = "Item.#{index}."
|
96
|
+
result["#{item_prefix}ItemName"] = item_name.to_s
|
97
|
+
result.merge!(
|
98
|
+
pack_single_item_attributes(attributes, replace, item_prefix))
|
99
|
+
index += 1
|
100
|
+
result
|
101
|
+
}
|
102
|
+
else
|
103
|
+
pack_single_item_attributes(items_or_attributes, replace)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def pack_single_item_attributes(attributes, replace, prefix = "")
|
122
108
|
result = {}
|
123
109
|
if attributes
|
124
110
|
idx = 0
|
125
111
|
skip_values = attributes.is_a?(Array)
|
126
112
|
attributes.each do |attribute, values|
|
127
113
|
# set replacement attribute
|
128
|
-
result["Attribute.#{idx}.Replace"] = 'true' if replace
|
114
|
+
result["#{prefix}Attribute.#{idx}.Replace"] = 'true' if replace
|
129
115
|
# pack Name/Value
|
130
116
|
unless values.nil?
|
131
|
-
Array(values)
|
132
|
-
|
133
|
-
|
117
|
+
# Array(values) does not work here:
|
118
|
+
# - Array('') => [] but we wanna get here ['']
|
119
|
+
[values].flatten.each do |value|
|
120
|
+
result["#{prefix}Attribute.#{idx}.Name"] = attribute
|
121
|
+
result["#{prefix}Attribute.#{idx}.Value"] = ruby_to_sdb(value) unless skip_values
|
134
122
|
idx += 1
|
135
123
|
end
|
136
124
|
else
|
137
|
-
result["Attribute.#{idx}.Name"] = attribute
|
138
|
-
result["Attribute.#{idx}.Value"] = ruby_to_sdb(nil) unless skip_values
|
125
|
+
result["#{prefix}Attribute.#{idx}.Name"] = attribute
|
126
|
+
result["#{prefix}Attribute.#{idx}.Value"] = ruby_to_sdb(nil) unless skip_values
|
139
127
|
idx += 1
|
140
128
|
end
|
141
129
|
end
|
@@ -163,23 +151,44 @@ module RightAws
|
|
163
151
|
def sdb_to_ruby(value)
|
164
152
|
value.eql?(@nil_rep) ? nil : value
|
165
153
|
end
|
166
|
-
|
154
|
+
|
155
|
+
# Convert select and query_with_attributes responses to a Ruby language values by replacing the user's chosen string representation of nil with Ruby nil.
|
156
|
+
# (This method affects on a passed response value)
|
157
|
+
def select_response_to_ruby(response) #:nodoc:
|
158
|
+
response[:items].each_with_index do |item, idx|
|
159
|
+
item.each do |key, attributes|
|
160
|
+
attributes.each do |name, values|
|
161
|
+
values.collect! { |value| sdb_to_ruby(value) }
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
response
|
166
|
+
end
|
167
|
+
|
167
168
|
# Create query expression from an array.
|
168
169
|
# (similar to ActiveRecord::Base#find using :conditions => ['query', param1, .., paramN])
|
169
170
|
#
|
170
171
|
def query_expression_from_array(params) #:nodoc:
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
end
|
172
|
+
return '' if params.right_blank?
|
173
|
+
query = params.shift.to_s
|
174
|
+
query.gsub(/(\\)?(\?)/) do
|
175
|
+
if $1 # if escaped '\?' is found - replace it by '?' without backslash
|
176
|
+
"?"
|
177
|
+
else # well, if no backslash precedes '?' then replace it by next param from the list
|
178
|
+
escape(params.shift)
|
179
179
|
end
|
180
180
|
end
|
181
181
|
end
|
182
|
-
|
182
|
+
|
183
|
+
def query_expression_from_hash(hash)
|
184
|
+
return '' if hash.right_blank?
|
185
|
+
expression = []
|
186
|
+
hash.each do |key, value|
|
187
|
+
expression << "#{key}=#{escape(value)}"
|
188
|
+
end
|
189
|
+
expression.join(' AND ')
|
190
|
+
end
|
191
|
+
|
183
192
|
# Retrieve a list of SDB domains from Amazon.
|
184
193
|
#
|
185
194
|
# Returns a hash:
|
@@ -245,6 +254,27 @@ module RightAws
|
|
245
254
|
on_exception
|
246
255
|
end
|
247
256
|
|
257
|
+
# Query Metadata for Domain
|
258
|
+
#
|
259
|
+
# Returns a hash on success or an exception on error.
|
260
|
+
#
|
261
|
+
# example:
|
262
|
+
# sdb = RightAWS:::SdbInterface.new
|
263
|
+
# sdb.domain_metadata('toys') # => {:attribute_values_size_bytes=>"2754",
|
264
|
+
# :item_count=>"25",
|
265
|
+
# :item_names_size_bytes=>"900",
|
266
|
+
# :timestamp=>"1291890409",
|
267
|
+
# :attribute_name_count=>"7",
|
268
|
+
# :box_usage=>"0.0000071759",
|
269
|
+
# :attribute_names_size_bytes=>"48",
|
270
|
+
# :attribute_value_count=>"154",
|
271
|
+
# :request_id=>"79bbfe8f-f0c9-59a2-0963-16d5fc6c3c52"}
|
272
|
+
# see http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/index.html?SDB_API_DomainMetadata.html
|
273
|
+
def domain_metadata(domain)
|
274
|
+
link = generate_request("DomainMetadata","DomainName"=>domain)
|
275
|
+
request_info(link,QSdbGenericParser.new)
|
276
|
+
end
|
277
|
+
|
248
278
|
# Delete SDB domain at Amazon.
|
249
279
|
#
|
250
280
|
# Returns a hash: { :box_usage, :request_id } on success or an exception on error.
|
@@ -315,6 +345,37 @@ module RightAws
|
|
315
345
|
rescue Exception
|
316
346
|
on_exception
|
317
347
|
end
|
348
|
+
|
349
|
+
# Add/Replace attributes for multiple items at a time.
|
350
|
+
#
|
351
|
+
# Params:
|
352
|
+
# domain_name = DomainName
|
353
|
+
# items = {
|
354
|
+
# 'Item1' => {
|
355
|
+
# 'nameA' => [valueA1, valueA2,..., valueAN],
|
356
|
+
# ...
|
357
|
+
# 'nameB' => [valueB1, valueB2,..., valueBN]
|
358
|
+
# },
|
359
|
+
# 'Item2' => {
|
360
|
+
# 'nameC' => [valueC1, valueC2,..., valueCN],
|
361
|
+
# ...
|
362
|
+
# 'nameD' => [valueD1, valueD2,..., valueDN]
|
363
|
+
# }
|
364
|
+
# }
|
365
|
+
# replace = :replace | any other value to skip replacement
|
366
|
+
#
|
367
|
+
# Usage of batch_put_attributes is similar to put_attributes except that
|
368
|
+
# instead of supplying an item_name and a hash of attributes, you supply a
|
369
|
+
# hash of item names to attributes.
|
370
|
+
#
|
371
|
+
# See: http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/index.html?SDB_API_BatchPutAttributes.html
|
372
|
+
def batch_put_attributes(domain_name, items, replace = false)
|
373
|
+
params = { 'DomainName' => domain_name }.merge(pack_attributes(items, replace, true))
|
374
|
+
link = generate_request("BatchPutAttributes", params)
|
375
|
+
request_info( link, QSdbSimpleParser.new)
|
376
|
+
rescue Exception
|
377
|
+
on_exception
|
378
|
+
end
|
318
379
|
|
319
380
|
# Retrieve SDB item's attribute(s).
|
320
381
|
#
|
@@ -338,12 +399,21 @@ module RightAws
|
|
338
399
|
# :box_usage => "0.0000093222",
|
339
400
|
# :request_id => "81273d21-001-1111-b3f9-512d91d29ac8" }
|
340
401
|
#
|
402
|
+
# # request all attributes using a consistent read
|
403
|
+
# # see: http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/index.html?ConsistencySummary.html
|
404
|
+
# sdb.get_attributes('family', 'toys', nil, true) # => { :attributes => {"cat" => ["clew", "Jons_socks", "mouse"] },
|
405
|
+
# "Silvia" => ["beetle", "rolling_pin", "kids"],
|
406
|
+
# "Jon" => ["vacuum_cleaner", "hammer", "spade"]},
|
407
|
+
# :box_usage => "0.0000093222",
|
408
|
+
# :request_id => "81273d21-000-1111-b3f9-512d91d29ac8" }
|
409
|
+
#
|
341
410
|
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_GetAttributes.html
|
342
411
|
#
|
343
|
-
def get_attributes(domain_name, item_name, attribute_name=nil)
|
344
|
-
link = generate_request("GetAttributes", 'DomainName'
|
345
|
-
'ItemName'
|
346
|
-
'AttributeName'
|
412
|
+
def get_attributes(domain_name, item_name, attribute_name=nil, consistent_read=nil)
|
413
|
+
link = generate_request("GetAttributes", 'DomainName' => domain_name,
|
414
|
+
'ItemName' => item_name,
|
415
|
+
'AttributeName' => attribute_name,
|
416
|
+
'ConsistentRead' => consistent_read )
|
347
417
|
res = request_info(link, QSdbGetAttributesParser.new)
|
348
418
|
res[:attributes].each_value do |values|
|
349
419
|
values.collect! { |e| sdb_to_ruby(e) }
|
@@ -440,9 +510,152 @@ module RightAws
|
|
440
510
|
on_exception
|
441
511
|
end
|
442
512
|
|
513
|
+
# Perform a query and fetch specified attributes.
|
514
|
+
# If attributes are not specified then fetches the whole list of attributes.
|
515
|
+
#
|
516
|
+
#
|
517
|
+
# Returns a hash:
|
518
|
+
# { :box_usage => string,
|
519
|
+
# :request_id => string,
|
520
|
+
# :next_token => string,
|
521
|
+
# :items => [ { ItemName1 => { attribute1 => value1, ... attributeM => valueM } },
|
522
|
+
# { ItemName2 => {...}}, ... ]
|
523
|
+
#
|
524
|
+
# Example:
|
525
|
+
#
|
526
|
+
# sdb.query_with_attributes(domain, ['hobby', 'country'], "['gender'='female'] intersection ['name' starts-with ''] sort 'name'") #=>
|
527
|
+
# { :request_id => "06057228-70d0-4487-89fb-fd9c028580d3",
|
528
|
+
# :items =>
|
529
|
+
# [ { "035f1ba8-dbd8-11dd-80bd-001bfc466dd7"=>
|
530
|
+
# { "hobby" => ["cooking", "flowers", "cats"],
|
531
|
+
# "country" => ["Russia"]}},
|
532
|
+
# { "0327614a-dbd8-11dd-80bd-001bfc466dd7"=>
|
533
|
+
# { "hobby" => ["patchwork", "bundle jumping"],
|
534
|
+
# "country" => ["USA"]}}, ... ],
|
535
|
+
# :box_usage=>"0.0000504786"}
|
536
|
+
#
|
537
|
+
# sdb.query_with_attributes(domain, [], "['gender'='female'] intersection ['name' starts-with ''] sort 'name'") #=>
|
538
|
+
# { :request_id => "75bb19db-a529-4f69-b86f-5e3800f79a45",
|
539
|
+
# :items =>
|
540
|
+
# [ { "035f1ba8-dbd8-11dd-80bd-001bfc466dd7"=>
|
541
|
+
# { "hobby" => ["cooking", "flowers", "cats"],
|
542
|
+
# "name" => ["Mary"],
|
543
|
+
# "country" => ["Russia"],
|
544
|
+
# "gender" => ["female"],
|
545
|
+
# "id" => ["035f1ba8-dbd8-11dd-80bd-001bfc466dd7"]}},
|
546
|
+
# { "0327614a-dbd8-11dd-80bd-001bfc466dd7"=>
|
547
|
+
# { "hobby" => ["patchwork", "bundle jumping"],
|
548
|
+
# "name" => ["Mary"],
|
549
|
+
# "country" => ["USA"],
|
550
|
+
# "gender" => ["female"],
|
551
|
+
# "id" => ["0327614a-dbd8-11dd-80bd-001bfc466dd7"]}}, ... ],
|
552
|
+
# :box_usage=>"0.0000506668"}
|
553
|
+
#
|
554
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?SDB_API_QueryWithAttributes.html
|
555
|
+
#
|
556
|
+
def query_with_attributes(domain_name, attributes=[], query_expression = nil, max_number_of_items = nil, next_token = nil)
|
557
|
+
attributes = Array(attributes)
|
558
|
+
query_expression = query_expression_from_array(query_expression) if query_expression.is_a?(Array)
|
559
|
+
@last_query_expression = query_expression
|
560
|
+
#
|
561
|
+
request_params = { 'DomainName' => domain_name,
|
562
|
+
'QueryExpression' => query_expression,
|
563
|
+
'MaxNumberOfItems' => max_number_of_items,
|
564
|
+
'NextToken' => next_token }
|
565
|
+
attributes.each_with_index do |attribute, idx|
|
566
|
+
request_params["AttributeName.#{idx+1}"] = attribute
|
567
|
+
end
|
568
|
+
link = generate_request("QueryWithAttributes", request_params)
|
569
|
+
result = select_response_to_ruby(request_info( link, QSdbQueryWithAttributesParser.new ))
|
570
|
+
# return result if no block given
|
571
|
+
return result unless block_given?
|
572
|
+
# loop if block if given
|
573
|
+
begin
|
574
|
+
# the block must return true if it wanna continue
|
575
|
+
break unless yield(result) && result[:next_token]
|
576
|
+
# make new request
|
577
|
+
request_params['NextToken'] = result[:next_token]
|
578
|
+
link = generate_request("QueryWithAttributes", request_params)
|
579
|
+
result = select_response_to_ruby(request_info( link, QSdbQueryWithAttributesParser.new ))
|
580
|
+
end while true
|
581
|
+
rescue Exception
|
582
|
+
on_exception
|
583
|
+
end
|
584
|
+
|
585
|
+
# Perform SQL-like select and fetch attributes.
|
586
|
+
# Attribute values must be quoted with a single or double quote. If a quote appears within the attribute value, it must be escaped with the same quote symbol as shown in the following example.
|
587
|
+
# (Use array to pass select_expression params to avoid manual escaping).
|
588
|
+
#
|
589
|
+
# sdb.select(["select * from my_domain where gender=?", 'female']) #=>
|
590
|
+
# {:request_id =>"8241b843-0fb9-4d66-9100-effae12249ec",
|
591
|
+
# :items =>
|
592
|
+
# [ { "035f1ba8-dbd8-11dd-80bd-001bfc466dd7"=>
|
593
|
+
# {"hobby" => ["cooking", "flowers", "cats"],
|
594
|
+
# "name" => ["Mary"],
|
595
|
+
# "country" => ["Russia"],
|
596
|
+
# "gender" => ["female"],
|
597
|
+
# "id" => ["035f1ba8-dbd8-11dd-80bd-001bfc466dd7"]}},
|
598
|
+
# { "0327614a-dbd8-11dd-80bd-001bfc466dd7"=>
|
599
|
+
# {"hobby" => ["patchwork", "bundle jumping"],
|
600
|
+
# "name" => ["Mary"],
|
601
|
+
# "country" => ["USA"],
|
602
|
+
# "gender" => ["female"],
|
603
|
+
# "id" => ["0327614a-dbd8-11dd-80bd-001bfc466dd7"]}}, ... ]
|
604
|
+
# :box_usage =>"0.0000506197"}
|
605
|
+
#
|
606
|
+
# sdb.select('select country, name from my_domain') #=>
|
607
|
+
# {:request_id=>"b1600198-c317-413f-a8dc-4e7f864a940a",
|
608
|
+
# :items=>
|
609
|
+
# [ { "035f1ba8-dbd8-11dd-80bd-001bfc466dd7"=> {"name"=>["Mary"], "country"=>["Russia"]} },
|
610
|
+
# { "376d2e00-75b0-11dd-9557-001bfc466dd7"=> {"name"=>["Putin"], "country"=>["Russia"]} },
|
611
|
+
# { "0327614a-dbd8-11dd-80bd-001bfc466dd7"=> {"name"=>["Mary"], "country"=>["USA"]} },
|
612
|
+
# { "372ebbd4-75b0-11dd-9557-001bfc466dd7"=> {"name"=>["Bush"], "country"=>["USA"]} },
|
613
|
+
# { "37a4e552-75b0-11dd-9557-001bfc466dd7"=> {"name"=>["Medvedev"], "country"=>["Russia"]} },
|
614
|
+
# { "38278dfe-75b0-11dd-9557-001bfc466dd7"=> {"name"=>["Mary"], "country"=>["Russia"]} },
|
615
|
+
# { "37df6c36-75b0-11dd-9557-001bfc466dd7"=> {"name"=>["Mary"], "country"=>["USA"]} } ],
|
616
|
+
# :box_usage=>"0.0000777663"}
|
617
|
+
#
|
618
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?SDB_API_Select.html
|
619
|
+
# http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?UsingSelect.html
|
620
|
+
# http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?SDBLimits.html
|
621
|
+
#
|
622
|
+
def select(select_expression, next_token = nil)
|
623
|
+
select_expression = query_expression_from_array(select_expression) if select_expression.is_a?(Array)
|
624
|
+
@last_query_expression = select_expression
|
625
|
+
#
|
626
|
+
request_params = { 'SelectExpression' => select_expression,
|
627
|
+
'NextToken' => next_token }
|
628
|
+
link = generate_request("Select", request_params)
|
629
|
+
result = select_response_to_ruby(request_info( link, QSdbSelectParser.new ))
|
630
|
+
return result unless block_given?
|
631
|
+
# loop if block if given
|
632
|
+
begin
|
633
|
+
# the block must return true if it wanna continue
|
634
|
+
break unless yield(result) && result[:next_token]
|
635
|
+
# make new request
|
636
|
+
request_params['NextToken'] = result[:next_token]
|
637
|
+
link = generate_request("Select", request_params)
|
638
|
+
result = select_response_to_ruby(request_info( link, QSdbSelectParser.new ))
|
639
|
+
end while true
|
640
|
+
rescue Exception
|
641
|
+
on_exception
|
642
|
+
end
|
643
|
+
|
443
644
|
#-----------------------------------------------------------------
|
444
645
|
# PARSERS:
|
445
646
|
#-----------------------------------------------------------------
|
647
|
+
class QSdbGenericParser < RightAWSParser #:nodoc:
|
648
|
+
def reset
|
649
|
+
@result = {}
|
650
|
+
end
|
651
|
+
def tagend(name)
|
652
|
+
case full_tag_name
|
653
|
+
when %r{/(DomainMetadataResult|ResponseMetadata)/}
|
654
|
+
@result[name.right_underscore.to_sym] = @text
|
655
|
+
end
|
656
|
+
end
|
657
|
+
end
|
658
|
+
|
446
659
|
class QSdbListDomainParser < RightAWSParser #:nodoc:
|
447
660
|
def reset
|
448
661
|
@result = { :domains => [] }
|
@@ -498,6 +711,52 @@ module RightAws
|
|
498
711
|
end
|
499
712
|
end
|
500
713
|
|
714
|
+
class QSdbQueryWithAttributesParser < RightAWSParser #:nodoc:
|
715
|
+
def reset
|
716
|
+
@result = { :items => [] }
|
717
|
+
end
|
718
|
+
def tagend(name)
|
719
|
+
case name
|
720
|
+
when 'Name'
|
721
|
+
case @xmlpath
|
722
|
+
when 'QueryWithAttributesResponse/QueryWithAttributesResult/Item'
|
723
|
+
@item = @text
|
724
|
+
@result[:items] << { @item => {} }
|
725
|
+
when 'QueryWithAttributesResponse/QueryWithAttributesResult/Item/Attribute'
|
726
|
+
@attribute = @text
|
727
|
+
@result[:items].last[@item][@attribute] ||= []
|
728
|
+
end
|
729
|
+
when 'RequestId' then @result[:request_id] = @text
|
730
|
+
when 'BoxUsage' then @result[:box_usage] = @text
|
731
|
+
when 'NextToken' then @result[:next_token] = @text
|
732
|
+
when 'Value' then @result[:items].last[@item][@attribute] << @text
|
733
|
+
end
|
734
|
+
end
|
735
|
+
end
|
736
|
+
|
737
|
+
class QSdbSelectParser < RightAWSParser #:nodoc:
|
738
|
+
def reset
|
739
|
+
@result = { :items => [] }
|
740
|
+
end
|
741
|
+
def tagend(name)
|
742
|
+
case name
|
743
|
+
when 'Name'
|
744
|
+
case @xmlpath
|
745
|
+
when 'SelectResponse/SelectResult/Item'
|
746
|
+
@item = @text
|
747
|
+
@result[:items] << { @item => {} }
|
748
|
+
when 'SelectResponse/SelectResult/Item/Attribute'
|
749
|
+
@attribute = @text
|
750
|
+
@result[:items].last[@item][@attribute] ||= []
|
751
|
+
end
|
752
|
+
when 'RequestId' then @result[:request_id] = @text
|
753
|
+
when 'BoxUsage' then @result[:box_usage] = @text
|
754
|
+
when 'NextToken' then @result[:next_token] = @text
|
755
|
+
when 'Value' then @result[:items].last[@item][@attribute] << @text
|
756
|
+
end
|
757
|
+
end
|
758
|
+
end
|
759
|
+
|
501
760
|
end
|
502
761
|
|
503
762
|
end
|