aws-sdk 1.2.3 → 1.2.4
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/lib/aws/core.rb +1 -1
- data/lib/aws/core/http/net_http_handler.rb +21 -62
- data/lib/aws/record/attribute_macros.rb +28 -4
- data/lib/aws/record/attributes/date.rb +89 -0
- data/lib/aws/record/base.rb +41 -4
- data/lib/aws/record/finder_methods.rb +7 -5
- data/lib/aws/record/scope.rb +32 -5
- data/lib/aws/s3/bucket.rb +14 -5
- data/lib/aws/s3/bucket_version_collection.rb +7 -11
- data/lib/aws/s3/client.rb +37 -1
- data/lib/aws/s3/client/xml.rb +8 -1
- data/lib/aws/s3/errors.rb +14 -0
- data/lib/aws/s3/multipart_upload_collection.rb +0 -3
- data/lib/aws/s3/object_collection.rb +182 -6
- data/lib/aws/s3/paginated_collection.rb +21 -40
- data/lib/aws/s3/prefix_and_delimiter_collection.rb +0 -7
- data/lib/aws/s3/presigned_post.rb +26 -11
- data/lib/aws/s3/request.rb +1 -1
- data/lib/aws/s3/s3_object.rb +10 -4
- data/lib/aws/s3/uploaded_part_collection.rb +3 -1
- data/lib/net/http/connection_pool.rb +193 -0
- data/lib/net/http/connection_pool/connection.rb +132 -0
- data/lib/net/http/connection_pool/session.rb +93 -0
- metadata +8 -4
data/lib/aws/core.rb
CHANGED
@@ -11,9 +11,7 @@
|
|
11
11
|
# ANY KIND, either express or implied. See the License for the specific
|
12
12
|
# language governing permissions and limitations under the License.
|
13
13
|
|
14
|
-
require 'net/http'
|
15
|
-
require 'net/https'
|
16
|
-
require 'openssl'
|
14
|
+
require 'net/http/connection_pool'
|
17
15
|
|
18
16
|
module AWS
|
19
17
|
module Core
|
@@ -22,72 +20,33 @@ module AWS
|
|
22
20
|
# The default http request handler for the aws-sdk gem. It is based
|
23
21
|
# on Net::Http.
|
24
22
|
class NetHttpHandler
|
25
|
-
|
26
|
-
def handle request, response
|
27
|
-
http_session_for(request) do |http|
|
28
|
-
begin
|
29
|
-
http_resp = http.request(build_request(request))
|
30
|
-
response.body = http_resp.body
|
31
|
-
response.status = http_resp.code.to_i
|
32
|
-
response.headers = http_resp.to_hash
|
33
|
-
rescue Timeout::Error, Errno::ETIMEDOUT => e
|
34
|
-
response.timeout = true
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# @private
|
40
|
-
protected
|
41
|
-
def http_session_for request, &block
|
42
|
-
begin
|
43
|
-
http = build_http(request)
|
44
|
-
http.start
|
45
|
-
yield(http)
|
46
|
-
ensure
|
47
|
-
http.finish if http.started?
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# @private
|
52
|
-
protected
|
53
|
-
def build_http request
|
54
|
-
|
55
|
-
http_args = []
|
56
|
-
http_args << request.host
|
57
|
-
http_args << (request.use_ssl? ? 443 : 80)
|
58
23
|
|
59
|
-
|
24
|
+
@@pool = Net::HTTP::ConnectionPool.new
|
60
25
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
http_args << proxy.password
|
68
|
-
end
|
26
|
+
# @private
|
27
|
+
def self.pool
|
28
|
+
@@pool
|
29
|
+
end
|
30
|
+
|
31
|
+
def handle request, response
|
69
32
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
33
|
+
options = {}
|
34
|
+
options[:ssl] = request.use_ssl?
|
35
|
+
options[:proxy_uri] = request.proxy_uri
|
36
|
+
options[:ssl_verify_peer] = request.ssl_verify_peer?
|
37
|
+
options[:ssl_ca_file] = request.ssl_ca_file
|
74
38
|
|
75
|
-
|
39
|
+
connection = self.class.pool.connection_for(request.host, options)
|
76
40
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
85
|
-
else
|
86
|
-
http.use_ssl = false
|
41
|
+
begin
|
42
|
+
http_response = connection.request(build_request(request))
|
43
|
+
response.body = http_response.body
|
44
|
+
response.status = http_response.code.to_i
|
45
|
+
response.headers = http_response.to_hash
|
46
|
+
rescue Timeout::Error, Errno::ETIMEDOUT => e
|
47
|
+
response.timeout = true
|
87
48
|
end
|
88
49
|
|
89
|
-
http
|
90
|
-
|
91
50
|
end
|
92
51
|
|
93
52
|
# @private
|
@@ -18,6 +18,7 @@ require 'aws/record/attributes/float'
|
|
18
18
|
require 'aws/record/attributes/sortable_float'
|
19
19
|
require 'aws/record/attributes/boolean'
|
20
20
|
require 'aws/record/attributes/datetime'
|
21
|
+
require 'aws/record/attributes/date'
|
21
22
|
|
22
23
|
module AWS
|
23
24
|
module Record
|
@@ -204,16 +205,39 @@ module AWS
|
|
204
205
|
# will be automanaged.
|
205
206
|
#
|
206
207
|
# @param [Symbol] name The name of the attribute.
|
208
|
+
#
|
207
209
|
# @param [Hash] options
|
208
|
-
#
|
209
|
-
# serialized with the correct number of digits to SimpleDB, left
|
210
|
-
# padded by zeros to allow sorting.
|
210
|
+
#
|
211
211
|
# @option options [Boolean] :set (false) When true this attribute
|
212
|
-
# can have multiple
|
212
|
+
# can have multiple date times.
|
213
|
+
#
|
213
214
|
def datetime_attr name, options = {}
|
214
215
|
add_attribute(DateTimeAttribute.new(name, options))
|
215
216
|
end
|
216
217
|
|
218
|
+
# Adds a date attribute to this class.
|
219
|
+
#
|
220
|
+
# @example A standard date attribute
|
221
|
+
#
|
222
|
+
# class Person < AWS::Record::Base
|
223
|
+
# date_attr :birthdate
|
224
|
+
# end
|
225
|
+
#
|
226
|
+
# baby = Person.new
|
227
|
+
# baby.birthdate = Time.now
|
228
|
+
# baby.birthdate #=> <Date: ....>
|
229
|
+
#
|
230
|
+
# @param [Symbol] name The name of the attribute.
|
231
|
+
#
|
232
|
+
# @param [Hash] options
|
233
|
+
#
|
234
|
+
# @option options [Boolean] :set (false) When true this attribute
|
235
|
+
# can have multiple dates.
|
236
|
+
#
|
237
|
+
def date_attr name, options = {}
|
238
|
+
add_attribute(DateAttribute.new(name, options))
|
239
|
+
end
|
240
|
+
|
217
241
|
# A convenience method for adding the standard two datetime attributes
|
218
242
|
# +:created_at+ and +:updated_at+.
|
219
243
|
#
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
8
|
+
#
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
12
|
+
# language governing permissions and limitations under the License.
|
13
|
+
|
14
|
+
require 'date'
|
15
|
+
require 'aws/record/attribute'
|
16
|
+
|
17
|
+
module AWS
|
18
|
+
module Record
|
19
|
+
|
20
|
+
# @private
|
21
|
+
class DateAttribute < Attribute
|
22
|
+
|
23
|
+
# Returns value cast to a Date object. Empty strings are cast to
|
24
|
+
# nil. Values are cast first to strings and then passed to
|
25
|
+
# Date.parse. Integers are treated as timestamps.
|
26
|
+
#
|
27
|
+
# date_attribute.type_cast('2000-01-02T10:11:12Z')
|
28
|
+
# #=> #<Date: 4903091/2,0,2299161>
|
29
|
+
#
|
30
|
+
# date_attribute.type_cast(1306170146)
|
31
|
+
# #<Date: 4911409/2,0,2299161>
|
32
|
+
#
|
33
|
+
# date_attribute.type_cast('')
|
34
|
+
# #=> nil
|
35
|
+
#
|
36
|
+
# date_attribute.type_cast(nil)
|
37
|
+
# #=> nil
|
38
|
+
#
|
39
|
+
# @param [Mixed] raw_value The value to cast to a Date object.
|
40
|
+
# @param [Hash] options
|
41
|
+
# @return [Date,nil]
|
42
|
+
def self.type_cast raw_value, options = {}
|
43
|
+
case raw_value
|
44
|
+
when nil then nil
|
45
|
+
when '' then nil
|
46
|
+
when Date then raw_value
|
47
|
+
when Integer then
|
48
|
+
begin
|
49
|
+
Date.parse(Time.at(raw_value).to_s) # assumed timestamp
|
50
|
+
rescue
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
else
|
54
|
+
begin
|
55
|
+
Date.parse(raw_value.to_s) # Time, DateTime or String
|
56
|
+
rescue
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns a Date object encoded as a string (suitable for sorting).
|
63
|
+
#
|
64
|
+
# attribute.serialize(DateTime.parse('2001-01-01'))
|
65
|
+
# #=> '2001-01-01'
|
66
|
+
#
|
67
|
+
# @param [Date] datetime The date to serialize.
|
68
|
+
#
|
69
|
+
# @param [Hash] options
|
70
|
+
#
|
71
|
+
# @return [String] Returns the date object serialized to a string
|
72
|
+
# ('YYYY-MM-DD').
|
73
|
+
#
|
74
|
+
def self.serialize date, options = {}
|
75
|
+
unless date.is_a?(Date)
|
76
|
+
raise ArgumentError, "expected a Date value, got #{date.class}"
|
77
|
+
end
|
78
|
+
date.strftime('%Y-%m-%d')
|
79
|
+
end
|
80
|
+
|
81
|
+
# @private
|
82
|
+
def self.allow_set?
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
data/lib/aws/record/base.rb
CHANGED
@@ -301,11 +301,23 @@ module AWS
|
|
301
301
|
#
|
302
302
|
# @param [Hash] attributes A set of attribute values to seed this record
|
303
303
|
# with. The attributes are bulk assigned.
|
304
|
+
#
|
304
305
|
# @return [Base] Returns a new record that has not been persisted yet.
|
306
|
+
#
|
305
307
|
def initialize attributes = {}
|
308
|
+
|
309
|
+
opts = attributes.dup
|
310
|
+
|
306
311
|
@_data = {}
|
312
|
+
|
313
|
+
@_domain = attributes.delete(:domain)
|
314
|
+
@_domain ||= attributes.delete('domain')
|
315
|
+
@_domain = self.class.domain_name(@_domain)
|
316
|
+
|
307
317
|
assign_default_values
|
318
|
+
|
308
319
|
bulk_assign(attributes)
|
320
|
+
|
309
321
|
end
|
310
322
|
|
311
323
|
# The id for each record is auto-generated. The default strategy
|
@@ -316,6 +328,12 @@ module AWS
|
|
316
328
|
@_id
|
317
329
|
end
|
318
330
|
|
331
|
+
# @return [String] Returns the name of the SimpleDB domain this record
|
332
|
+
# is persisted to or will be persisted to.
|
333
|
+
def domain
|
334
|
+
@_domain
|
335
|
+
end
|
336
|
+
|
319
337
|
# @return [Hash] A hash with attribute names as hash keys (strings) and
|
320
338
|
# attribute values (of mixed types) as hash values.
|
321
339
|
def attributes
|
@@ -450,7 +468,13 @@ module AWS
|
|
450
468
|
# @param [String] name Defaults to the name of this class.
|
451
469
|
# @return [String] Returns the full prefixed domain name for this class.
|
452
470
|
def domain_name name = nil
|
453
|
-
|
471
|
+
|
472
|
+
name = @_domain_name if name.nil?
|
473
|
+
name = self.name if name.nil?
|
474
|
+
name = name.name if name.is_a?(SimpleDB::Domain)
|
475
|
+
|
476
|
+
"#{Record.domain_prefix}#{name}"
|
477
|
+
|
454
478
|
end
|
455
479
|
|
456
480
|
# Creates the SimpleDB domain that is configured for this class.
|
@@ -461,14 +485,19 @@ module AWS
|
|
461
485
|
# @return [AWS::SimpleDB::Domain]
|
462
486
|
#
|
463
487
|
def create_domain name = nil
|
464
|
-
|
488
|
+
sdb.domains.create(domain_name(name))
|
465
489
|
end
|
466
490
|
|
467
491
|
# @return [AWS::SimpleDB::Domain] Returns a reference to the domain
|
468
492
|
# this class will save data to.
|
469
493
|
# @private
|
470
494
|
def sdb_domain name = nil
|
471
|
-
|
495
|
+
sdb.domains[domain_name(name)]
|
496
|
+
end
|
497
|
+
|
498
|
+
protected
|
499
|
+
def sdb
|
500
|
+
AWS::SimpleDB.new
|
472
501
|
end
|
473
502
|
|
474
503
|
end
|
@@ -547,7 +576,14 @@ module AWS
|
|
547
576
|
# @private
|
548
577
|
private
|
549
578
|
def sdb_item
|
550
|
-
|
579
|
+
sdb_domain.items[id]
|
580
|
+
end
|
581
|
+
|
582
|
+
# @return [SimpleDB::Domain] Returns the domain this record is
|
583
|
+
# persisted to or will be persisted to.
|
584
|
+
private
|
585
|
+
def sdb_domain
|
586
|
+
self.class.sdb_domain(domain)
|
551
587
|
end
|
552
588
|
|
553
589
|
# @private
|
@@ -589,6 +625,7 @@ module AWS
|
|
589
625
|
# @todo need to do something about partial hyrdation of attributes
|
590
626
|
private
|
591
627
|
def hydrate id, data
|
628
|
+
|
592
629
|
@_id = id
|
593
630
|
|
594
631
|
# New objects are populated with default values, but we don't
|
@@ -29,11 +29,13 @@ module AWS
|
|
29
29
|
# Record::Base
|
30
30
|
def find_by_id id, options = {}
|
31
31
|
|
32
|
-
|
32
|
+
domain = sdb_domain(options[:domain])
|
33
|
+
|
34
|
+
data = domain.items[id].data.attributes
|
33
35
|
|
34
36
|
raise RecordNotFound, "no data found for id: #{id}" if data.empty?
|
35
37
|
|
36
|
-
obj = self.new
|
38
|
+
obj = self.new(:domain => domain)
|
37
39
|
obj.send(:hydrate, id, data)
|
38
40
|
obj
|
39
41
|
|
@@ -117,7 +119,7 @@ module AWS
|
|
117
119
|
#
|
118
120
|
# @return [Scope] Returns an enumerable scope object.
|
119
121
|
def all options = {}
|
120
|
-
find(:all, options)
|
122
|
+
_new_scope.find(:all, options)
|
121
123
|
end
|
122
124
|
|
123
125
|
# Counts records in SimpleDB.
|
@@ -143,7 +145,7 @@ module AWS
|
|
143
145
|
# records are counted.
|
144
146
|
# @option options [Integer] :limit The max number of records to count.
|
145
147
|
def count(options = {})
|
146
|
-
|
148
|
+
_new_scope.count(options)
|
147
149
|
end
|
148
150
|
alias_method :size, :count
|
149
151
|
|
@@ -151,7 +153,7 @@ module AWS
|
|
151
153
|
# class. If there are no records in the current classes domain, then
|
152
154
|
# nil is returned.
|
153
155
|
def first options = {}
|
154
|
-
_new_scope.
|
156
|
+
_new_scope.first(options)
|
155
157
|
end
|
156
158
|
|
157
159
|
# Limits which records are retried from SimpleDB when performing a find.
|
data/lib/aws/record/scope.rb
CHANGED
@@ -58,13 +58,34 @@ module AWS
|
|
58
58
|
# @private
|
59
59
|
def initialize base_class, options = {}
|
60
60
|
@base_class = base_class
|
61
|
-
@options = options
|
61
|
+
@options = options.dup
|
62
|
+
@options[:where] ||= []
|
63
|
+
@options[:domain] ||= base_class.domain_name
|
62
64
|
end
|
63
65
|
|
64
66
|
# @return [Class] Returns the AWS::Record::Base extending class that
|
65
67
|
# this scope will find records for.
|
66
68
|
attr_reader :base_class
|
67
69
|
|
70
|
+
def new attributes = {}
|
71
|
+
|
72
|
+
options = {}
|
73
|
+
options.merge!(attributes)
|
74
|
+
unless options.key?(:domain) or options.key?('domain')
|
75
|
+
options[:domain] = _domain
|
76
|
+
end
|
77
|
+
|
78
|
+
@options[:where].each do |conditions|
|
79
|
+
if conditions.size == 1 and conditions.first.is_a?(Hash)
|
80
|
+
options.merge!(conditions.first)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
base_class.new(options)
|
85
|
+
|
86
|
+
end
|
87
|
+
alias_method :build, :new
|
88
|
+
|
68
89
|
# @param [String] domain
|
69
90
|
# @return [Scope] Returns a scope for restricting the domain of subsequent
|
70
91
|
# scope operations
|
@@ -102,7 +123,7 @@ module AWS
|
|
102
123
|
|
103
124
|
case
|
104
125
|
when id_or_mode == :all then scope
|
105
|
-
when id_or_mode == :first then scope.limit(1).first
|
126
|
+
when id_or_mode == :first then scope.limit(1).to_a.first
|
106
127
|
else
|
107
128
|
base_class.find_by_id(id_or_mode, :domain => scope._domain)
|
108
129
|
end
|
@@ -120,6 +141,12 @@ module AWS
|
|
120
141
|
end
|
121
142
|
alias_method :size, :count
|
122
143
|
|
144
|
+
# @return [Record::Base,nil] Gets the first record from the domain
|
145
|
+
# and returns it, or returns nil if the domain is empty.
|
146
|
+
def first options = {}
|
147
|
+
_handle_options(options).find(:first)
|
148
|
+
end
|
149
|
+
|
123
150
|
# Applies conditions to the scope that limit which records are returned.
|
124
151
|
# Only those matching all given conditions will be returned.
|
125
152
|
#
|
@@ -149,7 +176,7 @@ module AWS
|
|
149
176
|
if conditions.empty?
|
150
177
|
raise ArgumentError, 'missing required condition'
|
151
178
|
end
|
152
|
-
_with(:where =>
|
179
|
+
_with(:where => @options[:where] + [conditions])
|
153
180
|
end
|
154
181
|
|
155
182
|
# Specifies how to sort records returned.
|
@@ -213,7 +240,7 @@ module AWS
|
|
213
240
|
items = _item_collection
|
214
241
|
|
215
242
|
items.select.each do |item_data|
|
216
|
-
obj = base_class.new
|
243
|
+
obj = base_class.new(:domain => _domain)
|
217
244
|
obj.send(:hydrate, item_data.name, item_data.attributes)
|
218
245
|
yield(obj)
|
219
246
|
end
|
@@ -287,7 +314,7 @@ module AWS
|
|
287
314
|
items = base_class.sdb_domain(_domain).items
|
288
315
|
items = items.order(*@options[:order]) if @options[:order]
|
289
316
|
items = items.limit(*@options[:limit]) if @options[:limit]
|
290
|
-
|
317
|
+
@options[:where].each do |where_condition|
|
291
318
|
items = items.where(*where_condition)
|
292
319
|
end
|
293
320
|
items
|