aws-sdk 1.2.6 → 1.3.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.
Files changed (60) hide show
  1. data/lib/aws.rb +2 -0
  2. data/lib/aws/api_config/DynamoDB-2011-12-05.yml +721 -0
  3. data/lib/aws/core.rb +10 -1
  4. data/lib/aws/core/client.rb +17 -12
  5. data/lib/aws/core/configuration.rb +13 -3
  6. data/lib/aws/core/configured_json_client_methods.rb +71 -0
  7. data/lib/aws/core/lazy_error_classes.rb +7 -2
  8. data/lib/aws/core/option_grammar.rb +67 -13
  9. data/lib/aws/core/resource.rb +9 -1
  10. data/lib/aws/core/session_signer.rb +95 -0
  11. data/lib/aws/dynamo_db.rb +169 -0
  12. data/lib/aws/dynamo_db/attribute_collection.rb +460 -0
  13. data/lib/aws/dynamo_db/batch_get.rb +206 -0
  14. data/lib/aws/dynamo_db/client.rb +119 -0
  15. data/lib/aws/dynamo_db/config.rb +20 -0
  16. data/lib/aws/dynamo_db/errors.rb +57 -0
  17. data/lib/aws/dynamo_db/expectations.rb +40 -0
  18. data/lib/aws/dynamo_db/item.rb +130 -0
  19. data/lib/aws/dynamo_db/item_collection.rb +837 -0
  20. data/lib/aws/{record/optimistic_locking.rb → dynamo_db/item_data.rb} +9 -12
  21. data/lib/aws/{record/attributes/boolean.rb → dynamo_db/keys.rb} +15 -23
  22. data/lib/aws/dynamo_db/primary_key_element.rb +47 -0
  23. data/lib/aws/dynamo_db/request.rb +78 -0
  24. data/lib/aws/{record/attributes/float.rb → dynamo_db/resource.rb} +10 -25
  25. data/lib/aws/dynamo_db/table.rb +418 -0
  26. data/lib/aws/dynamo_db/table_collection.rb +165 -0
  27. data/lib/aws/dynamo_db/types.rb +86 -0
  28. data/lib/aws/ec2/resource_tag_collection.rb +3 -1
  29. data/lib/aws/record.rb +36 -8
  30. data/lib/aws/record/abstract_base.rb +642 -0
  31. data/lib/aws/record/attributes.rb +384 -0
  32. data/lib/aws/record/dirty_tracking.rb +0 -1
  33. data/lib/aws/record/errors.rb +0 -8
  34. data/lib/aws/record/hash_model.rb +163 -0
  35. data/lib/aws/record/hash_model/attributes.rb +182 -0
  36. data/lib/aws/record/hash_model/finder_methods.rb +178 -0
  37. data/lib/aws/record/hash_model/scope.rb +108 -0
  38. data/lib/aws/record/model.rb +429 -0
  39. data/lib/aws/record/model/attributes.rb +377 -0
  40. data/lib/aws/record/model/finder_methods.rb +232 -0
  41. data/lib/aws/record/model/scope.rb +213 -0
  42. data/lib/aws/record/scope.rb +43 -169
  43. data/lib/aws/record/validations.rb +11 -11
  44. data/lib/aws/s3/client.rb +9 -6
  45. data/lib/aws/s3/object_collection.rb +1 -1
  46. data/lib/aws/simple_db/expect_condition_option.rb +1 -1
  47. data/lib/aws/simple_db/item_collection.rb +5 -3
  48. data/lib/aws/sts/client.rb +9 -0
  49. metadata +73 -30
  50. data/lib/aws/record/attribute.rb +0 -94
  51. data/lib/aws/record/attribute_macros.rb +0 -312
  52. data/lib/aws/record/attributes/date.rb +0 -89
  53. data/lib/aws/record/attributes/datetime.rb +0 -86
  54. data/lib/aws/record/attributes/integer.rb +0 -68
  55. data/lib/aws/record/attributes/sortable_float.rb +0 -60
  56. data/lib/aws/record/attributes/sortable_integer.rb +0 -95
  57. data/lib/aws/record/attributes/string.rb +0 -69
  58. data/lib/aws/record/base.rb +0 -828
  59. data/lib/aws/record/finder_methods.rb +0 -230
  60. data/lib/aws/record/scopes.rb +0 -55
