aws-record 1.0.0.pre.7 → 1.0.0.pre.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 808122fbcc8d09789f250b6ab5f7bfa4af8a511f
4
- data.tar.gz: 006ed1f3c955fe8370cd4d2ae81adb17195cc77e
3
+ metadata.gz: 529b219269ff7db06904ac8069cd9d03c5a39b2f
4
+ data.tar.gz: de636bcd9279040598617f1cad6b9601f583a4fc
5
5
  SHA512:
6
- metadata.gz: 6586ed1a3add7fbe31dcd37b59f3798a0671b1ec25c0886f68c8c7545f5798fb4d6639c7c0ea14206ccba1d29b75d505ab34c211540026963a4c675542a37b4c
7
- data.tar.gz: ab2ecaf0359165f4c179af7df4d96bd142ca29f630a65bc9c9985fd7be8987f44fec050b41342ee6eec8ff1d0f5592b93d36f460b170f6943eab6c68d8b410fd
6
+ metadata.gz: 0466dcde49ea6a9f0a026b806fba07f3e4152d7d115c8c6f89bcf1955903cd92ada636e51b72c161a8cb3f14178948514bf1e5bc11aa72995541f69559b81255
7
+ data.tar.gz: be394920aba460d6f28d1087077a13f17e25c4f07eb93f24e4ccdf1a7abb222f8d946db3766e6817966659c524d0e550a9273b95be657434bee5e82ba088697b
@@ -13,6 +13,12 @@
13
13
 
14
14
  module Aws
15
15
  module Record
16
+
17
+ # This class provides helper methods for +Aws::Record+ attributes. These
18
+ # include marshalers for type casting of item attributes, the Amazon
19
+ # DynamoDB type for use in certain table and item operation calls, and the
20
+ # ability to define a database name that is separate from the name used
21
+ # within the model class and item instances.
16
22
  class Attribute
17
23
 
18
24
  attr_reader :name, :database_name, :dynamodb_type
@@ -66,6 +72,8 @@ module Aws
66
72
 
67
73
  end
68
74
 
75
+ # This is an identity marshaler, which performs no changes for type casting
76
+ # or serialization. It is generally not recommended for use.
69
77
  module DefaultMarshaler
70
78
  def self.type_cast(raw_value, options = {})
71
79
  raw_value
@@ -22,8 +22,28 @@ module Aws
22
22
  sub_class.instance_variable_set("@storage_attributes", {})
23
23
  end
24
24
 
25
- def initialize
25
+ # @example Usage Example
26
+ # class MyModel
27
+ # include Aws::Record
28
+ # integer_attr :id, hash_key: true
29
+ # string_attr :name, range_key: true
30
+ # string_attr :body
31
+ # end
32
+ #
33
+ # item = MyModel.new(id: 1, name: "Quick Create")
34
+ #
35
+ # Base initialization method for a new item. Optionally, allows you to
36
+ # provide initial attribute values for the model. You do not need to
37
+ # provide all, or even any, attributes at item creation time.
38
+ #
39
+ # @param [Hash] attr_values Attribute symbol/value pairs for any initial
40
+ # attribute values you wish to set.
41
+ # @return [Aws::Record] An item instance for your model.
42
+ def initialize(attr_values = {})
26
43
  @data = {}
44
+ attr_values.each do |attr_name, attr_value|
45
+ send("#{attr_name}=", attr_value)
46
+ end
27
47
  end
28
48
 
29
49
  # Returns a hash representation of the attribute data.
@@ -23,7 +23,8 @@ module Aws
23
23
  #
24
24
  # @override initialize(*)
25
25
  def initialize(*)
26
- super.tap { @dirty_data = {} }
26
+ @dirty_data = {}
27
+ super
27
28
  end
28
29
 
29
30
  # Returns +true+ if the specified attribute has any dirty changes, +false+ otherwise.
@@ -15,16 +15,42 @@ module Aws
15
15
  module Record
16
16
  module Errors
17
17
 
18
+ # RecordErrors relate to the persistence of items. They include both
19
+ # client errors and certain validation errors.
18
20
  class RecordError < RuntimeError; end
19
21
 
22
+ # Raised when a required key attribute is missing from an item when
23
+ # persistence is attempted.
20
24
  class KeyMissing < RecordError; end
25
+
26
+ # Raised when you attempt to load a record from the database, but it does
27
+ # not exist there.
21
28
  class NotFound < RecordError; end
22
- class ItemAlreadyExists < RecordError; end
29
+
30
+ # Raised when a conditional write fails.
31
+ class ConditionalWriteFailed < RecordError; end
32
+
33
+ # Raised when a validation hook call to +:valid?+ fails.
23
34
  class ValidationError < RecordError; end
