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

Sign up to get free protection for your applications and to get access to all the features.
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