@@ -11,24 +11,21 @@
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 'aws/simple_db'
15
- require 'aws/record/scope'
16
-
17
14
  module AWS
18
- module Record
15
+ class DynamoDB
19
16
 
20
- module OptimisticLocking
17
+ class ItemData
21
18
 
22
- def optimistic_locking attribute_name = :version_id
23
- attribute = integer_attr(attribute_name)
24
- @optimistic_locking_attr = attribute
25
- end
19
+ attr_reader :item
26
20
 
27
- # @private
28
- def optimistic_locking_attr
29
- @optimistic_locking_attr
21
+ attr_reader :attributes
22
+
23
+ def initialize(opts = {})
24
+ @item = opts[:item]
25
+ @attributes = opts[:attributes]
30
26
  end
31
27
 
32
28
  end
29
+
33
30
  end
34
31
  end
@@ -11,36 +11,28 @@
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 'aws/record/attribute'
15
-
16
14
  module AWS
17
- module Record
15
+ class DynamoDB
18
16
 
19
17
  # @private
20
- class BooleanAttribute < Attribute
18
+ module Keys
21
19
 
22
- def self.type_cast raw_value, options = {}
23
- case raw_value
24
- when nil then nil
25
- when '' then nil
26
- when false, 'false', '0', 0 then false
27
- else true
28
- end
29
- end
20
+ include Types
30
21
 
31
- def self.serialize boolean, options = {}
32
- case boolean
33
- when false then '0'
34
- when true then '1'
35
- else
36
- msg = "expected a boolean value, got #{boolean.class}"
37
- raise ArgumentError, msg
38
- end
22
+ # @return [Hash] Client options for identifying an item.
23
+ def item_key_options(item, extra = {})
24
+ key = item_key_hash(item)
25
+ extra.merge({ :table_name => item.table.name, :key => key })
39
26
  end
40
27
 
41
- # @private
42
- def self.allow_set?
43
- false
28
+ # @return [Hash] Returns just the hash key element and range key element
29
+ def item_key_hash item
30
+ item.table.assert_schema!
31
+ key = {}
32
+ key[:hash_key_element] = format_attribute_value(item.hash_value)
33
+ key[:range_key_element] = format_attribute_value(item.range_value) if
34
+ item.table.composite_key?
35
+ key
44
36
  end
45
37
 
46
38
  end
@@ -0,0 +1,47 @@
1
+ # Copyright 2011-2012 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
+ module AWS
15
+ class DynamoDB
16
+ class PrimaryKeyElement
17
+
18
+ attr_reader :name
19
+
20
+ attr_reader :type
21
+
22
+ ATTRIBUTE_TYPES = {
23
+ "S" => :string,
24
+ "N" => :number
25
+ }
26
+
27
+ def initialize(hash)
28
+ @name = hash[:name] || hash["AttributeName"]
29
+ @type = hash[:type] || ATTRIBUTE_TYPES[hash["AttributeType"]]
30
+ end
31
+
32
+ def self.from_description(description)
33
+ (name, type, *extra) = description.to_a.flatten
34
+
35
+ raise(ArgumentError,
36
+ "key element may contain only one name/type pair") unless
37
+ extra.empty?
38
+
39
+ raise ArgumentError, "unsupported type #{type.inspect}" unless
40
+ ATTRIBUTE_TYPES.values.include?(type.to_sym)
41
+
42
+ new(:name => name.to_s, :type => type)
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,78 @@
1
+ # Copyright 2011-2012 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 'openssl'
15
+ require 'time'
16
+
17
+ module AWS
18
+ class DynamoDB
19
+
20
+ class Request < Core::Http::Request
21
+
22
+ def initialize(*args)
23
+ super
24
+ headers["content-type"] = "application/json; amzn-1.0"
25
+ end
26
+
27
+ attr_accessor :body
28
+
29
+ def add_authorization!(signer)
30
+
31
+ self.access_key_id = signer.access_key_id
32
+
33
+ headers["x-amz-date"] ||= (headers["date"] ||= Time.now.rfc822)
34
+ headers["host"] ||= host
35
+
36
+ raise ArgumentError, "a security token is required" unless
37
+ signer.session_token
38
+
39
+ headers["x-amz-security-token"] = signer.session_token
40
+
41
+ # compute the authorization
42
+ request_hash = OpenSSL::Digest::SHA256.digest(string_to_sign)
43
+ signature = signer.sign(request_hash)
44
+ headers["x-amzn-authorization"] =
45
+ "AWS3 "+
46
+ "AWSAccessKeyId=#{signer.access_key_id},"+
47
+ "Algorithm=HmacSHA256,"+
48
+ "SignedHeaders=#{headers_to_sign.join(';')},"+
49
+ "Signature=#{signature}"
50
+ end
51
+
52
+ def headers_to_sign
53
+ headers.keys.select do |header|
54
+ header == "content-encoding" ||
55
+ header == "host" ||
56
+ header =~ /^x-amz/
57
+ end
58
+ end
59
+
60
+ def canonical_headers
61
+ headers_to_sign.map do |name|
62
+ value = headers[name]
63
+ "#{name.downcase.strip}:#{value.strip}\n"
64
+ end.sort.join
65
+ end
66
+
67
+ def string_to_sign
68
+ [http_method,
69
+ "/",
70
+ "",
71
+ canonical_headers,
72
+ body].join("\n")
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+ end
@@ -11,38 +11,23 @@
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 'aws/record/attribute'
15
-
16
14
  module AWS