24
35
 
36
+ # Raised when an attribute is defined that has a name collision with an
37
+ # existing attribute.
25
38
  class NameCollision < RuntimeError; end
39
+
40
+ # Raised when you attempt to create an attribute which has a name that
41
+ # conflicts with reserved names (generally, defined method names). If you
42
+ # see this error, you should change the attribute name in the model. If
43
+ # the database uses this name, you can take advantage of the
44
+ # +:database_attribute_name+ option in
45
+ # {Aws::Record::Attributes::ClassMethods#attr #attr}
26
46
  class ReservedName < RuntimeError; end
47
+
48
+ # Raised when you attempt a table migration and your model class is
49
+ # invalid.
27
50
  class InvalidModel < RuntimeError; end
51
+
52
+ # Raised when you attempt update/delete operations on a table that does
53
+ # not exist.
28
54
  class TableDoesNotExist < RuntimeError; end
29
55
 
30
56
  end
@@ -1,3 +1,16 @@
1
+ # Copyright 2015-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
+ # use this file except in compliance with the License. A copy of the License is
5
+ # located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is distributed on
10
+ # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
+ # or implied. See the License for the specific language governing permissions
12
+ # and limitations under the License.
13
+
1
14
  module Aws
2
15
  module Record
3
16
  class ItemCollection
@@ -39,8 +39,8 @@ module Aws
39
39
  # default, will either perform a conditional put or an update call.
40
40
  # @raise [Aws::Record::Errors::KeyMissing] if a required key attribute
41
41
  # does not have a value within this item instance.
42
- # @raise [Aws::Record::Errors::ItemAlreadyExists] if a conditional put
43
- # fails because the item exists on the remote end.
42
+ # @raise [Aws::Record::Errors::ConditionalWriteFailed] if a conditional
43
+ # put fails because the item exists on the remote end.
44
44
  # @raise [Aws::Record::Errors::ValidationError] if the item responds to
45
45
  # +:valid?+ and that call returned false. In such a case, checking root
46
46
  # cause is dependent on the validation library you are using.
@@ -122,11 +122,10 @@ module Aws
122
122
  begin
123
123
  dynamodb_client.put_item(put_opts)
124
124
  rescue Aws::DynamoDB::Errors::ConditionalCheckFailedException => e
125
- raise Errors::ItemAlreadyExists.new(
126
- "Conditional #put_item call failed, an item with the same key"\
127
- " already exists in the table. Either load and update this"\
128
- " item, or include the :force option to clobber the remote"\
129
- " item."
125
+ raise Errors::ConditionalWriteFailed.new(
126
+ "Conditional #put_item call failed! Check that conditional write"\
127
+ " conditions are met, or include the :force option to clobber"\
128
+ " the remote item."
130
129
  )
131
130
  end
132
131
  else
@@ -237,7 +236,7 @@ module Aws
237
236
  "Missing required key #{attr_sym} in #{opts}"
238
237
  )
239
238
  end
240
- attr_name = attr_sym.to_s
239
+ attr_name = attributes[attr_sym].database_name
241
240
  key[attr_name] = attributes[attr_sym].serialize(opts[attr_sym])
242
241
  end
