aws 2.3.5 → 2.3.6
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/README.markdown +2 -8
- data/lib/awsbase/right_awsbase.rb +14 -2
- data/lib/s3/right_s3.rb +4 -0
- data/lib/s3/right_s3_interface.rb +4 -0
- data/lib/sdb/right_sdb_interface.rb +740 -706
- data/test/acf/{test_right_acf.rb → test_acf.rb} +0 -0
- data/test/ec2/{test_right_ec2.rb → test_ec2.rb} +0 -0
- data/test/rds/test_rds.rb +13 -2
- data/test/sqs/{test_right_sqs.rb → test_sqs.rb} +3 -9
- data/test/ts_right_aws.rb +3 -3
- metadata +6 -6
data/README.markdown
CHANGED
@@ -1,14 +1,8 @@
|
|
1
1
|
# Appoxy AWS Library
|
2
2
|
|
3
|
-
|
3
|
+
A Ruby gem for all Amazon Web Services.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
1. RightScale wasn't fixing critical bugs that were reported in their forums.
|
8
|
-
1. It didn't work with Ruby 1.9 - this version does
|
9
|
-
1. RightScale doesn't have the source hosted for the community
|
10
|
-
1. We needed fixes and changes for [http://code.google.com/p/simple-record/ SimpleRecord] and didn't want to wait for RightScale to do it.
|
11
|
-
1. We needed support for new AWS services.
|
5
|
+
Brought to you by: [](http://www.appoxy.com)
|
12
6
|
|
13
7
|
## Discussion Group
|
14
8
|
|
@@ -395,7 +395,7 @@ module Aws
|
|
395
395
|
end
|
396
396
|
request = Net::HTTP::Post.new(service)
|
397
397
|
request.body = service_params
|
398
|
-
request['Content-Type'] = 'application/x-www-form-urlencoded'
|
398
|
+
request['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'
|
399
399
|
else
|
400
400
|
request = Net::HTTP::Get.new("#{service}?#{service_params}")
|
401
401
|
end
|
@@ -430,6 +430,17 @@ module Aws
|
|
430
430
|
|
431
431
|
end
|
432
432
|
|
433
|
+
def close_conn(conn_name)
|
434
|
+
conn_mode = @params[:connection_mode]
|
435
|
+
if conn_mode == :per_thread || conn_mode == :single
|
436
|
+
thread = conn_mode == :per_thread ? Thread.current : Thread.main
|
437
|
+
if !thread[conn_name].nil?
|
438
|
+
thread[conn_name].finish
|
439
|
+
thread[conn_name] = nil
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
433
444
|
#
|
434
445
|
# def request_info2(request, parser, lib_params, connection_name, logger, bench)
|
435
446
|
# t = get_conn(connection_name, lib_params, logger)
|
@@ -476,7 +487,7 @@ module Aws
|
|
476
487
|
@last_response = nil
|
477
488
|
|
478
489
|
response = @connection.request(request)
|
479
|
-
#
|
490
|
+
# puts "response=" + response.body
|
480
491
|
# benchblock.service.add!{ response = @connection.request(request) }
|
481
492
|
# check response for errors...
|
482
493
|
@last_response = response
|
@@ -513,6 +524,7 @@ module Aws
|
|
513
524
|
if level_hash.is_a? Hash # When there's only one
|
514
525
|
ret << level_hash
|
515
526
|
else # should be array
|
527
|
+
# puts 'level_hash=' + level_hash.inspect
|
516
528
|
level_hash.each do |x|
|
517
529
|
ret << x
|
518
530
|
end
|
data/lib/s3/right_s3.rb
CHANGED
@@ -64,6 +64,10 @@ module Aws
|
|
64
64
|
def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
|
65
65
|
@interface = S3Interface.new(aws_access_key_id, aws_secret_access_key, params)
|
66
66
|
end
|
67
|
+
|
68
|
+
def close_connection
|
69
|
+
@interface.close_connection
|
70
|
+
end
|
67
71
|
|
68
72
|
# Retrieve a list of buckets.
|
69
73
|
# Returns an array of Aws::S3::Bucket instances.
|
@@ -25,754 +25,788 @@ require "aws"
|
|
25
25
|
|
26
26
|
module Aws
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
include AwsBaseInterface
|
31
|
-
|
32
|
-
DEFAULT_HOST = 'sdb.amazonaws.com'
|
33
|
-
DEFAULT_PORT = 443
|
34
|
-
DEFAULT_PROTOCOL = 'https'
|
35
|
-
DEFAULT_SERVICE = '/'
|
36
|
-
API_VERSION = '2009-04-15'
|
37
|
-
DEFAULT_NIL_REPRESENTATION = 'nil'
|
38
|
-
|
39
|
-
@@bench = AwsBenchmarkingBlock.new
|
40
|
-
def self.bench_xml; @@bench.xml; end
|
41
|
-
def self.bench_sdb; @@bench.service; end
|
42
|
-
|
43
|
-
attr_reader :last_query_expression
|
44
|
-
|
45
|
-
# Creates new RightSdb instance.
|
46
|
-
#
|
47
|
-
# Params:
|
48
|
-
# { :server => 'sdb.amazonaws.com' # Amazon service host: 'sdb.amazonaws.com'(default)
|
49
|
-
# :port => 443 # Amazon service port: 80(default) or 443
|
50
|
-
# :protocol => 'https' # Amazon service protocol: 'http'(default) or 'https'
|
51
|
-
# :signature_version => '2' # The signature version : '0', '1' or '2' (default)
|
52
|
-
# DEPRECATED :multi_thread => true|false # Multi-threaded (connection per each thread): true or false(default)
|
53
|
-
# :connection_mode => :default # options are :default (will use best known option, may change in the future)
|
54
|
-
# :per_request (opens and closes a connection on every request to SDB)
|
55
|
-
# :single - one connection shared across app (same as old multi_thread=>false)
|
56
|
-
# :per_thread - one connection per ruby thread (same as old multi_thread=>true)
|
57
|
-
# :pool (uses a connection pool with a maximum number of connections - NOT IMPLEMENTED YET)
|
58
|
-
# :logger => Logger Object # Logger instance: logs to STDOUT if omitted
|
59
|
-
# :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')
|
60
|
-
# :service => '/' # Set this to /mdb/request.mgwsi for usage with M/DB #
|
61
|
-
#
|
62
|
-
# Example:
|
63
|
-
#
|
64
|
-
# sdb = Aws::SdbInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX', {:connection_mode => :per_request, :logger => Logger.new('/tmp/x.log')}) #=> #<RightSdb:0xa6b8c27c>
|
65
|
-
#
|
66
|
-
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/
|
67
|
-
#
|
68
|
-
def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
|
69
|
-
@nil_rep = params[:nil_representation] ? params[:nil_representation] : DEFAULT_NIL_REPRESENTATION
|
70
|
-
params.delete(:nil_representation)
|
71
|
-
init({ :name => 'SDB',
|
72
|
-
:default_host => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).host : DEFAULT_HOST,
|
73
|
-
:default_port => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).port : DEFAULT_PORT,
|
74
|
-
:default_protocol => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).scheme : DEFAULT_PROTOCOL,
|
75
|
-
:default_service => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).path : DEFAULT_SERVICE },
|
76
|
-
# :service_endpoint => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).path : DEFAULT_ENDPOINT },
|
77
|
-
aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'],
|
78
|
-
aws_secret_access_key || ENV['AWS_SECRET_ACCESS_KEY'],
|
79
|
-
params)
|
80
|
-
end
|
28
|
+
class SdbInterface < AwsBase
|
81
29
|
|
82
|
-
|
83
|
-
# Requests
|
84
|
-
#-----------------------------------------------------------------
|
85
|
-
def generate_request(action, params={}) #:nodoc:
|
86
|
-
generate_request2(@aws_access_key_id, @aws_secret_access_key, action, API_VERSION, @params, params)
|
87
|
-
end
|
30
|
+
include AwsBaseInterface
|
88
31
|
|
32
|
+
DEFAULT_HOST = 'sdb.amazonaws.com'
|
33
|
+
DEFAULT_PORT = 443
|
34
|
+
DEFAULT_PROTOCOL = 'https'
|
35
|
+
DEFAULT_SERVICE = '/'
|
36
|
+
API_VERSION = '2009-04-15'
|
37
|
+
DEFAULT_NIL_REPRESENTATION = 'nil'
|
89
38
|
|
90
|
-
|
91
|
-
# Raises AwsError if any banana happened
|
92
|
-
def request_info(request, parser) #:nodoc:
|
93
|
-
# request_info2(request, parser, :sdb_connection)
|
94
|
-
request_info2(request, parser, @params, :s3_connection, @logger, @@bench)
|
39
|
+
@@bench = AwsBenchmarkingBlock.new
|
95
40
|
|
96
|
-
|
41
|
+
def self.bench_xml;
|
42
|
+
@@bench.xml;
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.bench_sdb;
|
46
|
+
@@bench.service;
|
47
|
+
end
|
97
48
|
|
49
|
+
attr_reader :last_query_expression
|
50
|
+
|
51
|
+
# Creates new RightSdb instance.
|
52
|
+
#
|
53
|
+
# Params:
|
54
|
+
# { :server => 'sdb.amazonaws.com' # Amazon service host: 'sdb.amazonaws.com'(default)
|
55
|
+
# :port => 443 # Amazon service port: 80(default) or 443
|
56
|
+
# :protocol => 'https' # Amazon service protocol: 'http'(default) or 'https'
|
57
|
+
# :signature_version => '2' # The signature version : '0', '1' or '2' (default)
|
58
|
+
# DEPRECATED :multi_thread => true|false # Multi-threaded (connection per each thread): true or false(default)
|
59
|
+
# :connection_mode => :default # options are :default (will use best known option, may change in the future)
|
60
|
+
# :per_request (opens and closes a connection on every request to SDB)
|
61
|
+
# :single - one connection shared across app (same as old multi_thread=>false)
|
62
|
+
# :per_thread - one connection per ruby thread (same as old multi_thread=>true)
|
63
|
+
# :pool (uses a connection pool with a maximum number of connections - NOT IMPLEMENTED YET)
|
64
|
+
# :logger => Logger Object # Logger instance: logs to STDOUT if omitted
|
65
|
+
# :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')
|
66
|
+
# :service => '/' # Set this to /mdb/request.mgwsi for usage with M/DB #
|
67
|
+
#
|
68
|
+
# Example:
|
69
|
+
#
|
70
|
+
# sdb = Aws::SdbInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX', {:connection_mode => :per_request, :logger => Logger.new('/tmp/x.log')}) #=> #<RightSdb:0xa6b8c27c>
|
71
|
+
#
|
72
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/
|
73
|
+
#
|
74
|
+
def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
|
75
|
+
@nil_rep = params[:nil_representation] ? params[:nil_representation] : DEFAULT_NIL_REPRESENTATION
|
76
|
+
params.delete(:nil_representation)
|
77
|
+
init({ :name => 'SDB',
|
78
|
+
:default_host => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).host : DEFAULT_HOST,
|
79
|
+
:default_port => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).port : DEFAULT_PORT,
|
80
|
+
:default_protocol => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).scheme : DEFAULT_PROTOCOL,
|
81
|
+
:default_service => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).path : DEFAULT_SERVICE },
|
82
|
+
# :service_endpoint => ENV['SDB_URL'] ? URI.parse(ENV['SDB_URL']).path : DEFAULT_ENDPOINT },
|
83
|
+
aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'],
|
84
|
+
aws_secret_access_key || ENV['AWS_SECRET_ACCESS_KEY'],
|
85
|
+
params)
|
86
|
+
end
|
98
87
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
thread[:sdb_connection].finish
|
105
|
-
thread[:sdb_connection] = nil
|
88
|
+
#-----------------------------------------------------------------
|
89
|
+
# Requests
|
90
|
+
#-----------------------------------------------------------------
|
91
|
+
def generate_request(action, params={}) #:nodoc:
|
92
|
+
generate_request2(@aws_access_key_id, @aws_secret_access_key, action, API_VERSION, @params, params)
|
106
93
|
end
|
107
|
-
end
|
108
|
-
end
|
109
94
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
95
|
+
|
96
|
+
# Sends request to Amazon and parses the response
|
97
|
+
# Raises AwsError if any banana happened
|
98
|
+
def request_info(request, parser) #:nodoc:
|
99
|
+
# request_info2(request, parser, :sdb_connection)
|
100
|
+
request_info2(request, parser, @params, :s3_connection, @logger, @@bench)
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
def close_connection
|
105
|
+
close_conn(:sdb_connection)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Prepare attributes for putting.
|
109
|
+
# (used by put_attributes)
|
110
|
+
def pack_attributes(attributes, replace = false, key_prefix = "") #:nodoc:
|
111
|
+
result = {}
|
112
|
+
if attributes
|
113
|
+
idx = 0
|
114
|
+
skip_values = attributes.is_a?(Array)
|
115
|
+
attributes.each do |attribute, values|
|
116
|
+
# set replacement attribute
|
117
|
+
result["#{key_prefix}Attribute.#{idx}.Replace"] = 'true' if replace
|
118
|
+
# pack Name/Value
|
119
|
+
unless values.nil?
|
120
|
+
Array(values).each do |value|
|
121
|
+
result["#{key_prefix}Attribute.#{idx}.Name"] = attribute
|
122
|
+
result["#{key_prefix}Attribute.#{idx}.Value"] = ruby_to_sdb(value) unless skip_values
|
123
|
+
idx += 1
|
124
|
+
end
|
125
|
+
else
|
126
|
+
result["#{key_prefix}Attribute.#{idx}.Name"] = attribute
|
127
|
+
result["#{key_prefix}Attribute.#{idx}.Value"] = ruby_to_sdb(nil) unless skip_values
|
128
|
+
idx += 1
|
129
|
+
end
|
130
|
+
end
|
126
131
|
end
|
127
|
-
|
128
|
-
|
129
|
-
result["#{key_prefix}Attribute.#{idx}.Value"] = ruby_to_sdb(nil) unless skip_values
|
130
|
-
idx += 1
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
result
|
135
|
-
end
|
132
|
+
result
|
133
|
+
end
|
136
134
|
|
137
135
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
136
|
+
# Use this helper to manually escape the fields in the query expressions.
|
137
|
+
# To escape the single quotes and backslashes and to wrap the string into the single quotes.
|
138
|
+
#
|
139
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API.html
|
140
|
+
#
|
141
|
+
def escape(value)
|
142
|
+
%Q{'#{value.to_s.gsub(/(['\\])/){ "\\#{$1}" }}'} if value
|
143
|
+
end
|
146
144
|
|
147
|
-
|
148
|
-
|
149
|
-
|
145
|
+
# Convert a Ruby language value to a SDB value by replacing Ruby nil with the user's chosen string representation of nil.
|
146
|
+
# Non-nil values are unaffected by this filter.
|
147
|
+
def ruby_to_sdb(value)
|
150
148
|
# puts "value #{value} is frozen? #{value.frozen?}"
|
151
149
|
# value.nil? ? @nil_rep : ((value.frozen? || !value.is_a?(String)) ? value : value.force_encoding("UTF-8"))
|
152
|
-
|
153
|
-
|
150
|
+
value.nil? ? @nil_rep : value
|
151
|
+
end
|
154
152
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
153
|
+
# Convert a SDB value to a Ruby language value by replacing the user's chosen string representation of nil with Ruby nil.
|
154
|
+
# Values are unaffected by this filter unless they match the nil representation exactly.
|
155
|
+
def sdb_to_ruby(value)
|
156
|
+
value.eql?(@nil_rep) ? nil : value
|
157
|
+
end
|
160
158
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
159
|
+
# 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.
|
160
|
+
# (This method affects on a passed response value)
|
161
|
+
def select_response_to_ruby(response) #:nodoc:
|
162
|
+
response[:items].each_with_index do |item, idx|
|
163
|
+
item.each do |key, attributes|
|
164
|
+
attributes.each do |name, values|
|
165
|
+
values.collect! { |value| sdb_to_ruby(value) }
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
response
|
170
|
+
end
|
173
171
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
172
|
+
# Create query expression from an array.
|
173
|
+
# (similar to ActiveRecord::Base#find using :conditions => ['query', param1, .., paramN])
|
174
|
+
#
|
175
|
+
def query_expression_from_array(params) #:nodoc:
|
176
|
+
return '' if params.blank?
|
177
|
+
query = params[0].to_s
|
178
|
+
i = 1
|
179
|
+
query.gsub(/(\\)?(\?)/) do
|
180
|
+
if $1 # if escaped '\?' is found - replace it by '?' without backslash
|
181
|
+
"?"
|
182
|
+
else # well, if no backslash precedes '?' then replace it by next param from the list
|
183
|
+
ret = escape(params[i])
|
184
|
+
i+=1
|
185
|
+
ret
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
191
189
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
190
|
+
def query_expression_from_hash(hash)
|
191
|
+
return '' if hash.blank?
|
192
|
+
expression = []
|
193
|
+
hash.each do |key, value|
|
194
|
+
expression << "#{key}=#{escape(value)}"
|
195
|
+
end
|
196
|
+
expression.join(' AND ')
|
197
|
+
end
|
200
198
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
199
|
+
# Retrieve a list of SDB domains from Amazon.
|
200
|
+
#
|
201
|
+
# Returns a hash:
|
202
|
+
# { :domains => [domain1, ..., domainN],
|
203
|
+
# :next_token => string || nil,
|
204
|
+
# :box_usage => string,
|
205
|
+
# :request_id => string }
|
206
|
+
#
|
207
|
+
# Example:
|
208
|
+
#
|
209
|
+
# sdb = Aws::SdbInterface.new
|
210
|
+
# sdb.list_domains #=> { :box_usage => "0.0000071759",
|
211
|
+
# :request_id => "976709f9-0111-2345-92cb-9ce90acd0982",
|
212
|
+
# :domains => ["toys", "dolls"]}
|
213
|
+
#
|
214
|
+
# If a block is given, this method yields to it. If the block returns true, list_domains will continue looping the request. If the block returns false,
|
215
|
+
# list_domains will end.
|
216
|
+
#
|
217
|
+
# sdb.list_domains(10) do |result| # list by 10 domains per iteration
|
218
|
+
# puts result.inspect
|
219
|
+
# true
|
220
|
+
# end
|
221
|
+
#
|
222
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_ListDomains.html
|
223
|
+
#
|
224
|
+
def list_domains(max_number_of_domains = nil, next_token = nil )
|
225
|
+
request_params = { 'MaxNumberOfDomains' => max_number_of_domains,
|
226
|
+
'NextToken' => next_token }
|
227
|
+
link = generate_request("ListDomains", request_params)
|
228
|
+
result = request_info(link, QSdbListDomainParser.new)
|
229
|
+
# return result if no block given
|
230
|
+
return result unless block_given?
|
231
|
+
# loop if block if given
|
232
|
+
begin
|
233
|
+
# the block must return true if it wanna continue
|
234
|
+
break unless yield(result) && result[:next_token]
|
235
|
+
# make new request
|
236
|
+
request_params['NextToken'] = result[:next_token]
|
237
|
+
link = generate_request("ListDomains", request_params)
|
238
|
+
result = request_info(link, QSdbListDomainParser.new)
|
239
|
+
end while true
|
240
|
+
rescue Exception
|
241
|
+
on_exception
|
242
|
+
end
|
245
243
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
244
|
+
# Retrieve a list of SDB domains from Amazon.
|
245
|
+
#
|
246
|
+
# Returns a hash:
|
247
|
+
# { :domains => [domain1, ..., domainN],
|
248
|
+
# :next_token => string || nil,
|
249
|
+
# :box_usage => string,
|
250
|
+
# :request_id => string }
|
251
|
+
#
|
252
|
+
# Example:
|
253
|
+
#
|
254
|
+
# sdb = Aws::SdbInterface.new
|
255
|
+
# sdb.list_domains #=> { :box_usage => "0.0000071759",
|
256
|
+
# :request_id => "976709f9-0111-2345-92cb-9ce90acd0982",
|
257
|
+
# :domains => ["toys", "dolls"]}
|
258
|
+
#
|
259
|
+
# If a block is given, this method yields to it. If the block returns true, list_domains will continue looping the request. If the block returns false,
|
260
|
+
# list_domains will end.
|
261
|
+
#
|
262
|
+
# sdb.list_domains(10) do |result| # list by 10 domains per iteration
|
263
|
+
# puts result.inspect
|
264
|
+
# true
|
265
|
+
# end
|
266
|
+
#
|
267
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_ListDomains.html
|
268
|
+
#
|
269
|
+
def domain_metadata(domain_name)
|
270
|
+
link = generate_request("DomainMetadata", 'DomainName' => domain_name)
|
271
|
+
result = request_info(link, QSdbDomainMetadataParser.new)
|
272
|
+
return result
|
273
|
+
rescue Exception
|
274
|
+
on_exception
|
275
|
+
end
|
278
276
|
|
279
277
|
|
278
|
+
# Create new SDB domain at Amazon.
|
279
|
+
#
|
280
|
+
# Returns a hash: { :box_usage, :request_id } on success or an exception on error.
|
281
|
+
# (Amazon raises no errors if the domain already exists).
|
282
|
+
#
|
283
|
+
# Example:
|
284
|
+
#
|
285
|
+
# sdb = Aws::SdbInterface.new
|
286
|
+
# sdb.create_domain('toys') # => { :box_usage => "0.0000071759",
|
287
|
+
# :request_id => "976709f9-0111-2345-92cb-9ce90acd0982" }
|
288
|
+
#
|
289
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_CreateDomain.html
|
290
|
+
def create_domain(domain_name)
|
291
|
+
link = generate_request("CreateDomain",
|
292
|
+
'DomainName' => domain_name)
|
293
|
+
request_info(link, QSdbSimpleParser.new)
|
294
|
+
rescue Exception
|
295
|
+
on_exception
|
296
|
+
end
|
280
297
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
298
|
+
# Delete SDB domain at Amazon.
|
299
|
+
#
|
300
|
+
# Returns a hash: { :box_usage, :request_id } on success or an exception on error.
|
301
|
+
# (Amazon raises no errors if the domain does not exist).
|
302
|
+
#
|
303
|
+
# Example:
|
304
|
+
#
|
305
|
+
# sdb = Aws::SdbInterface.new
|
306
|
+
# sdb.delete_domain('toys') # => { :box_usage => "0.0000071759",
|
307
|
+
# :request_id => "976709f9-0111-2345-92cb-9ce90acd0982" }
|
308
|
+
#
|
309
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_DeleteDomain.html
|
310
|
+
#
|
311
|
+
def delete_domain(domain_name)
|
312
|
+
link = generate_request("DeleteDomain",
|
313
|
+
'DomainName' => domain_name)
|
314
|
+
request_info(link, QSdbSimpleParser.new)
|
315
|
+
rescue Exception
|
316
|
+
on_exception
|
317
|
+
end
|
300
318
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
319
|
+
# Add/Replace item attributes.
|
320
|
+
#
|
321
|
+
# Params:
|
322
|
+
# domain_name = DomainName
|
323
|
+
# item_name = ItemName
|
324
|
+
# attributes = {
|
325
|
+
# 'nameA' => [valueA1,..., valueAN],
|
326
|
+
# ...
|
327
|
+
# 'nameZ' => [valueZ1,..., valueZN]
|
328
|
+
# }
|
329
|
+
# replace = :replace | any other value to skip replacement
|
330
|
+
#
|
331
|
+
# Returns a hash: { :box_usage, :request_id } on success or an exception on error.
|
332
|
+
# (Amazon raises no errors if the attribute was not overridden, as when the :replace param is unset).
|
333
|
+
#
|
334
|
+
# Example:
|
335
|
+
#
|
336
|
+
# sdb = Aws::SdbInterface.new
|
337
|
+
# sdb.create_domain 'family'
|
338
|
+
#
|
339
|
+
# attributes = {}
|
340
|
+
# # create attributes for Jon and Silvia
|
341
|
+
# attributes['Jon'] = %w{ car beer }
|
342
|
+
# attributes['Silvia'] = %w{ beetle rolling_pin kids }
|
343
|
+
# sdb.put_attributes 'family', 'toys', attributes #=> ok
|
344
|
+
# # now: Jon=>[car, beer], Silvia=>[beetle, rolling_pin, kids]
|
345
|
+
#
|
346
|
+
# # add attributes to Jon
|
347
|
+
# attributes.delete('Silvia')
|
348
|
+
# attributes['Jon'] = %w{ girls pub }
|
349
|
+
# sdb.put_attributes 'family', 'toys', attributes #=> ok
|
350
|
+
# # now: Jon=>[car, beer, girls, pub], Silvia=>[beetle, rolling_pin, kids]
|
351
|
+
#
|
352
|
+
# # replace attributes for Jon and add to a cat (the cat had no attributes before)
|
353
|
+
# attributes['Jon'] = %w{ vacuum_cleaner hammer spade }
|
354
|
+
# attributes['cat'] = %w{ mouse clew Jons_socks }
|
355
|
+
# sdb.put_attributes 'family', 'toys', attributes, :replace #=> ok
|
356
|
+
# # now: Jon=>[vacuum_cleaner, hammer, spade], Silvia=>[beetle, rolling_pin, kids], cat=>[mouse, clew, Jons_socks]
|
357
|
+
#
|
358
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_PutAttributes.html
|
359
|
+
#
|
360
|
+
def put_attributes(domain_name, item_name, attributes, replace = false)
|
361
|
+
params = { 'DomainName' => domain_name,
|
362
|
+
'ItemName' => item_name }.merge(pack_attributes(attributes, replace))
|
363
|
+
link = generate_request("PutAttributes", params)
|
364
|
+
request_info( link, QSdbSimpleParser.new )
|
365
|
+
rescue Exception
|
366
|
+
on_exception
|
367
|
+
end
|
321
368
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
#
|
339
|
-
# sdb = Aws::SdbInterface.new
|
340
|
-
# sdb.create_domain 'family'
|
341
|
-
#
|
342
|
-
# attributes = {}
|
343
|
-
# # create attributes for Jon and Silvia
|
344
|
-
# attributes['Jon'] = %w{ car beer }
|
345
|
-
# attributes['Silvia'] = %w{ beetle rolling_pin kids }
|
346
|
-
# sdb.put_attributes 'family', 'toys', attributes #=> ok
|
347
|
-
# # now: Jon=>[car, beer], Silvia=>[beetle, rolling_pin, kids]
|
348
|
-
#
|
349
|
-
# # add attributes to Jon
|
350
|
-
# attributes.delete('Silvia')
|
351
|
-
# attributes['Jon'] = %w{ girls pub }
|
352
|
-
# sdb.put_attributes 'family', 'toys', attributes #=> ok
|
353
|
-
# # now: Jon=>[car, beer, girls, pub], Silvia=>[beetle, rolling_pin, kids]
|
354
|
-
#
|
355
|
-
# # replace attributes for Jon and add to a cat (the cat had no attributes before)
|
356
|
-
# attributes['Jon'] = %w{ vacuum_cleaner hammer spade }
|
357
|
-
# attributes['cat'] = %w{ mouse clew Jons_socks }
|
358
|
-
# sdb.put_attributes 'family', 'toys', attributes, :replace #=> ok
|
359
|
-
# # now: Jon=>[vacuum_cleaner, hammer, spade], Silvia=>[beetle, rolling_pin, kids], cat=>[mouse, clew, Jons_socks]
|
360
|
-
#
|
361
|
-
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_PutAttributes.html
|
362
|
-
#
|
363
|
-
def put_attributes(domain_name, item_name, attributes, replace = false)
|
364
|
-
params = { 'DomainName' => domain_name,
|
365
|
-
'ItemName' => item_name }.merge(pack_attributes(attributes, replace))
|
366
|
-
link = generate_request("PutAttributes", params)
|
367
|
-
request_info( link, QSdbSimpleParser.new )
|
368
|
-
rescue Exception
|
369
|
-
on_exception
|
370
|
-
end
|
369
|
+
#
|
370
|
+
# items is an array of Aws::SdbInterface::Item.new(o.id, o.attributes, true)
|
371
|
+
def batch_put_attributes(domain_name, items)
|
372
|
+
params = { 'DomainName' => domain_name }
|
373
|
+
i = 0
|
374
|
+
items.each do |item|
|
375
|
+
prefix = "Item." + i.to_s + "."
|
376
|
+
params[prefix + "ItemName"] = item.item_name
|
377
|
+
params.merge!(pack_attributes(item.attributes, item.replace, prefix))
|
378
|
+
i += 1
|
379
|
+
end
|
380
|
+
link = generate_request("BatchPutAttributes", params)
|
381
|
+
request_info( link, QSdbSimpleParser.new )
|
382
|
+
rescue Exception
|
383
|
+
on_exception
|
384
|
+
end
|
371
385
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
386
|
+
# Retrieve SDB item's attribute(s).
|
387
|
+
#
|
388
|
+
# Returns a hash:
|
389
|
+
# { :box_usage => string,
|
390
|
+
# :request_id => string,
|
391
|
+
# :attributes => { 'nameA' => [valueA1,..., valueAN],
|
392
|
+
# ... ,
|
393
|
+
# 'nameZ' => [valueZ1,..., valueZN] } }
|
394
|
+
#
|
395
|
+
# Example:
|
396
|
+
# # request all attributes
|
397
|
+
# sdb.get_attributes('family', 'toys') # => { :attributes => {"cat" => ["clew", "Jons_socks", "mouse"] },
|
398
|
+
# "Silvia" => ["beetle", "rolling_pin", "kids"],
|
399
|
+
# "Jon" => ["vacuum_cleaner", "hammer", "spade"]},
|
400
|
+
# :box_usage => "0.0000093222",
|
401
|
+
# :request_id => "81273d21-000-1111-b3f9-512d91d29ac8" }
|
402
|
+
#
|
403
|
+
# # request cat's attributes only
|
404
|
+
# sdb.get_attributes('family', 'toys', 'cat') # => { :attributes => {"cat" => ["clew", "Jons_socks", "mouse"] },
|
405
|
+
# :box_usage => "0.0000093222",
|
406
|
+
# :request_id => "81273d21-001-1111-b3f9-512d91d29ac8" }
|
407
|
+
#
|
408
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_GetAttributes.html
|
409
|
+
#
|
410
|
+
def get_attributes(domain_name, item_name, attribute_name=nil)
|
411
|
+
link = generate_request("GetAttributes", 'DomainName' => domain_name,
|
412
|
+
'ItemName' => item_name,
|
413
|
+
'AttributeName' => attribute_name )
|
414
|
+
res = request_info(link, QSdbGetAttributesParser.new)
|
415
|
+
res[:attributes].each_value do |values|
|
416
|
+
values.collect! { |e| sdb_to_ruby(e) }
|
417
|
+
end
|
418
|
+
res
|
419
|
+
rescue Exception
|
420
|
+
on_exception
|
421
|
+
end
|
388
422
|
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
def get_attributes(domain_name, item_name, attribute_name=nil)
|
414
|
-
link = generate_request("GetAttributes", 'DomainName' => domain_name,
|
415
|
-
'ItemName' => item_name,
|
416
|
-
'AttributeName' => attribute_name )
|
417
|
-
res = request_info(link, QSdbGetAttributesParser.new)
|
418
|
-
res[:attributes].each_value do |values|
|
419
|
-
values.collect! { |e| sdb_to_ruby(e) }
|
420
|
-
end
|
421
|
-
res
|
422
|
-
rescue Exception
|
423
|
-
on_exception
|
424
|
-
end
|
423
|
+
# Delete value, attribute or item.
|
424
|
+
#
|
425
|
+
# Example:
|
426
|
+
# # delete 'vodka' and 'girls' from 'Jon' and 'mice' from 'cat'.
|
427
|
+
# sdb.delete_attributes 'family', 'toys', { 'Jon' => ['vodka', 'girls'], 'cat' => ['mice'] }
|
428
|
+
#
|
429
|
+
# # delete the all the values from attributes (i.e. delete the attributes)
|
430
|
+
# sdb.delete_attributes 'family', 'toys', { 'Jon' => [], 'cat' => [] }
|
431
|
+
# # or
|
432
|
+
# sdb.delete_attributes 'family', 'toys', [ 'Jon', 'cat' ]
|
433
|
+
#
|
434
|
+
# # delete all the attributes from item 'toys' (i.e. delete the item)
|
435
|
+
# sdb.delete_attributes 'family', 'toys'
|
436
|
+
#
|
437
|
+
# see http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_DeleteAttributes.html
|
438
|
+
#
|
439
|
+
def delete_attributes(domain_name, item_name, attributes = nil)
|
440
|
+
params = { 'DomainName' => domain_name,
|
441
|
+
'ItemName' => item_name }.merge(pack_attributes(attributes))
|
442
|
+
link = generate_request("DeleteAttributes", params)
|
443
|
+
request_info( link, QSdbSimpleParser.new )
|
444
|
+
rescue Exception
|
445
|
+
on_exception
|
446
|
+
end
|
425
447
|
|
426
|
-
# Delete value, attribute or item.
|
427
|
-
#
|
428
|
-
# Example:
|
429
|
-
# # delete 'vodka' and 'girls' from 'Jon' and 'mice' from 'cat'.
|
430
|
-
# sdb.delete_attributes 'family', 'toys', { 'Jon' => ['vodka', 'girls'], 'cat' => ['mice'] }
|
431
|
-
#
|
432
|
-
# # delete the all the values from attributes (i.e. delete the attributes)
|
433
|
-
# sdb.delete_attributes 'family', 'toys', { 'Jon' => [], 'cat' => [] }
|
434
|
-
# # or
|
435
|
-
# sdb.delete_attributes 'family', 'toys', [ 'Jon', 'cat' ]
|
436
|
-
#
|
437
|
-
# # delete all the attributes from item 'toys' (i.e. delete the item)
|
438
|
-
# sdb.delete_attributes 'family', 'toys'
|
439
|
-
#
|
440
|
-
# see http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_DeleteAttributes.html
|
441
|
-
#
|
442
|
-
def delete_attributes(domain_name, item_name, attributes = nil)
|
443
|
-
params = { 'DomainName' => domain_name,
|
444
|
-
'ItemName' => item_name }.merge(pack_attributes(attributes))
|
445
|
-
link = generate_request("DeleteAttributes", params)
|
446
|
-
request_info( link, QSdbSimpleParser.new )
|
447
|
-
rescue Exception
|
448
|
-
on_exception
|
449
|
-
end
|
450
448
|
|
449
|
+
# QUERY:
|
450
|
+
|
451
|
+
# Perform a query on SDB.
|
452
|
+
#
|
453
|
+
# Returns a hash:
|
454
|
+
# { :box_usage => string,
|
455
|
+
# :request_id => string,
|
456
|
+
# :next_token => string,
|
457
|
+
# :items => [ItemName1,..., ItemNameN] }
|
458
|
+
#
|
459
|
+
# Example:
|
460
|
+
#
|
461
|
+
# query = "['cat' = 'clew']"
|
462
|
+
# sdb.query('family', query) #=> hash of data
|
463
|
+
# sdb.query('family', query, 10) #=> hash of data with max of 10 items
|
464
|
+
#
|
465
|
+
# If a block is given, query will iteratively yield results to it as long as the block continues to return true.
|
466
|
+
#
|
467
|
+
# # List 10 items per iteration. Don't
|
468
|
+
# # forget to escape single quotes and backslashes and wrap all the items in single quotes.
|
469
|
+
# query = "['cat'='clew'] union ['dog'='Jon\\'s boot']"
|
470
|
+
# sdb.query('family', query, 10) do |result|
|
471
|
+
# puts result.inspect
|
472
|
+
# true
|
473
|
+
# end
|
474
|
+
#
|
475
|
+
# # Same query using automatic escaping...to use the auto escape, pass the query and its params as an array:
|
476
|
+
# query = [ "['cat'=?] union ['dog'=?]", "clew", "Jon's boot" ]
|
477
|
+
# sdb.query('family', query)
|
478
|
+
#
|
479
|
+
# query = [ "['cat'=?] union ['dog'=?] sort 'cat' desc", "clew", "Jon's boot" ]
|
480
|
+
# sdb.query('family', query)
|
481
|
+
#
|
482
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_Query.html
|
483
|
+
# http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?SortingData.html
|
484
|
+
#
|
485
|
+
def query(domain_name, query_expression = nil, max_number_of_items = nil, next_token = nil)
|
486
|
+
query_expression = query_expression_from_array(query_expression) if query_expression.is_a?(Array)
|
487
|
+
@last_query_expression = query_expression
|
488
|
+
#
|
489
|
+
request_params = { 'DomainName' => domain_name,
|
490
|
+
'QueryExpression' => query_expression,
|
491
|
+
'MaxNumberOfItems' => max_number_of_items,
|
492
|
+
'NextToken' => next_token }
|
493
|
+
link = generate_request("Query", request_params)
|
494
|
+
result = request_info( link, QSdbQueryParser.new )
|
495
|
+
# return result if no block given
|
496
|
+
return result unless block_given?
|
497
|
+
# loop if block if given
|
498
|
+
begin
|
499
|
+
# the block must return true if it wanna continue
|
500
|
+
break unless yield(result) && result[:next_token]
|
501
|
+
# make new request
|
502
|
+
request_params['NextToken'] = result[:next_token]
|
503
|
+
link = generate_request("Query", request_params)
|
504
|
+
result = request_info( link, QSdbQueryParser.new )
|
505
|
+
end while true
|
506
|
+
rescue Exception
|
507
|
+
on_exception
|
508
|
+
end
|
451
509
|
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
510
|
+
# Perform a query and fetch specified attributes.
|
511
|
+
# If attributes are not specified then fetches the whole list of attributes.
|
512
|
+
#
|
513
|
+
#
|
514
|
+
# Returns a hash:
|
515
|
+
# { :box_usage => string,
|
516
|
+
# :request_id => string,
|
517
|
+
# :next_token => string,
|
518
|
+
# :items => [ { ItemName1 => { attribute1 => value1, ... attributeM => valueM } },
|
519
|
+
# { ItemName2 => {...}}, ... ]
|
520
|
+
#
|
521
|
+
# Example:
|
522
|
+
#
|
523
|
+
# sdb.query_with_attributes(domain, ['hobby', 'country'], "['gender'='female'] intersection ['name' starts-with ''] sort 'name'") #=>
|
524
|
+
# { :request_id => "06057228-70d0-4487-89fb-fd9c028580d3",
|
525
|
+
# :items =>
|
526
|
+
# [ { "035f1ba8-dbd8-11dd-80bd-001bfc466dd7"=>
|
527
|
+
# { "hobby" => ["cooking", "flowers", "cats"],
|
528
|
+
# "country" => ["Russia"]}},
|
529
|
+
# { "0327614a-dbd8-11dd-80bd-001bfc466dd7"=>
|
530
|
+
# { "hobby" => ["patchwork", "bundle jumping"],
|
531
|
+
# "country" => ["USA"]}}, ... ],
|
532
|
+
# :box_usage=>"0.0000504786"}
|
533
|
+
#
|
534
|
+
# sdb.query_with_attributes(domain, [], "['gender'='female'] intersection ['name' starts-with ''] sort 'name'") #=>
|
535
|
+
# { :request_id => "75bb19db-a529-4f69-b86f-5e3800f79a45",
|
536
|
+
# :items =>
|
537
|
+
# [ { "035f1ba8-dbd8-11dd-80bd-001bfc466dd7"=>
|
538
|
+
# { "hobby" => ["cooking", "flowers", "cats"],
|
539
|
+
# "name" => ["Mary"],
|
540
|
+
# "country" => ["Russia"],
|
541
|
+
# "gender" => ["female"],
|
542
|
+
# "id" => ["035f1ba8-dbd8-11dd-80bd-001bfc466dd7"]}},
|
543
|
+
# { "0327614a-dbd8-11dd-80bd-001bfc466dd7"=>
|
544
|
+
# { "hobby" => ["patchwork", "bundle jumping"],
|
545
|
+
# "name" => ["Mary"],
|
546
|
+
# "country" => ["USA"],
|
547
|
+
# "gender" => ["female"],
|
548
|
+
# "id" => ["0327614a-dbd8-11dd-80bd-001bfc466dd7"]}}, ... ],
|
549
|
+
# :box_usage=>"0.0000506668"}
|
550
|
+
#
|
551
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?SDB_API_QueryWithAttributes.html
|
552
|
+
#
|
553
|
+
def query_with_attributes(domain_name, attributes=[], query_expression = nil, max_number_of_items = nil, next_token = nil)
|
554
|
+
attributes = attributes.to_a
|
555
|
+
query_expression = query_expression_from_array(query_expression) if query_expression.is_a?(Array)
|
556
|
+
@last_query_expression = query_expression
|
557
|
+
#
|
558
|
+
request_params = { 'DomainName' => domain_name,
|
559
|
+
'QueryExpression' => query_expression,
|
560
|
+
'MaxNumberOfItems' => max_number_of_items,
|
561
|
+
'NextToken' => next_token }
|
562
|
+
attributes.each_with_index do |attribute, idx|
|
563
|
+
request_params["AttributeName.#{idx+1}"] = attribute
|
564
|
+
end
|
565
|
+
link = generate_request("QueryWithAttributes", request_params)
|
566
|
+
result = select_response_to_ruby(request_info( link, QSdbQueryWithAttributesParser.new ))
|
567
|
+
# return result if no block given
|
568
|
+
return result unless block_given?
|
569
|
+
# loop if block if given
|
570
|
+
begin
|
571
|
+
# the block must return true if it wanna continue
|
572
|
+
break unless yield(result) && result[:next_token]
|
573
|
+
# make new request
|
574
|
+
request_params['NextToken'] = result[:next_token]
|
575
|
+
link = generate_request("QueryWithAttributes", request_params)
|
576
|
+
result = select_response_to_ruby(request_info( link, QSdbQueryWithAttributesParser.new ))
|
577
|
+
end while true
|
578
|
+
rescue Exception
|
579
|
+
on_exception
|
580
|
+
end
|
512
581
|
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
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
|
582
|
+
# Perform SQL-like select and fetch attributes.
|
583
|
+
# 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.
|
584
|
+
# (Use array to pass select_expression params to avoid manual escaping).
|
585
|
+
#
|
586
|
+
# sdb.select(["select * from my_domain where gender=?", 'female']) #=>
|
587
|
+
# {:request_id =>"8241b843-0fb9-4d66-9100-effae12249ec",
|
588
|
+
# :items =>
|
589
|
+
# [ { "035f1ba8-dbd8-11dd-80bd-001bfc466dd7"=>
|
590
|
+
# {"hobby" => ["cooking", "flowers", "cats"],
|
591
|
+
# "name" => ["Mary"],
|
592
|
+
# "country" => ["Russia"],
|
593
|
+
# "gender" => ["female"],
|
594
|
+
# "id" => ["035f1ba8-dbd8-11dd-80bd-001bfc466dd7"]}},
|
595
|
+
# { "0327614a-dbd8-11dd-80bd-001bfc466dd7"=>
|
596
|
+
# {"hobby" => ["patchwork", "bundle jumping"],
|
597
|
+
# "name" => ["Mary"],
|
598
|
+
# "country" => ["USA"],
|
599
|
+
# "gender" => ["female"],
|
600
|
+
# "id" => ["0327614a-dbd8-11dd-80bd-001bfc466dd7"]}}, ... ]
|
601
|
+
# :box_usage =>"0.0000506197"}
|
602
|
+
#
|
603
|
+
# sdb.select('select country, name from my_domain') #=>
|
604
|
+
# {:request_id=>"b1600198-c317-413f-a8dc-4e7f864a940a",
|
605
|
+
# :items=>
|
606
|
+
# [ { "035f1ba8-dbd8-11dd-80bd-001bfc466dd7"=> {"name"=>["Mary"], "country"=>["Russia"]} },
|
607
|
+
# { "376d2e00-75b0-11dd-9557-001bfc466dd7"=> {"name"=>["Putin"], "country"=>["Russia"]} },
|
608
|
+
# { "0327614a-dbd8-11dd-80bd-001bfc466dd7"=> {"name"=>["Mary"], "country"=>["USA"]} },
|
609
|
+
# { "372ebbd4-75b0-11dd-9557-001bfc466dd7"=> {"name"=>["Bush"], "country"=>["USA"]} },
|
610
|
+
# { "37a4e552-75b0-11dd-9557-001bfc466dd7"=> {"name"=>["Medvedev"], "country"=>["Russia"]} },
|
611
|
+
# { "38278dfe-75b0-11dd-9557-001bfc466dd7"=> {"name"=>["Mary"], "country"=>["Russia"]} },
|
612
|
+
# { "37df6c36-75b0-11dd-9557-001bfc466dd7"=> {"name"=>["Mary"], "country"=>["USA"]} } ],
|
613
|
+
# :box_usage=>"0.0000777663"}
|
614
|
+
#
|
615
|
+
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?SDB_API_Select.html
|
616
|
+
# http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?UsingSelect.html
|
617
|
+
# http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?SDBLimits.html
|
618
|
+
#
|
619
|
+
def select(select_expression, next_token = nil)
|
620
|
+
select_expression = query_expression_from_array(select_expression) if select_expression.is_a?(Array)
|
621
|
+
@last_query_expression = select_expression
|
622
|
+
#
|
623
|
+
request_params = { 'SelectExpression' => select_expression,
|
624
|
+
'NextToken' => next_token }
|
625
|
+
link = generate_request("Select", request_params)
|
626
|
+
result = select_response_to_ruby(request_info( link, QSdbSelectParser.new ))
|
627
|
+
return result unless block_given?
|
628
|
+
# loop if block if given
|
629
|
+
begin
|
630
|
+
# the block must return true if it wanna continue
|
631
|
+
break unless yield(result) && result[:next_token]
|
632
|
+
# make new request
|
633
|
+
request_params['NextToken'] = result[:next_token]
|
634
|
+
link = generate_request("Select", request_params)
|
635
|
+
result = select_response_to_ruby(request_info( link, QSdbSelectParser.new ))
|
636
|
+
end while true
|
637
|
+
rescue Exception
|
638
|
+
on_exception
|
639
|
+
end
|
584
640
|
|
585
|
-
|
586
|
-
|
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
|
641
|
+
class Item
|
642
|
+
attr_accessor :item_name, :attributes, :replace
|
643
643
|
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
end
|
651
|
-
end
|
644
|
+
def initialize(item_name, attributes, replace = false)
|
645
|
+
@item_name = item_name
|
646
|
+
@attributes = attributes
|
647
|
+
@replace = replace
|
648
|
+
end
|
649
|
+
end
|
652
650
|
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
def tagend(name)
|
661
|
-
case name
|
662
|
-
when 'NextToken' then @result[:next_token] = @text
|
663
|
-
when 'DomainName' then @result[:domains] << @text
|
664
|
-
when 'BoxUsage' then @result[:box_usage] = @text
|
665
|
-
when 'RequestId' then @result[:request_id] = @text
|
666
|
-
end
|
667
|
-
end
|
668
|
-
end
|
651
|
+
#-----------------------------------------------------------------
|
652
|
+
# PARSERS:
|
653
|
+
#-----------------------------------------------------------------
|
654
|
+
class QSdbListDomainParser < AwsParser #:nodoc:
|
655
|
+
def reset
|
656
|
+
@result = { :domains => [] }
|
657
|
+
end
|
669
658
|
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
end
|
685
|
-
end
|
686
|
-
end
|
659
|
+
def tagend(name)
|
660
|
+
case name
|
661
|
+
when 'NextToken' then
|
662
|
+
@result[:next_token] = @text
|
663
|
+
when 'DomainName' then
|
664
|
+
@result[:domains] << @text
|
665
|
+
when 'BoxUsage' then
|
666
|
+
@result[:box_usage] = @text
|
667
|
+
when 'RequestId' then
|
668
|
+
@result[:request_id] = @text
|
669
|
+
end
|
670
|
+
end
|
671
|
+
end
|
687
672
|
|
673
|
+
class QSdbDomainMetadataParser < AwsParser #:nodoc:
|
674
|
+
def reset
|
675
|
+
@result = {}
|
676
|
+
end
|
688
677
|
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
678
|
+
def tagend(name)
|
679
|
+
case name
|
680
|
+
when 'Timestamp' then
|
681
|
+
@result[:timestamp] = @text
|
682
|
+
when 'ItemCount' then
|
683
|
+
@result[:item_count] = @text.to_i
|
684
|
+
when 'AttributeValueCount' then
|
685
|
+
@result[:attribute_value_count] = @text.to_i
|
686
|
+
when 'AttributeNameCount' then
|
687
|
+
@result[:attribute_name_acount] = @text.to_i
|
688
|
+
when 'ItemNamesSizeBytes' then
|
689
|
+
@result[:item_names_size_bytes] = @text.to_i
|
690
|
+
when 'AttributeValuesSizeBytes' then
|
691
|
+
@result[:attributes_values_size_bytes] = @text.to_i
|
692
|
+
when 'AttributeNamesSizeBytes' then
|
693
|
+
@result[:attributes_names_size_bytes] = @text.to_i
|
694
|
+
|
695
|
+
end
|
696
|
+
end
|
697
697
|
end
|
698
|
-
end
|
699
|
-
end
|
700
698
|
|
701
|
-
class QSdbGetAttributesParser < AwsParser #:nodoc:
|
702
|
-
def reset
|
703
|
-
@last_attribute_name = nil
|
704
|
-
@result = { :attributes => {} }
|
705
|
-
end
|
706
|
-
def tagend(name)
|
707
|
-
case name
|
708
|
-
when 'Name' then @last_attribute_name = @text
|
709
|
-
when 'Value' then (@result[:attributes][@last_attribute_name] ||= []) << @text
|
710
|
-
when 'BoxUsage' then @result[:box_usage] = @text
|
711
|
-
when 'RequestId' then @result[:request_id] = @text
|
712
|
-
end
|
713
|
-
end
|
714
|
-
end
|
715
699
|
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
def tagend(name)
|
721
|
-
case name
|
722
|
-
when 'ItemName' then @result[:items] << @text
|
723
|
-
when 'BoxUsage' then @result[:box_usage] = @text
|
724
|
-
when 'RequestId' then @result[:request_id] = @text
|
725
|
-
when 'NextToken' then @result[:next_token] = @text
|
726
|
-
end
|
727
|
-
end
|
728
|
-
end
|
700
|
+
class QSdbSimpleParser < AwsParser #:nodoc:
|
701
|
+
def reset
|
702
|
+
@result = {}
|
703
|
+
end
|
729
704
|
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
@item = @text
|
740
|
-
@result[:items] << { @item => {} }
|
741
|
-
when 'QueryWithAttributesResponse/QueryWithAttributesResult/Item/Attribute'
|
742
|
-
@attribute = @text
|
743
|
-
@result[:items].last[@item][@attribute] ||= []
|
744
|
-
end
|
745
|
-
when 'RequestId' then @result[:request_id] = @text
|
746
|
-
when 'BoxUsage' then @result[:box_usage] = @text
|
747
|
-
when 'NextToken' then @result[:next_token] = @text
|
748
|
-
when 'Value' then @result[:items].last[@item][@attribute] << @text
|
749
|
-
end
|
750
|
-
end
|
751
|
-
end
|
705
|
+
def tagend(name)
|
706
|
+
case name
|
707
|
+
when 'BoxUsage' then
|
708
|
+
@result[:box_usage] = @text
|
709
|
+
when 'RequestId' then
|
710
|
+
@result[:request_id] = @text
|
711
|
+
end
|
712
|
+
end
|
713
|
+
end
|
752
714
|
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
715
|
+
class QSdbGetAttributesParser < AwsParser #:nodoc:
|
716
|
+
def reset
|
717
|
+
@last_attribute_name = nil
|
718
|
+
@result = { :attributes => {} }
|
719
|
+
end
|
720
|
+
|
721
|
+
def tagend(name)
|
722
|
+
case name
|
723
|
+
when 'Name' then
|
724
|
+
@last_attribute_name = @text
|
725
|
+
when 'Value' then
|
726
|
+
(@result[:attributes][@last_attribute_name] ||= []) << @text
|
727
|
+
when 'BoxUsage' then
|
728
|
+
@result[:box_usage] = @text
|
729
|
+
when 'RequestId' then
|
730
|
+
@result[:request_id] = @text
|
731
|
+
end
|
732
|
+
end
|
733
|
+
end
|
734
|
+
|
735
|
+
class QSdbQueryParser < AwsParser #:nodoc:
|
736
|
+
def reset
|
737
|
+
@result = { :items => [] }
|
738
|
+
end
|
739
|
+
|
740
|
+
def tagend(name)
|
741
|
+
case name
|
742
|
+
when 'ItemName' then
|
743
|
+
@result[:items] << @text
|
744
|
+
when 'BoxUsage' then
|
745
|
+
@result[:box_usage] = @text
|
746
|
+
when 'RequestId' then
|
747
|
+
@result[:request_id] = @text
|
748
|
+
when 'NextToken' then
|
749
|
+
@result[:next_token] = @text
|
750
|
+
end
|
751
|
+
end
|
752
|
+
end
|
753
|
+
|
754
|
+
class QSdbQueryWithAttributesParser < AwsParser #:nodoc:
|
755
|
+
def reset
|
756
|
+
@result = { :items => [] }
|
757
|
+
end
|
758
|
+
|
759
|
+
def tagend(name)
|
760
|
+
case name
|
761
|
+
when 'Name'
|
762
|
+
case @xmlpath
|
763
|
+
when 'QueryWithAttributesResponse/QueryWithAttributesResult/Item'
|
764
|
+
@item = @text
|
765
|
+
@result[:items] << { @item => {} }
|
766
|
+
when 'QueryWithAttributesResponse/QueryWithAttributesResult/Item/Attribute'
|
767
|
+
@attribute = @text
|
768
|
+
@result[:items].last[@item][@attribute] ||= []
|
769
|
+
end
|
770
|
+
when 'RequestId' then
|
771
|
+
@result[:request_id] = @text
|
772
|
+
when 'BoxUsage' then
|
773
|
+
@result[:box_usage] = @text
|
774
|
+
when 'NextToken' then
|
775
|
+
@result[:next_token] = @text
|
776
|
+
when 'Value' then
|
777
|
+
@result[:items].last[@item][@attribute] << @text
|
778
|
+
end
|
779
|
+
end
|
780
|
+
end
|
775
781
|
|
776
|
-
|
782
|
+
class QSdbSelectParser < AwsParser #:nodoc:
|
783
|
+
def reset
|
784
|
+
@result = { :items => [] }
|
785
|
+
end
|
786
|
+
|
787
|
+
def tagend(name)
|
788
|
+
case name
|
789
|
+
when 'Name'
|
790
|
+
case @xmlpath
|
791
|
+
when 'SelectResponse/SelectResult/Item'
|
792
|
+
@item = @text
|
793
|
+
@result[:items] << { @item => {} }
|
794
|
+
when 'SelectResponse/SelectResult/Item/Attribute'
|
795
|
+
@attribute = @text
|
796
|
+
@result[:items].last[@item][@attribute] ||= []
|
797
|
+
end
|
798
|
+
when 'RequestId' then
|
799
|
+
@result[:request_id] = @text
|
800
|
+
when 'BoxUsage' then
|
801
|
+
@result[:box_usage] = @text
|
802
|
+
when 'NextToken' then
|
803
|
+
@result[:next_token] = @text
|
804
|
+
when 'Value' then
|
805
|
+
@result[:items].last[@item][@attribute] << @text
|
806
|
+
end
|
807
|
+
end
|
808
|
+
end
|
809
|
+
|
810
|
+
end
|
777
811
|
|
778
812
|
end
|