17
- module Record
15
+ class DynamoDB
16
+ class Resource < Core::Resource
18
17
 
19
- # @private
20
- class FloatAttribute < Attribute
21
-
22
- def self.type_cast raw_value, options = {}
23
- case raw_value
24
- when nil then nil
25
- when '' then nil
26
- when Float then raw_value
27
- else
28
- raw_value.respond_to?(:to_f) ?
29
- raw_value.to_f :
30
- raw_value.to_s.to_f
31
- end
32
- end
18
+ # @private
19
+ def self.attribute name, options = {}
33
20
 
34
- def self.serialize float, options = {}
35
- expect(Float, float) do
36
- float.to_s
21
+ # DynamoDB attributes are all returned in UpperCamelCase, this
22
+ # converts the :snake_case name into the correct format.
23
+ unless options[:as]
24
+ options[:as] = name.to_s.split(/_/).map(&:capitalize).join
37
25
  end
38
- end
39
26
 
40
- # @private
41
- def self.allow_set?
42
- true
27
+ super(name, options)
28
+
43
29
  end
44
30
 
45
31
  end
46
-
47
32
  end
48
33
  end
@@ -0,0 +1,418 @@
1
+ # Copyright 2011-2012 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
+ module AWS
15
+ class DynamoDB
16
+
17
+ # Represents a DynamoDB table.
18
+ #
19
+ # == Working with Tables
20
+ #
21
+ # Dynamo DB allows you to organize data into tables. Tables have a
22
+ # unique name and a key schema. A key schema is comprised of a
23
+ # hash key and an optional range key.
24
+ #
25
+ # Dynamo DB automatically partitions the data contained in a table
26
+ # across multiple nodes so that the data throughput is not constrained
27
+ # by the scale of a single box. You can reserve the required throughput
28
+ # by specifying a number of reads and writes per second to support.
29
+ #
30
+ # == Creating a Table
31
+ #
32
+ # To get started you can create a table by supplying a name
33
+ # and the read/write capacity. A default schema of a hash_key
34
+ # ({:id => :string}) will be provided.
35
+ #
36
+ # dynamo_db = AWS::DynamoDB.new
37
+ # dynamo_db.tables.create('mytable', 10, 5)
38
+ #
39
+ # You can provide your own hash key and optional range key.
40
+ #
41
+ # dynamo_db.tables.create('comments', 10, 5,
42
+ # :hash_key => { :blog_post_id => :number },
43
+ # :range_key => { :comment_id => :number }
44
+ # )
45
+ #
46
+ # == Provisioning Throughput
47
+ #
48
+ # You must specify the desired read and write capacity when
49
+ # creating a table. After a table is created you can see what has
50
+ # been provisioned.
51
+ #
52
+ # table.read_capacity_units #=> 10
53
+ # table.write_capacity_units #=> 5
54
+ #
55
+ # To change these values, call {#provision_throughput}:
56
+ #
57
+ # table.provision_throughput :read_capacity_units => 100, :write_capacity_units => 100
58
+ #
59
+ # Please note that provisioned throughput can be decreased only once
60
+ # within a 24 hour period.
61
+ #
62
+ # == Table Status
63
+ #
64
+ # When you create or update a table the changes can take some time to
65
+ # apply. You can query the status of your table at any time:
66
+ #
67
+ # # creating a table can be a *very* slow operation
68
+ # table = dynamo_db.tables.create('mytable')
69
+ # sleep 1 while table.status == :creating
70
+ # table.status #=> :active
71
+ #
72
+ # @attr_reader [Time] created_at When the table was first creatd.
73
+ #
74
+ # @attr_reader [Symbol] status
75
+ #
76
+ # @attr [Integer] read_capacity_units
77
+ #
78
+ # @attr [Integer] write_capacity_units
79
+ #
80
+ # @attr [Time] throughput_last_increased_at
81
+ #
82
+ # @attr [Time] throughput_last_decreased_at
83
+ #
84
+ # @attr [PrimaryKeyElement] hash_key Returns the hash key element
85
+ # for this table.
86
+ #
87
+ # @attr [PrimaryKeyElement,nil] range_key Returns the range key
88
+ # element for this table, or nil if the table does not have a range
89
+ # key.
90
+ #
91
+ class Table < Resource
92
+
93
+ # @private
94
+ def initialize name, options = {}
95
+ @name = name
96
+ super
97
+ end
98
+
99
+ # @return [String] The name of this table.
100
+ attr_reader :name
101
+
102
+ attribute :creation_date_time, :timestamp => true, :static => true
103
+
104
+ alias_method :created_at, :creation_date_time
105
+
106
+ attribute :status, :as => 'TableStatus', :to_sym => true
107
+
108
+ attribute :throughput_last_increased_at,
109
+ :as => 'LastIncreaseDateTime',
110
+ :timestamp => true
111
+
112
+ attribute :throughput_last_decreased_at,
113
+ :as => 'LastDecreaseDateTime',
114
+ :timestamp => true
115
+
116
+ attribute :read_capacity_units
117
+
118
+ attribute :write_capacity_units
119
+
120
+ attribute :hash_key, :as => "HashKeyElement", :static => true do
121
+ translates_output {|v| PrimaryKeyElement.new(v) }
122
+ end
123
+
124
+ attribute :range_key, :as => "RangeKeyElement", :static => true do
125
+ translates_output {|v| PrimaryKeyElement.new(v) }
126
+ end
127
+ alias_method :range_key_without_schema_override, :range_key
128
+
129
+ populates_from :describe_table do |resp|
130
+ desc = resp.data['Table']
131
+ if desc['TableName'] == name
132
+ desc.merge(desc['ProvisionedThroughput']).merge(desc['KeySchema'])
133
+ end
134
+ end
135
+
136
+ populates_from :create_table, :delete_table do |resp|
137
+ desc = resp.data['TableDescription']
138
+ if desc['TableName'] == name
139
+ desc.merge(desc['ProvisionedThroughput']).merge(desc['KeySchema'])
140
+ end
141
+ end
142
+
143
+ # @return [PrimaryKeyElement]
144
+ def range_key
145
+ if schema_loaded?
146
+ static_attributes[:range_key]
147
+ else
148
+ range_key_without_schema_override
149
+ end
150
+ end
151
+
152
+ # @param [Hash] options
153
+ #
154
+ # @option options [Integer] :read_capacity_units
155
+ #
156
+ # @option options [Integer] :write_capacity_units
157
+ #
158
+ # @return [Hash] Returns a hash with the current throughput
159
+ # provisioning (+:read_capacity_units+ and +:write_capacity_units+).
160
+ #
161
+ def provision_throughput options = {}
162
+
163
+ options[:read_capacity_units] ||= read_capacity_units
164
+ options[:write_capacity_units] ||= write_capacity_units
165
+
166
+ client_opts = {}
167
+ client_opts[:table_name] = name
168
+ client_opts[:provisioned_throughput] = options
169
+ client.update_table(client_opts)
170
+
171
+ options
172
+
173
+ end
174
+
175
+ # @param [Integer] read_capacity_units
176
+ def read_capacity_units= read_capacity_units
177
+ provision_throughput(:read_capacity_units => read_capacity_units)
178
+ end
179
+
180
+ # @param [Integer] write_capacity_units
181
+ def write_capacity_units= write_capacity_units
182
+ provision_throughput(:write_capacity_units => write_capacity_units)
183
+ end
184
+
185
+ # @return [Boolean] Returns true if the table has a hash key and no
186
+ # range key.
187
+ def simple_key?
188
+ range_key.nil?
189
+ end
190
+
191
+ # @return [Boolean] Returns true if the table has both a hash key and
192
+ # a range key.
193
+ def composite_key?
194
+ !simple_key?
195
+ end
196
+ alias_method :has_range_key?, :composite_key?
197
+
198
+ # @return [Boolean] True if the table's schema information is
199
+ # loaded into memory.
200
+ #
201
+ # @note You must load the the table schema using {#load_schema},
202
+ # {#hash_key} or {#range_key} or configure it using
203
+ # {#hash_key=} and optionally {#range_key=} in order to work
204
+ # with DynamoDB items.
205
+ #
206
+ def schema_loaded?
207
+ static_attributes.include?(:hash_key)
208
+ end
209
+
210
+ # Raises an exception unless the table schema is loaded.
211
+ #
212
+ # @return [nil]
213
+ #
214
+ def assert_schema!
215
+ raise "table schema not loaded" unless schema_loaded?
216
+ end
217
+
218
+ # Loads the table's schema information into memory. This method
219
+ # should not be used in a high-volume code path, and is intended
220
+ # only as a convenience for exploring the API. In general you
221
+ # should configure a schema with {#hash_key=} and {#range_key=}
222
+ # before using the table.
223
+ #
224
+ # @note You must load the the table schema using {#load_schema},
225
+ # {#hash_key} or {#range_key} or configure it using
226
+ # {#hash_key=} and optionally {#range_key=} in order to work
227
+ # with DynamoDB items.
228
+ #
229
+ # @return self
230
+ def load_schema
231
+ hash_key
232
+ self
233
+ end
234
+
235
+ # Configures the hash key element of the table's key schema.
236
+ # This is the preferred way to load the table schema so that it
237
+ # can be used to work with DynamoDB items.
238
+ #
239
+ # # these are equivalent:
240
+ # table.hash_key = [:id, :string]
241
+ # table.hash_key = { :id => :string }
242
+ #
243
+ # @note For tables with composite primary keys, you must call
244
+ # this method first followed by {#range_key=} to configure the
245
+ # table schema.
246
+ #
247
+ # @param description A description of the hash key element. If
248
+ # this is a hash, it may contain a single mapping; the key is
249
+ # the name of the hash key attribute and the value is the type
250
+ # (+:string+ or +:number+). If it is an array, the first
251
+ # element is the name and the second element is the type.
252
+ #
253
+ def hash_key= description
254
+ static_attributes[:hash_key] =
255
+ PrimaryKeyElement.from_description(description)
256
+ end
257
+
258
+ # Configures the range key element of the table's key schema.
259
+ # This is the preferred way to load the table schema so that it
260
+ # can be used to work with DynamoDB items. This method is only
261
+ # valid if the table has a composite key schema, and it may only
262
+ # be called after {#hash_key=} has been used to configure the
263
+ # hash key element.
264
+ #
265
+ # # these are equivalent:
266
+ # table.range_key = [:id, :string]
267
+ # table.range_key = { :id => :string }
268
+ #
269
+ # @param description A description of the range key element. If
270
+ # this is a hash, it may contain a single mapping; the key is
271
+ # the name of the hash key attribute and the value is the type
272
+ # (+:string+ or +:number+). If it is an array, the first
273
+ # element is the name and the second element is the type.
274
+ #
275
+ def range_key= description
276
+ raise "attempted to set a range key without configuring a hash key first" unless
277
+ schema_loaded?
278
+
279
+ static_attributes[:range_key] =
280
+ PrimaryKeyElement.from_description(description)
281
+
282
+ end
283
+
284
+ # Deletes a table and all of its items. The table must be in an
285
+ # +:active+ state (see {#status}).
286
+ #
287
+ # @return [nil]
288
+ #
289
+ def delete
290
+ client.delete_table(:table_name => name)
291
+ nil
292
+ end
293
+
294
+ # @return [ItemCollection] Returns an object representing all the
295
+ # items in the table.
296
+ def items
297
+ ItemCollection.new(self)
298
+ end
299
+
300
+ # @return [Boolean] Returns true if the table exists. Note that a table
301
+ # exists even when it is in a +:deleting+ state; this method
302
+ # only returns false when DynamoDB no longer returns any
303
+ # information about the table.
304
+ def exists?
305
+ get_resource
306
+ true
307
+ rescue Errors::ResourceNotFoundException
308
+ false
309
+ end
310
+
311
+ # Requets a list of attributes for a list of items in the same table.
312
+ #
313
+ # If you want to request a list of attributes for items that span
314
+ # multiple tables, see {DynamoDB#batch_get}.
315
+ #
316
+ # You can call this method in two forms:
317
+ #
318
+ # # block form
319
+ # table.batch_get(:all, items) do |attributes|
320
+ # # yeilds one hash of attribute names/values for each item
321
+ # puts attributes.to_yaml
322
+ # end
323
+ #
324
+ # # enumerable return value
325
+ # attribute_hashes = table.batch_get(:all, items)
326
+ # attribute_hashes.each do |attributes|
327
+ # # ...
328
+ # end
329
+ #
330
+ # @note This method does not require the table schema to be loaded.
331
+ #
332
+ # == Attributes
333
+ #
334
+ # You can specify the list of attributes to request in 3 ways:
335
+ #
336
+ # * The symbol +:all+ (to recieve all attributes)
337
+ # * A single attribute name (e.g. 'size')
338
+ # * An array of attribute names (e.g. ['size', 'color'])
339
+ #
340
+ # A few exmaples:
341
+ #
342
+ # # get all attributes
343
+ # table.batch_get(:all, items)
344
+ #
345
+ # # only get the 'color' attribute
346
+ # table.batch_get('color', items)
347
+ #
348
+ # # get 'color' and 'size' attributes
349
+ # table.batch_get(['color', size'], items)
350
+ #
351
+ # == Items
352
+ #
353
+ # You must specify an array of items to fetch attributes for.
354
+ # The +items+ param should always be an array with:
355
+ #
356
+ # * String hash key values
357
+ # * Arrays of string hash key and range key values
358
+ # * Item objects
359
+ #
360
+ # Here are a few examples:
361
+ #
362
+ # # items as a list of hash key values
363
+ # items = %w(hashkey1 hashkey2 hashkey3)
364
+ # table.batch_get(:all, items)
365
+ #
366
+ # # items as a list of hash and range key values
367
+ # items = [['hashkey1', 'rangekey2'], ['hashkey1', 'rangekey2']]
368
+ # table.batch_get(:all, items)
369
+ #
370
+ # # items as a list of Item objects
371
+ # items = []
372
+ # items << Item.new(table, 'hashkey1')
373
+ # items << Item.new(table, 'hashkey2')
374
+ # table.batch_get(:all, items)
375
+ #
376
+ # Please note that you must provide both hash and range keys for tables
377
+ # that include a range key in the schema.
378
+ #
379
+ # @param [:all, String, Array<String>] attributes The list of
380
+ # attributes you want to fetch for each item. +attributes+ may be:
381
+ #
382
+ # * the symbol +:all+
383
+ # * a single attribute name string
384
+ # * an array of attribute name strings
385
+ #
386
+ # @param [Mixed] items A list of 2 or more items to fetch attributes
387
+ # for. You may provide +items+ as:
388
+ #
389
+ # * an array of hash key value strings
390
+ # * an array of hash and range key value pairs (nested arrays)
391
+ # * an array of {Item} objects
392
+ #
393
+ # @yield [Hash] Yields a hash of attributes for each item.
394
+ #
395
+ # @return [Enumerable] Returns an enumerable object that yields
396
+ # hashes of attributes.
397
+ #
398
+ def batch_get attributes, items, &block
399
+ batch = BatchGet.new(:config => config)
400
+ batch.table(name, attributes, items)
401
+ enum = batch.to_enum(:each_attributes)
402
+ block_given? ? enum.each(&block) : enum
403
+ end
404
+
405
+ protected
406
+ def get_resource attribute_name = nil
407
+ client.describe_table(resource_options)
408
+ end
409
+
410
+ protected
411
+ def resource_identifiers
412
+ [[:table_name, name]]
413
+ end
414
+
415
+ end
416
+
417
+ end
418
+ end