243
242
  request_opts = {
@@ -252,6 +251,69 @@ module Aws
252
251
  end
253
252
  end
254
253
 
254
+ # @example Usage Example
255
+ # class MyModel
256
+ # include Aws::Record
257
+ # integer_attr :id, hash_key: true
258
+ # string_attr :name, range_key: true
259
+ # string_attr :body
260
+ # boolean_attr :sir_not_appearing_in_this_example
261
+ # end
262
+ #
263
+ # MyModel.update(id: 1, name: "First", body: "Hello!")
264
+ #
265
+ # Performs an
266
+ # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#update_item-instance_method Aws::DynamoDB::Client#update_item}
267
+ # call immediately on the table, using the attribute key/value pairs
268
+ # provided.
269
+ #
270
+ # @param [Hash] opts attribute-value pairs for the update operation you
271
+ # wish to perform. You must include all key attributes for a valid
272
+ # call, then you may optionally include any other attributes that you
273
+ # wish to update.
274
+ # @raise [Aws::Record::Errors::KeyMissing] if your option parameters do
275
+ # not include all table keys.
276
+ def update(opts)
277
+ key = {}
278
+ updates = {}
279
+ @keys.each_value do |attr_sym|
280
+ unless value = opts.delete(attr_sym)
281
+ raise Errors::KeyMissing.new(
282
+ "Missing required key #{attr_sym} in #{opts}"
283
+ )
284
+ end
285
+ attr_name = attributes[attr_sym].database_name
286
+ key[attr_name] = attributes[attr_sym].serialize(value)
287
+ end
288
+ request_opts = {
289
+ table_name: table_name,
290
+ key: key
291
+ }
292
+ update_expressions = []
293
+ exp_attr_names = {}
294
+ exp_attr_values = {}
295
+ name_sub_token = "A"
296
+ value_sub_token = "a"
297
+ opts.each do |attr_sym, value|
298
+ name_sub = "#" + name_sub_token
299
+ value_sub = ":" + value_sub_token
300
+ name_sub_token = name_sub_token.succ
301
+ value_sub_token = value_sub_token.succ
302
+
303
+ attr_name = attributes[attr_sym].database_name
304
+ update_expressions << "#{name_sub} = #{value_sub}"
305
+ exp_attr_names[name_sub] = attr_name
306
+ exp_attr_values[value_sub] = attributes[attr_sym].serialize(value)
307
+ end
308
+ unless update_expressions.empty?
309
+ uex = "SET " + update_expressions.join(", ")
310
+ request_opts[:update_expression] = uex
311
+ request_opts[:expression_attribute_names] = exp_attr_names
312
+ request_opts[:expression_attribute_values] = exp_attr_values
313
+ end
314
+ dynamodb_client.update_item(request_opts)
315
+ end
316
+
255
317
  private
256
318
  def build_item_from_resp(resp)
257
319
  record = new
@@ -27,6 +27,35 @@ module Aws
27
27
  # populating the +:table_name+ parameter from the model class, and
28
28
  # combining this with the other parameters you provide.
29
29
  #
30
+ # @example A query with key and filter expressions:
31
+ # # Example model class
32
+ # class ExampleTable
33
+ # include Aws::Record
34
+ # string_attr :uuid, hash_key: true
35
+ # integer_attr :id, range_key: true
36
+ # string_attr :body
37
+ # end
38
+ #
39
+ # query = ExampleTable.query(
40
+ # key_condition_expression: "#H = :h AND #R > :r",
41
+ # filter_expression: "contains(#B, :b)",
42
+ # expression_attribute_names: {
43
+ # "#H" => "uuid",
44
+ # "#R" => "id",
45
+ # "#B" => "body"
46
+ # },
47
+ # expression_attribute_values: {
48
+ # ":h" => "123456789uuid987654321",
49
+ # ":r" => 100,
50
+ # ":b" => "some substring"
51
+ # }
52
+ # )
53
+ #
54
+ # # You can enumerate over your results.
55
+ # query.each do |r|
56
+ # puts "UUID: #{r.uuid}\nID: #{r.id}\nBODY: #{r.body}\n"
57
+ # end
58
+ #
30
59
  # @param [Hash] opts options to pass on to the client call to +#query+.
31
60
  # See the documentation above in the AWS SDK for Ruby V2.
32
61
  # @return [Aws::Record::ItemCollection] an enumerable collection of the
@@ -41,6 +70,30 @@ module Aws
41
70
  # populating the +:table_name+ parameter from the model class, and
42
71
  # combining this with the other parameters you provide.
43
72
  #
73
+ # @example A scan with a filter expression:
74
+ # # Example model class
75
+ # class ExampleTable
76
+ # include Aws::Record
77
+ # string_attr :uuid, hash_key: true
78
+ # integer_attr :id, range_key: true
79
+ # string_attr :body
80
+ # end
81
+ #
82
+ # scan = ExampleTable.scan(
83
+ # filter_expression: "contains(#B, :b)",
84
+ # expression_attribute_names: {
85
+ # "#B" => "body"
86
+ # },
87
+ # expression_attribute_values: {
88
+ # ":b" => "some substring"
89
+ # }
90
+ # )
91
+ #
92
+ # # You can enumerate over your results.
93
+ # scan.each do |r|
94
+ # puts "UUID: #{r.uuid}\nID: #{r.id}\nBODY: #{r.body}\n"
95
+ # end
96
+ #
44
97
  # @param [Hash] opts options to pass on to the client call to +#scan+.
45
98
  # See the documentation above in the AWS SDK for Ruby V2.
46
99
  # @return [Aws::Record::ItemCollection] an enumerable collection of the
@@ -29,7 +29,7 @@ module Aws
29
29
  # class. If this option is not included, a client will be constructed for
30
30
  # you with default parameters.
31
31
  def initialize(model, opts = {})
32
- assert_model_valid(model)
32
+ _assert_model_valid(model)
33
33
  @model = model
34
34
  @client = opts[:client] || Aws::DynamoDB::Client.new
35
35
  end
@@ -39,6 +39,20 @@ module Aws
39
39
  # populating the attribute definitions and key schema based on your model
40
40
  # class, as well as passing through other parameters as provided by you.
41
41
  #
42
+ # @example Creating a table with a global secondary index named +:gsi+
43
+ # migration.create!(
44
+ # provisioned_throughput: {
45
+ # read_capacity_units: 5,
46
+ # write_capacity_units: 2
47
+ # },
48
+ # global_secondary_index_throughput: {
49
+ # gsi: {
50
+ # read_capacity_units: 3,
51
+ # write_capacity_units: 1
52
+ # }
53
+ # }
54
+ # )
55
+ #
42
56
  # @param [Hash] opts options to pass on to the client call to
43
57
  # +#create_table+. See the documentation above in the AWS SDK for Ruby
44
58
  # V2.
@@ -53,8 +67,8 @@ module Aws
53
67
  gsit = opts.delete(:global_secondary_index_throughput)
54
68
  create_opts = opts.merge({
55
69
  table_name: @model.table_name,
56
- attribute_definitions: attribute_definitions,
57
- key_schema: key_schema
70
+ attribute_definitions: _attribute_definitions,
71
+ key_schema: _key_schema
58
72
  })
59
73
  if lsis = @model.local_secondary_indexes_for_migration
60
74
  create_opts[:local_secondary_indexes] = lsis
@@ -117,25 +131,25 @@ module Aws
117
131
  end
118
132
 
119
133
  private
120
- def assert_model_valid(model)
121
- assert_required_include(model)
122
- assert_keys(model)
134
+ def _assert_model_valid(model)
135
+ _assert_required_include(model)
136
+ _assert_keys(model)
123
137
  end
124
138
 
125
- def assert_required_include(model)
139
+ def _assert_required_include(model)
126
140
  unless model.include?(::Aws::Record)
127
141
  raise Errors::InvalidModel.new("Table models must include Aws::Record")
128
142
  end
129
143
  end
130
144
 
131
- def assert_keys(model)
145
+ def _assert_keys(model)
132
146
  if model.hash_key.nil?
133
147
  raise Errors::InvalidModel.new("Table models must include a hash key")
134
148
  end
135
149
  end
136
150
 
137
- def attribute_definitions
138
- keys.map do |type, attr|
151
+ def _attribute_definitions
152
+ _keys.map do |type, attr|
139
153
  {
140
154
  attribute_name: attr.database_name,
141
155
  attribute_type: attr.dynamodb_type
@@ -183,8 +197,8 @@ module Aws
183
197
  ret
184
198
  end
185
199
 
186
- def key_schema
187
- keys.map do |type, attr|
200
+ def _key_schema
201
+ _keys.map do |type, attr|
188
202
  {
189
203
  attribute_name: attr.database_name,
190
204
  key_type: type == :hash ? "HASH" : "RANGE"
@@ -192,7 +206,7 @@ module Aws
192
206
  end
193
207
  end
194
208
 
195
- def keys
209
+ def _keys
196
210
  @model.keys.inject({}) do |acc, (type, name)|
197
211
  acc[type] = @model.attributes[name]
198
212
  acc
@@ -13,6 +13,6 @@
13
13
 
14
14
  module Aws
15
15
  module Record
16
- VERSION = '1.0.0.pre.7'
16
+ VERSION = '1.0.0.pre.8'
17
17
  end
18
18
  end
@@ -12,6 +12,22 @@
12
12
  # and limitations under the License.
13
13
 
14
14
  module Aws
15
+
16
+ # +Aws::Record+ is the module you include in your model classes in order to
17
+ # decorate them with the Amazon DynamoDB integration methods provided by this
18
+ # library. Methods you can use are shown below, in sub-modules organized by
19
+ # functionality.
20
+ #
21
+ # @example A class definition using +Aws::Record+
22
+ # class MyModel
23
+ # include Aws::Record
24
+ # string_attr :uuid, hash_key: true
25
+ # integer_attr :post_id, range_key: true
26
+ # boolean_attr :is_active
27
+ # datetime_attr :created_at
28
+ # string_set_attr :tags
29
+ # map_attr :metadata
30
+ # end
15
31
  module Record
16
32
  # @!parse extend RecordClassMethods
17
33
  # @!parse include Attributes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre.7
4
+ version: 1.0.0.pre.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amazon Web Services
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-21 00:00:00.000000000 Z
11
+ date: 2016-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-resources