aws-record 1.0.0.pre.1 → 1.0.0.pre.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/aws-record.rb +22 -6
- data/lib/aws-record/record.rb +107 -4
- data/lib/aws-record/record/attribute.rb +50 -1
- data/lib/aws-record/record/attributes.rb +56 -38
- data/lib/aws-record/record/attributes/boolean_marshaler.rb +13 -0
- data/lib/aws-record/record/attributes/date_marshaler.rb +13 -0
- data/lib/aws-record/record/attributes/date_time_marshaler.rb +13 -0
- data/lib/aws-record/record/attributes/float_marshaler.rb +13 -0
- data/lib/aws-record/record/attributes/integer_marshaler.rb +13 -0
- data/lib/aws-record/record/attributes/string_marshaler.rb +13 -0
- data/lib/aws-record/record/errors.rb +13 -0
- data/lib/aws-record/record/item_collection.rb +42 -0
- data/lib/aws-record/record/item_operations.rb +40 -8
- data/lib/aws-record/record/query.rb +56 -0
- data/lib/aws-record/record/secondary_indexes.rb +156 -0
- data/lib/aws-record/record/table_migration.rb +116 -2
- data/lib/aws-record/record/version.rb +14 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f411d61078b7eeb8fbd7081d51c3f41b1c9116ca
|
4
|
+
data.tar.gz: 073b4953897897aba7298b5ba90e8050a015fcde
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba35bcbfadff82862f5170c428d213c23157307c07ef9325263d877596cb2c32e0a9b65ee150e7492538b67f422c90d3f8112b5d51def09508e55c974ae6944f
|
7
|
+
data.tar.gz: 9301a70e55fae642dd83c814720ab78543dae3ec12e1c806df096326009308dce7fbb2666a1a8610cd18c69418be9e70d93649b1d2780b42523fb9361c7e04a6
|
data/lib/aws-record.rb
CHANGED
@@ -1,15 +1,31 @@
|
|
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
|
require 'aws-sdk-resources'
|
2
15
|
|
3
16
|
module Aws
|
4
17
|
autoload :Record, 'aws-record/record'
|
5
18
|
|
6
19
|
module Record
|
7
|
-
autoload :Attribute,
|
8
|
-
autoload :Attributes,
|
9
|
-
autoload :Errors,
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
20
|
+
autoload :Attribute, 'aws-record/record/attribute'
|
21
|
+
autoload :Attributes, 'aws-record/record/attributes'
|
22
|
+
autoload :Errors, 'aws-record/record/errors'
|
23
|
+
autoload :ItemCollection, 'aws-record/record/item_collection'
|
24
|
+
autoload :ItemOperations, 'aws-record/record/item_operations'
|
25
|
+
autoload :Query, 'aws-record/record/query'
|
26
|
+
autoload :SecondaryIndexes, 'aws-record/record/secondary_indexes'
|
27
|
+
autoload :TableMigration, 'aws-record/record/table_migration'
|
28
|
+
autoload :VERSION, 'aws-record/record/version'
|
13
29
|
|
14
30
|
module Attributes
|
15
31
|
autoload :StringMarshaler, 'aws-record/record/attributes/string_marshaler'
|
data/lib/aws-record/record.rb
CHANGED
@@ -1,9 +1,33 @@
|
|
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
|
16
|
+
|
17
|
+
# Usage of {Aws::Record} requires only that you include this module. This
|
18
|
+
# method will then pull in the other default modules.
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# class MyTable
|
22
|
+
# include Aws::Record
|
23
|
+
# # Attribute definitions go here...
|
24
|
+
# end
|
3
25
|
def self.included(sub_class)
|
4
|
-
sub_class.extend
|
5
|
-
sub_class.include
|
6
|
-
sub_class.include
|
26
|
+
sub_class.send(:extend, RecordClassMethods)
|
27
|
+
sub_class.send(:include, Attributes)
|
28
|
+
sub_class.send(:include, ItemOperations)
|
29
|
+
sub_class.send(:include, Query)
|
30
|
+
sub_class.send(:include, SecondaryIndexes)
|
7
31
|
end
|
8
32
|
|
9
33
|
private
|
@@ -12,6 +36,25 @@ module Aws
|
|
12
36
|
end
|
13
37
|
|
14
38
|
module RecordClassMethods
|
39
|
+
|
40
|
+
# Returns the Amazon DynamoDB table name for this model class.
|
41
|
+
#
|
42
|
+
# By default, this will simply be the name of the class. However, you can
|
43
|
+
# also define a custom table name at the class level to be anything that
|
44
|
+
# you want.
|
45
|
+
#
|
46
|
+
# @example
|
47
|
+
# class MyTable
|
48
|
+
# include Aws::Record
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# class MyTableTest
|
52
|
+
# include Aws::Record
|
53
|
+
# set_table_name "test_MyTable"
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# MyTable.table_name # => "MyTable"
|
57
|
+
# MyOtherTable.table_name # => "test_MyTable"
|
15
58
|
def table_name
|
16
59
|
if @table_name
|
17
60
|
@table_name
|
@@ -20,10 +63,33 @@ module Aws
|
|
20
63
|
end
|
21
64
|
end
|
22
65
|
|
66
|
+
# Allows you to set a custom Amazon DynamoDB table name for this model
|
67
|
+
# class.
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# class MyTable
|
71
|
+
# include Aws::Record
|
72
|
+
# set_table_name "prod_MyTable"
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# class MyTableTest
|
76
|
+
# include Aws::Record
|
77
|
+
# set_table_name "test_MyTable"
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# MyTable.table_name # => "prod_MyTable"
|
81
|
+
# MyOtherTable.table_name # => "test_MyTable"
|
23
82
|
def set_table_name(name)
|
24
83
|
@table_name = name
|
25
84
|
end
|
26
85
|
|
86
|
+
# Fetches the table's provisioned throughput from the associated Amazon
|
87
|
+
# DynamoDB table.
|
88
|
+
#
|
89
|
+
# @return [Hash] a hash containing the +:read_capacity_units+ and
|
90
|
+
# +:write_capacity_units+ of your remote table.
|
91
|
+
# @raise [Aws::Record::Errors::TableDoesNotExist] if the table name does
|
92
|
+
# not exist in DynamoDB.
|
27
93
|
def provisioned_throughput
|
28
94
|
begin
|
29
95
|
resp = dynamodb_client.describe_table(table_name: @table_name)
|
@@ -37,6 +103,9 @@ module Aws
|
|
37
103
|
end
|
38
104
|
end
|
39
105
|
|
106
|
+
# Checks if the model's table name exists in Amazon DynamoDB.
|
107
|
+
#
|
108
|
+
# @return [Boolean] true if the table does exist, false if it does not.
|
40
109
|
def table_exists?
|
41
110
|
begin
|
42
111
|
resp = dynamodb_client.describe_table(table_name: @table_name)
|
@@ -50,16 +119,50 @@ module Aws
|
|
50
119
|
end
|
51
120
|
end
|
52
121
|
|
122
|
+
# Configures the Amazon DynamoDB client used by this class and all
|
123
|
+
# instances of this class.
|
124
|
+
#
|
125
|
+
# Please note that this method is also called internally when you first
|
126
|
+
# attempt to perform an operation against the remote end, if you have not
|
127
|
+
# already configured a client. As such, please read and understand the
|
128
|
+
# documentation in the AWS SDK for Ruby V2 around
|
129
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/index.html#Configuration configuration}
|
130
|
+
# to ensure you understand how default configuration behavior works. When
|
131
|
+
# in doubt, call this method to ensure your client is configured the way
|
132
|
+
# you want it to be configured.
|
133
|
+
#
|
134
|
+
# @param [Hash] opts the options you wish to use to create the client.
|
135
|
+
# Note that if you include the option +:client+, all other options
|
136
|
+
# will be ignored. See the documentation for other options in the
|
137
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#initialize-instance_method AWS SDK for Ruby V2}.
|
138
|
+
# @option opts [Aws::DynamoDB::Client] :client allows you to pass in your
|
139
|
+
# own pre-configured client.
|
53
140
|
def configure_client(opts = {})
|
54
141
|
provided_client = opts.delete(:client)
|
55
|
-
opts[:user_agent_suffix] =
|
142
|
+
opts[:user_agent_suffix] = _user_agent(opts.delete(:user_agent_suffix))
|
56
143
|
client = provided_client || Aws::DynamoDB::Client.new(opts)
|
57
144
|
@dynamodb_client = client
|
58
145
|
end
|
59
146
|
|
147
|
+
# Gets the
|
148
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html Aws::DynamoDB::Client}
|
149
|
+
# instance that this model uses. When called for the first time, if
|
150
|
+
# {#configure_client} has not yet been called, will configure a new client
|
151
|
+
# for you with default parameters.
|
152
|
+
#
|
153
|
+
# @return [Aws::DynamoDB::Client] the Amazon DynamoDB client instance.
|
60
154
|
def dynamodb_client
|
61
155
|
@dynamodb_client ||= configure_client
|
62
156
|
end
|
157
|
+
|
158
|
+
private
|
159
|
+
def _user_agent(custom)
|
160
|
+
if custom
|
161
|
+
custom
|
162
|
+
else
|
163
|
+
" aws-record/#{VERSION}"
|
164
|
+
end
|
165
|
+
end
|
63
166
|
end
|
64
167
|
end
|
65
168
|
end
|
@@ -1,9 +1,40 @@
|
|
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 Attribute
|
4
17
|
|
5
18
|
attr_reader :name, :database_name, :dynamodb_type
|
6
19
|
|
20
|
+
# @param [Symbol] name Name of the attribute. It should be a name that is
|
21
|
+
# safe to use as a method.
|
22
|
+
# @param [Hash] options
|
23
|
+
# @option options [Marshaler] :marshaler The marshaler for this attribute.
|
24
|
+
# So long as you provide a marshaler which implements `#type_cast` and
|
25
|
+
# `#serialize` that consume raw values as expected, you can bring your
|
26
|
+
# own marshaler type.
|
27
|
+
# @option options [Array] :validators An array of validator classes that
|
28
|
+
# will be run when an attribute is checked for validity.
|
29
|
+
# @option options [String] :database_attribute_name Optional attribute
|
30
|
+
# used to specify a different name for database persistence than the
|
31
|
+
# `name` parameter. Must be unique (you can't have overlap between
|
32
|
+
# database attribute names and the names of other attributes).
|
33
|
+
# @option options [String] :dynamodb_type Generally used for keys and
|
34
|
+
# index attributes, one of "S", "N", "B", "BOOL", "SS", "NS", "BS",
|
35
|
+
# "M", "L". Optional if this attribute will never be used for a key or
|
36
|
+
# secondary index, but most convenience methods for setting attributes
|
37
|
+
# will provide this.
|
7
38
|
def initialize(name, options = {})
|
8
39
|
@name = name
|
9
40
|
@database_name = options[:database_attribute_name] || name.to_s
|
@@ -12,14 +43,31 @@ module Aws
|
|
12
43
|
@validators = options[:validators] || []
|
13
44
|
end
|
14
45
|
|
46
|
+
# Attempts to type cast a raw value into the attribute's type. This call
|
47
|
+
# will forward the raw value to this attribute's marshaler class.
|
48
|
+
#
|
49
|
+
# @return [Object] the type cast object. Return type is dependent on the
|
50
|
+
# marshaler used. See your attribute's marshaler class for details.
|
15
51
|
def type_cast(raw_value)
|
16
52
|
@marshaler.type_cast(raw_value)
|
17
53
|
end
|
18
54
|
|
55
|
+
# Attempts to serialize a raw value into the attribute's serialized
|
56
|
+
# storage type. This call will forward the raw value to this attribute's
|
57
|
+
# marshaler class.
|
58
|
+
#
|
59
|
+
# @return [Object] the serialized object. Return type is dependent on the
|
60
|
+
# marshaler used. See your attribute's marshaler class for details.
|
19
61
|
def serialize(raw_value)
|
20
62
|
@marshaler.serialize(raw_value)
|
21
63
|
end
|
22
64
|
|
65
|
+
# Checks if the raw value is valid for this attribute. This is done by
|
66
|
+
# type casting the raw value, then running that value through each
|
67
|
+
# validator present for this attribute.
|
68
|
+
#
|
69
|
+
# @return [Boolean] true if the raw value is valid for this attribute,
|
70
|
+
# false if it is not.
|
23
71
|
def valid?(raw_value)
|
24
72
|
value = type_cast(raw_value)
|
25
73
|
@validators.all? do |validator|
|
@@ -27,8 +75,9 @@ module Aws
|
|
27
75
|
end
|
28
76
|
end
|
29
77
|
|
78
|
+
# @api private
|
30
79
|
def extract(dynamodb_item)
|
31
|
-
dynamodb_item[database_name]
|
80
|
+
dynamodb_item[@database_name]
|
32
81
|
end
|
33
82
|
|
34
83
|
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
|
module Attributes
|
@@ -30,21 +43,21 @@ module Aws
|
|
30
43
|
# as you provide a marshaler which implements `#type_cast` and
|
31
44
|
# `#serialize` that consume raw values as expected, you can bring your
|
32
45
|
# own marshaler type. Convenience methods will provide this for you.
|
33
|
-
# @param [Hash]
|
34
|
-
# @option
|
46
|
+
# @param [Hash] opts
|
47
|
+
# @option opts [Array] :validators An array of validator classes that
|
35
48
|
# will be run when an attribute is checked for validity.
|
36
|
-
# @option
|
49
|
+
# @option opts [String] :database_attribute_name Optional attribute
|
37
50
|
# used to specify a different name for database persistence than the
|
38
51
|
# `name` parameter. Must be unique (you can't have overlap between
|
39
52
|
# database attribute names and the names of other attributes).
|
40
|
-
# @option
|
53
|
+
# @option opts [String] :dynamodb_type Generally used for keys and
|
41
54
|
# index attributes, one of "S", "N", "B", "BOOL", "SS", "NS", "BS",
|
42
55
|
# "M", "L". Optional if this attribute will never be used for a key or
|
43
56
|
# secondary index, but most convenience methods for setting attributes
|
44
57
|
# will provide this.
|
45
|
-
# @option
|
58
|
+
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
46
59
|
# the hash key for the table.
|
47
|
-
# @option
|
60
|
+
# @option opts [Boolean] :range_key Set to true if this attribute is
|
48
61
|
# the range key for the table.
|
49
62
|
def attr(name, marshaler, opts = {})
|
50
63
|
validate_attr_name(name)
|
@@ -68,84 +81,84 @@ module Aws
|
|
68
81
|
#
|
69
82
|
# @param [Symbol] name Name of this attribute. It should be a name that
|
70
83
|
# is safe to use as a method.
|
71
|
-
# @param [Hash]
|
72
|
-
# @option
|
84
|
+
# @param [Hash] opts
|
85
|
+
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
73
86
|
# the hash key for the table.
|
74
|
-
# @option
|
87
|
+
# @option opts [Boolean] :range_key Set to true if this attribute is
|
75
88
|
# the range key for the table.
|
76
|
-
def string_attr(
|
89
|
+
def string_attr(name, opts = {})
|
77
90
|
opts[:dynamodb_type] = "S"
|
78
|
-
attr(
|
91
|
+
attr(name, Attributes::StringMarshaler, opts)
|
79
92
|
end
|
80
93
|
|
81
94
|
# Define a boolean-type attribute for your model.
|
82
95
|
#
|
83
96
|
# @param [Symbol] name Name of this attribute. It should be a name that
|
84
97
|
# is safe to use as a method.
|
85
|
-
# @param [Hash]
|
86
|
-
# @option
|
98
|
+
# @param [Hash] opts
|
99
|
+
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
87
100
|
# the hash key for the table.
|
88
|
-
# @option
|
101
|
+
# @option opts [Boolean] :range_key Set to true if this attribute is
|
89
102
|
# the range key for the table.
|
90
|
-
def boolean_attr(
|
103
|
+
def boolean_attr(name, opts = {})
|
91
104
|
opts[:dynamodb_type] = "BOOL"
|
92
|
-
attr(
|
105
|
+
attr(name, Attributes::BooleanMarshaler, opts)
|
93
106
|
end
|
94
107
|
|
95
108
|
# Define a integer-type attribute for your model.
|
96
109
|
#
|
97
110
|
# @param [Symbol] name Name of this attribute. It should be a name that
|
98
111
|
# is safe to use as a method.
|
99
|
-
# @param [Hash]
|
100
|
-
# @option
|
112
|
+
# @param [Hash] opts
|
113
|
+
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
101
114
|
# the hash key for the table.
|
102
|
-
# @option
|
115
|
+
# @option opts [Boolean] :range_key Set to true if this attribute is
|
103
116
|
# the range key for the table.
|
104
|
-
def integer_attr(
|
117
|
+
def integer_attr(name, opts = {})
|
105
118
|
opts[:dynamodb_type] = "N"
|
106
|
-
attr(
|
119
|
+
attr(name, Attributes::IntegerMarshaler, opts)
|
107
120
|
end
|
108
121
|
|
109
122
|
# Define a float-type attribute for your model.
|
110
123
|
#
|
111
124
|
# @param [Symbol] name Name of this attribute. It should be a name that
|
112
125
|
# is safe to use as a method.
|
113
|
-
# @param [Hash]
|
114
|
-
# @option
|
126
|
+
# @param [Hash] opts
|
127
|
+
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
115
128
|
# the hash key for the table.
|
116
|
-
# @option
|
129
|
+
# @option opts [Boolean] :range_key Set to true if this attribute is
|
117
130
|
# the range key for the table.
|
118
|
-
def float_attr(
|
131
|
+
def float_attr(name, opts = {})
|
119
132
|
opts[:dynamodb_type] = "N"
|
120
|
-
attr(
|
133
|
+
attr(name, Attributes::FloatMarshaler, opts)
|
121
134
|
end
|
122
135
|
|
123
136
|
# Define a date-type attribute for your model.
|
124
137
|
#
|
125
138
|
# @param [Symbol] name Name of this attribute. It should be a name that
|
126
139
|
# is safe to use as a method.
|
127
|
-
# @param [Hash]
|
128
|
-
# @option
|
140
|
+
# @param [Hash] opts
|
141
|
+
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
129
142
|
# the hash key for the table.
|
130
|
-
# @option
|
143
|
+
# @option opts [Boolean] :range_key Set to true if this attribute is
|
131
144
|
# the range key for the table.
|
132
|
-
def date_attr(
|
145
|
+
def date_attr(name, opts = {})
|
133
146
|
opts[:dynamodb_type] = "S"
|
134
|
-
attr(
|
147
|
+
attr(name, Attributes::DateMarshaler, opts)
|
135
148
|
end
|
136
149
|
|
137
150
|
# Define a datetime-type attribute for your model.
|
138
151
|
#
|
139
152
|
# @param [Symbol] name Name of this attribute. It should be a name that
|
140
153
|
# is safe to use as a method.
|
141
|
-
# @param [Hash]
|
142
|
-
# @option
|
154
|
+
# @param [Hash] opts
|
155
|
+
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
143
156
|
# the hash key for the table.
|
144
|
-
# @option
|
157
|
+
# @option opts [Boolean] :range_key Set to true if this attribute is
|
145
158
|
# the range key for the table.
|
146
|
-
def datetime_attr(
|
159
|
+
def datetime_attr(name, opts = {})
|
147
160
|
opts[:dynamodb_type] = "S"
|
148
|
-
attr(
|
161
|
+
attr(name, Attributes::DateTimeMarshaler, opts)
|
149
162
|
end
|
150
163
|
|
151
164
|
# @return [Hash] hash of symbolized attribute names to attribute objects
|
@@ -153,6 +166,11 @@ module Aws
|
|
153
166
|
@attributes
|
154
167
|
end
|
155
168
|
|
169
|
+
# @return [Hash] hash of database names to attribute names
|
170
|
+
def storage_attributes
|
171
|
+
@storage_attributes
|
172
|
+
end
|
173
|
+
|
156
174
|
# @return [Aws::Record::Attribute,nil]
|
157
175
|
def hash_key
|
158
176
|
@attributes[@keys[:hash]]
|
@@ -218,12 +236,12 @@ module Aws
|
|
218
236
|
end
|
219
237
|
|
220
238
|
def check_for_naming_collisions(name, storage_name)
|
221
|
-
if @attributes[storage_name]
|
239
|
+
if @attributes[storage_name.to_sym]
|
222
240
|
raise Errors::NameCollision.new(
|
223
241
|
"Custom storage name #{storage_name} already exists as an"\
|
224
242
|
" attribute name in #{@attributes}"
|
225
243
|
)
|
226
|
-
elsif @storage_attributes[name]
|
244
|
+
elsif @storage_attributes[name.to_s]
|
227
245
|
raise Errors::NameCollision.new(
|
228
246
|
"Attribute name #{name} already exists as a custom storage"\
|
229
247
|
" name in #{@storage_attributes}"
|
@@ -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
|
module Attributes
|
@@ -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
|
require 'date'
|
2
15
|
|
3
16
|
module Aws
|
@@ -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
|
require 'date'
|
2
15
|
|
3
16
|
module Aws
|
@@ -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
|
module Attributes
|
@@ -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
|
module Attributes
|
@@ -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
|
module Attributes
|
@@ -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
|
module Errors
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Aws
|
2
|
+
module Record
|
3
|
+
class ItemCollection
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def initialize(search_method, search_params, model, client)
|
7
|
+
@search_method = search_method
|
8
|
+
@search_params = search_params
|
9
|
+
@model = model
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
def each(&block)
|
14
|
+
return enum_for(:each) unless block_given?
|
15
|
+
unless @result
|
16
|
+
@result = @client.send(@search_method, @search_params)
|
17
|
+
end
|
18
|
+
@result.each_page do |page|
|
19
|
+
items = _build_items_from_response(page.items, @model)
|
20
|
+
items.each do |item|
|
21
|
+
yield item
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def _build_items_from_response(items, model)
|
28
|
+
ret = []
|
29
|
+
items.each do |item|
|
30
|
+
record = model.new
|
31
|
+
data = record.instance_variable_get("@data")
|
32
|
+
model.attributes.each do |name, attr|
|
33
|
+
data[name] = attr.extract(item)
|
34
|
+
end
|
35
|
+
ret << record
|
36
|
+
end
|
37
|
+
ret
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,11 +1,32 @@
|
|
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
|
module ItemOperations
|
4
17
|
|
18
|
+
# @api private
|
5
19
|
def self.included(sub_class)
|
6
20
|
sub_class.extend(ItemOperationsClassMethods)
|
7
21
|
end
|
8
22
|
|
23
|
+
# Saves this instance of an item to Amazon DynamoDB using the
|
24
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#put_item-instance_method Aws::DynamoDB::Client#put_item}
|
25
|
+
# API. Uses this item instance's attributes in order to build the request
|
26
|
+
# on your behalf.
|
27
|
+
#
|
28
|
+
# @raise [Aws::Record::Errors::KeyMissing] if a required key attribute
|
29
|
+
# does not have a value within this item instance.
|
9
30
|
def save
|
10
31
|
dynamodb_client.put_item(
|
11
32
|
table_name: self.class.table_name,
|
@@ -13,6 +34,10 @@ module Aws
|
|
13
34
|
)
|
14
35
|
end
|
15
36
|
|
37
|
+
# Deletes the item instance that matches the key values of this item
|
38
|
+
# instance in Amazon DynamoDB. Uses the
|
39
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#delete_item-instance_method Aws::DynamoDB::Client#delete_item}
|
40
|
+
# API.
|
16
41
|
def delete!
|
17
42
|
dynamodb_client.delete_item(
|
18
43
|
table_name: self.class.table_name,
|
@@ -60,6 +85,21 @@ module Aws
|
|
60
85
|
end
|
61
86
|
|
62
87
|
module ItemOperationsClassMethods
|
88
|
+
|
89
|
+
# @example Usage Example
|
90
|
+
# class MyModel
|
91
|
+
# include Aws::Record
|
92
|
+
# integer_attr :id, hash_key: true
|
93
|
+
# string_attr :name, range_key: true
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# MyModel.find(id: 1, name: "First")
|
97
|
+
#
|
98
|
+
# @param [Hash] opts attribute-value pairs for the key you wish to
|
99
|
+
# search for.
|
100
|
+
# @return [Aws::Record] builds and returns an instance of your model.
|
101
|
+
# @raise [Aws::Record::Errors::KeyMissing] if your option parameters do
|
102
|
+
# not include all table keys.
|
63
103
|
def find(opts)
|
64
104
|
key = {}
|
65
105
|
@keys.each_value do |attr_sym|
|
@@ -92,14 +132,6 @@ module Aws
|
|
92
132
|
end
|
93
133
|
record
|
94
134
|
end
|
95
|
-
|
96
|
-
def user_agent(custom)
|
97
|
-
if custom
|
98
|
-
custom
|
99
|
-
else
|
100
|
-
" aws-record/#{VERSION}"
|
101
|
-
end
|
102
|
-
end
|
103
135
|
end
|
104
136
|
|
105
137
|
end
|
@@ -0,0 +1,56 @@
|
|
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
|
+
|
14
|
+
module Aws
|
15
|
+
module Record
|
16
|
+
module Query
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
def self.included(sub_class)
|
20
|
+
sub_class.extend(QueryClassMethods)
|
21
|
+
end
|
22
|
+
|
23
|
+
module QueryClassMethods
|
24
|
+
|
25
|
+
# This method calls
|
26
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#query-instance_method Aws::DynamoDB::Client#query},
|
27
|
+
# populating the +:table_name+ parameter from the model class, and
|
28
|
+
# combining this with the other parameters you provide.
|
29
|
+
#
|
30
|
+
# @param [Hash] opts options to pass on to the client call to +#query+.
|
31
|
+
# See the documentation above in the AWS SDK for Ruby V2.
|
32
|
+
# @return [Aws::Record::ItemCollection] an enumerable collection of the
|
33
|
+
# query result.
|
34
|
+
def query(opts)
|
35
|
+
query_opts = opts.merge(table_name: table_name)
|
36
|
+
ItemCollection.new(:query, query_opts, self, dynamodb_client)
|
37
|
+
end
|
38
|
+
|
39
|
+
# This method calls
|
40
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#scan-instance_method Aws::DynamoDB::Client#scan},
|
41
|
+
# populating the +:table_name+ parameter from the model class, and
|
42
|
+
# combining this with the other parameters you provide.
|
43
|
+
#
|
44
|
+
# @param [Hash] opts options to pass on to the client call to +#scan+.
|
45
|
+
# See the documentation above in the AWS SDK for Ruby V2.
|
46
|
+
# @return [Aws::Record::ItemCollection] an enumerable collection of the
|
47
|
+
# scan result.
|
48
|
+
def scan(opts = {})
|
49
|
+
scan_opts = opts.merge(table_name: table_name)
|
50
|
+
ItemCollection.new(:scan, scan_opts, self, dynamodb_client)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,156 @@
|
|
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
|
+
|
14
|
+
module Aws
|
15
|
+
module Record
|
16
|
+
module SecondaryIndexes
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
def self.included(sub_class)
|
20
|
+
sub_class.instance_variable_set("@local_secondary_indexes", {})
|
21
|
+
sub_class.instance_variable_set("@global_secondary_indexes", {})
|
22
|
+
sub_class.extend(SecondaryIndexesClassMethods)
|
23
|
+
end
|
24
|
+
|
25
|
+
module SecondaryIndexesClassMethods
|
26
|
+
|
27
|
+
# Creates a local secondary index for the model. Learn more about Local
|
28
|
+
# Secondary Indexes in the
|
29
|
+
# {http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LSI.html Amazon DynamoDB Developer Guide}.
|
30
|
+
#
|
31
|
+
# @param [Symbol] name index name for this local secondary index
|
32
|
+
# @param [Hash] opts
|
33
|
+
# @option opts [Symbol] :range_key the range key used by this local
|
34
|
+
# secondary index. Note that the hash key MUST be the table's hash
|
35
|
+
# key, and so that value will be filled in for you.
|
36
|
+
# @option opts [Hash] :projection a hash which defines which attributes
|
37
|
+
# are copied from the table to the index. See shape details in the
|
38
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Types/Projection.html AWS SDK for Ruby V2 docs}.
|
39
|
+
def local_secondary_index(name, opts)
|
40
|
+
opts[:hash_key] = hash_key.name
|
41
|
+
_validate_required_lsi_keys(opts)
|
42
|
+
local_secondary_indexes[name] = opts
|
43
|
+
end
|
44
|
+
|
45
|
+
# Creates a global secondary index for the model. Learn more about
|
46
|
+
# Global Secondary Indexes in the
|
47
|
+
# {http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html Amazon DynamoDB Developer Guide}.
|
48
|
+
#
|
49
|
+
# @param [Symbol] name index name for this global secondary index
|
50
|
+
# @param [Hash] opts
|
51
|
+
# @option opts [Symbol] :hash_key the hash key used by this global
|
52
|
+
# secondary index.
|
53
|
+
# @option opts [Symbol] :range_key the range key used by this global
|
54
|
+
# secondary index.
|
55
|
+
# @option opts [Hash] :projection a hash which defines which attributes
|
56
|
+
# are copied from the table to the index. See shape details in the
|
57
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Types/Projection.html AWS SDK for Ruby V2 docs}.
|
58
|
+
def global_secondary_index(name, opts)
|
59
|
+
_validate_required_gsi_keys(opts)
|
60
|
+
global_secondary_indexes[name] = opts
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [Hash] hash of local secondary index names to the index's
|
64
|
+
# attributes.
|
65
|
+
def local_secondary_indexes
|
66
|
+
@local_secondary_indexes
|
67
|
+
end
|
68
|
+
|
69
|
+
# @return [Hash] hash of global secondary index names to the index's
|
70
|
+
# attributes.
|
71
|
+
def global_secondary_indexes
|
72
|
+
@global_secondary_indexes
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [Hash] hash of the local secondary indexes in a form suitable
|
76
|
+
# for use in a table migration. For example, any attributes which
|
77
|
+
# have a unique database storage name will use that name instead.
|
78
|
+
def local_secondary_indexes_for_migration
|
79
|
+
_migration_format_indexes(local_secondary_indexes)
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Hash] hash of the global secondary indexes in a form suitable
|
83
|
+
# for use in a table migration. For example, any attributes which
|
84
|
+
# have a unique database storage name will use that name instead.
|
85
|
+
def global_secondary_indexes_for_migration
|
86
|
+
_migration_format_indexes(global_secondary_indexes)
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def _migration_format_indexes(indexes)
|
91
|
+
return nil if indexes.empty?
|
92
|
+
indexes.collect do |name, opts|
|
93
|
+
h = { index_name: name }
|
94
|
+
h[:key_schema] = _si_key_schema(opts)
|
95
|
+
opts.delete(:hash_key)
|
96
|
+
opts.delete(:range_key)
|
97
|
+
h = h.merge(opts)
|
98
|
+
h
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def _si_key_schema(opts)
|
103
|
+
key_schema = [{
|
104
|
+
key_type: "HASH",
|
105
|
+
attribute_name: @attributes[opts[:hash_key]].database_name
|
106
|
+
}]
|
107
|
+
if opts[:range_key]
|
108
|
+
key_schema << {
|
109
|
+
key_type: "RANGE",
|
110
|
+
attribute_name: @attributes[opts[:range_key]].database_name
|
111
|
+
}
|
112
|
+
end
|
113
|
+
key_schema
|
114
|
+
end
|
115
|
+
|
116
|
+
def _validate_required_lsi_keys(params)
|
117
|
+
if params[:hash_key] && params[:range_key]
|
118
|
+
_validate_attributes_exist(params[:hash_key], params[:range_key])
|
119
|
+
else
|
120
|
+
raise ArgumentError.new(
|
121
|
+
"Local Secondary Indexes require a hash and range key!"
|
122
|
+
)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def _validate_required_gsi_keys(params)
|
127
|
+
if params[:hash_key]
|
128
|
+
if params[:range_key]
|
129
|
+
_validate_attributes_exist(params[:hash_key], params[:range_key])
|
130
|
+
else
|
131
|
+
_validate_attributes_exist(params[:hash_key])
|
132
|
+
end
|
133
|
+
else
|
134
|
+
raise ArgumentError.new(
|
135
|
+
"Global Secondary Indexes require at least a hash key!"
|
136
|
+
)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def _validate_attributes_exist(*attr_names)
|
141
|
+
missing = attr_names.select do |attr_name|
|
142
|
+
@attributes[attr_name].nil?
|
143
|
+
end
|
144
|
+
unless missing.empty?
|
145
|
+
raise ArgumentError.new(
|
146
|
+
"#{missing.join(", ")} not present in model attributes."\
|
147
|
+
" Please ensure that attributes are defined in the model"\
|
148
|
+
" class BEFORE defining a index on those attributes."
|
149
|
+
)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -1,24 +1,88 @@
|
|
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 TableMigration
|
4
17
|
|
18
|
+
# @!attribute [rw] client
|
19
|
+
# @return [Aws::DynamoDB::Client] the
|
20
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html Aws::DynamoDB::Client}
|
21
|
+
# class used by this table migration instance.
|
5
22
|
attr_accessor :client
|
6
23
|
|
7
|
-
|
24
|
+
# @param [Aws::Record] model a model class that includes {Aws::Record}.
|
25
|
+
# @param [Hash] opts
|
26
|
+
# @option opts [Aws::DynamoDB::Client] :client Allows you to inject your
|
27
|
+
# own
|
28
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html Aws::DynamoDB::Client}
|
29
|
+
# class. If this option is not included, a client will be constructed for
|
30
|
+
# you with default parameters.
|
31
|
+
def initialize(model, opts = {})
|
8
32
|
assert_model_valid(model)
|
9
33
|
@model = model
|
10
|
-
@client = client || Aws::DynamoDB::Client.new
|
34
|
+
@client = opts[:client] || Aws::DynamoDB::Client.new
|
11
35
|
end
|
12
36
|
|
37
|
+
# This method calls
|
38
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#create_table-instance_method Aws::DynamoDB::Client#create_table},
|
39
|
+
# populating the attribute definitions and key schema based on your model
|
40
|
+
# class, as well as passing through other parameters as provided by you.
|
41
|
+
#
|
42
|
+
# @param [Hash] opts options to pass on to the client call to
|
43
|
+
# +#create_table+. See the documentation above in the AWS SDK for Ruby
|
44
|
+
# V2.
|
45
|
+
# @option opts [Hash] :provisioned_throughput This is a required argument,
|
46
|
+
# in which you must specify the +:read_capacity_units+ and
|
47
|
+
# +:write_capacity_units+ of your new table.
|
48
|
+
# @option opts [Hash] :global_secondary_index_throughput This argument is
|
49
|
+
# required if you define any global secondary indexes. It should map your
|
50
|
+
# global secondary index names to their provisioned throughput, similar
|
51
|
+
# to how you define the provisioned throughput for the table in general.
|
13
52
|
def create!(opts)
|
53
|
+
gsit = opts.delete(:global_secondary_index_throughput)
|
14
54
|
create_opts = opts.merge({
|
15
55
|
table_name: @model.table_name,
|
16
56
|
attribute_definitions: attribute_definitions,
|
17
57
|
key_schema: key_schema
|
18
58
|
})
|
59
|
+
if lsis = @model.local_secondary_indexes_for_migration
|
60
|
+
create_opts[:local_secondary_indexes] = lsis
|
61
|
+
_append_to_attribute_definitions(lsis, create_opts)
|
62
|
+
end
|
63
|
+
if gsis = @model.global_secondary_indexes_for_migration
|
64
|
+
unless gsit
|
65
|
+
raise ArgumentError.new(
|
66
|
+
"If you define global secondary indexes, you must also define"\
|
67
|
+
" :global_secondary_index_throughput on table creation."
|
68
|
+
)
|
69
|
+
end
|
70
|
+
gsis_with_throughput = _add_throughout_to_gsis(gsis, gsit)
|
71
|
+
create_opts[:global_secondary_indexes] = gsis_with_throughput
|
72
|
+
_append_to_attribute_definitions(gsis, create_opts)
|
73
|
+
end
|
19
74
|
@client.create_table(create_opts)
|
20
75
|
end
|
21
76
|
|
77
|
+
# This method calls
|
78
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#update_table-instance_method Aws::DynamoDB::Client#update_table}
|
79
|
+
# using the parameters that you provide.
|
80
|
+
#
|
81
|
+
# @param [Hash] opts options to pass on to the client call to
|
82
|
+
# +#update_table+. See the documentation above in the AWS SDK for Ruby
|
83
|
+
# V2.
|
84
|
+
# @raise [Aws::Record::Errors::TableDoesNotExist] if the table does not
|
85
|
+
# currently exist in Amazon DynamoDB.
|
22
86
|
def update!(opts)
|
23
87
|
begin
|
24
88
|
update_opts = opts.merge({
|
@@ -30,6 +94,12 @@ module Aws
|
|
30
94
|
end
|
31
95
|
end
|
32
96
|
|
97
|
+
# This method calls
|
98
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#delete_table-instance_method Aws::DynamoDB::Client#delete_table}
|
99
|
+
# using the table name of your model.
|
100
|
+
#
|
101
|
+
# @raise [Aws::Record::Errors::TableDoesNotExist] if the table did not
|
102
|
+
# exist in Amazon DynamoDB at the time of calling.
|
33
103
|
def delete!
|
34
104
|
begin
|
35
105
|
@client.delete_table(table_name: @model.table_name)
|
@@ -38,6 +108,10 @@ module Aws
|
|
38
108
|
end
|
39
109
|
end
|
40
110
|
|
111
|
+
# This method waits on the table specified in the model to exist and be
|
112
|
+
# marked as ACTIVE in Amazon DynamoDB. Note that this method can run for
|
113
|
+
# several minutes if the table does not exist, and is not created within
|
114
|
+
# the wait period.
|
41
115
|
def wait_until_available
|
42
116
|
@client.wait_until(:table_exists, table_name: @model.table_name)
|
43
117
|
end
|
@@ -69,6 +143,46 @@ module Aws
|
|
69
143
|
end
|
70
144
|
end
|
71
145
|
|
146
|
+
def _append_to_attribute_definitions(secondary_indexes, create_opts)
|
147
|
+
attr_def = create_opts[:attribute_definitions]
|
148
|
+
secondary_indexes.each do |si|
|
149
|
+
si[:key_schema].each do |key_schema|
|
150
|
+
exists = attr_def.find { |a|
|
151
|
+
a[:attribute_name] == key_schema[:attribute_name]
|
152
|
+
}
|
153
|
+
unless exists
|
154
|
+
attr = @model.attributes[
|
155
|
+
@model.storage_attributes[key_schema[:attribute_name]]
|
156
|
+
]
|
157
|
+
attr_def << {
|
158
|
+
attribute_name: attr.database_name,
|
159
|
+
attribute_type: attr.dynamodb_type
|
160
|
+
}
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
create_opts[:attribute_definitions] = attr_def
|
165
|
+
end
|
166
|
+
|
167
|
+
def _add_throughout_to_gsis(global_secondary_indexes, gsi_throughput)
|
168
|
+
missing_throughput = []
|
169
|
+
ret = global_secondary_indexes.map do |params|
|
170
|
+
name = params[:index_name]
|
171
|
+
throughput = gsi_throughput[name]
|
172
|
+
missing_throughput << name unless throughput
|
173
|
+
params.merge(provisioned_throughput: throughput)
|
174
|
+
end
|
175
|
+
unless missing_throughput.empty?
|
176
|
+
raise ArgumentError.new(
|
177
|
+
"Missing provisioned throughput for the following global secondary"\
|
178
|
+
" indexes: #{missing_throughput.join(", ")}. GSIs:"\
|
179
|
+
" #{global_secondary_indexes} and defined throughput:"\
|
180
|
+
" #{gsi_throughput}"
|
181
|
+
)
|
182
|
+
end
|
183
|
+
ret
|
184
|
+
end
|
185
|
+
|
72
186
|
def key_schema
|
73
187
|
keys.map do |type, attr|
|
74
188
|
{
|
@@ -1,5 +1,18 @@
|
|
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
|
-
VERSION = "1.0.0.pre.
|
16
|
+
VERSION = "1.0.0.pre.2"
|
4
17
|
end
|
5
18
|
end
|
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.
|
4
|
+
version: 1.0.0.pre.2
|
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:
|
11
|
+
date: 2016-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-resources
|
@@ -42,7 +42,10 @@ files:
|
|
42
42
|
- lib/aws-record/record/attributes/integer_marshaler.rb
|
43
43
|
- lib/aws-record/record/attributes/string_marshaler.rb
|
44
44
|
- lib/aws-record/record/errors.rb
|
45
|
+
- lib/aws-record/record/item_collection.rb
|
45
46
|
- lib/aws-record/record/item_operations.rb
|
47
|
+
- lib/aws-record/record/query.rb
|
48
|
+
- lib/aws-record/record/secondary_indexes.rb
|
46
49
|
- lib/aws-record/record/table_migration.rb
|
47
50
|
- lib/aws-record/record/version.rb
|
48
51
|
homepage: http://github.com/aws/aws-sdk-ruby-record
|
@@ -65,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
68
|
version: 1.3.1
|
66
69
|
requirements: []
|
67
70
|
rubyforge_project:
|
68
|
-
rubygems_version: 2.
|
71
|
+
rubygems_version: 2.4.8
|
69
72
|
signing_key:
|
70
73
|
specification_version: 4
|
71
74
|
summary: AWS Record library for Amazon DynamoDB
|