aws-record 2.1.0 → 2.1.1
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d5eae4de88bc967f473b49bf9294047a6ee6821
|
4
|
+
data.tar.gz: 5c2e4404ad3b47f909d572b546f3cd70a8e0e93d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c261673f84aa256222fdd9c17f715ab9161c1a1a1fd23978b494c62627312d12dd314d824321ef43296f87fe92be35ab135de104b6094bb753b746fe3e7235f6
|
7
|
+
data.tar.gz: 7742ea625d83be44c72602f0d55b05f7614f87971cd69bcb402f02de0e7c55057b9870a77b43b0d2adfe02f428565b7be7e770317ba9220bc8b2386528306750
|
data/lib/aws-record.rb
CHANGED
@@ -34,6 +34,7 @@ require_relative 'aws-record/record/marshalers/float_marshaler'
|
|
34
34
|
require_relative 'aws-record/record/marshalers/date_marshaler'
|
35
35
|
require_relative 'aws-record/record/marshalers/date_time_marshaler'
|
36
36
|
require_relative 'aws-record/record/marshalers/time_marshaler'
|
37
|
+
require_relative 'aws-record/record/marshalers/epoch_time_marshaler'
|
37
38
|
require_relative 'aws-record/record/marshalers/list_marshaler'
|
38
39
|
require_relative 'aws-record/record/marshalers/map_marshaler'
|
39
40
|
require_relative 'aws-record/record/marshalers/string_set_marshaler'
|
@@ -240,6 +240,28 @@ module Aws
|
|
240
240
|
attr(name, Marshalers::TimeMarshaler.new(opts), opts)
|
241
241
|
end
|
242
242
|
|
243
|
+
# Define a time-type attribute for your model which persists as
|
244
|
+
# epoch-seconds.
|
245
|
+
#
|
246
|
+
# @param [Symbol] name Name of this attribute. It should be a name
|
247
|
+
# that is safe to use as a method.
|
248
|
+
# @param [Hash] opts
|
249
|
+
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
250
|
+
# the hash key for the table.
|
251
|
+
# @option opts [Boolean] :range_key Set to true if this attribute is
|
252
|
+
# the range key for the table.
|
253
|
+
# @option opts [Boolean] :persist_nil Optional attribute used to
|
254
|
+
# indicate whether nil values should be persisted. If true, explicitly
|
255
|
+
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
256
|
+
# nil values will be ignored and not persisted. By default, is false.
|
257
|
+
# @option opts [Object] :default_value Optional attribute used to
|
258
|
+
# define a "default value" to be used if the attribute's value on an
|
259
|
+
# item is nil or not set at persistence time.
|
260
|
+
def epoch_time_attr(name, opts = {})
|
261
|
+
opts[:dynamodb_type] = "N"
|
262
|
+
attr(name, Marshalers::EpochTimeMarshaler.new(opts), opts)
|
263
|
+
end
|
264
|
+
|
243
265
|
# Define a list-type attribute for your model.
|
244
266
|
#
|
245
267
|
# Lists do not have to be homogeneous, but they do have to be types that
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Copyright 2018 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
|
+
require 'time'
|
15
|
+
|
16
|
+
module Aws
|
17
|
+
module Record
|
18
|
+
module Marshalers
|
19
|
+
|
20
|
+
class EpochTimeMarshaler
|
21
|
+
def initialize(opts = {})
|
22
|
+
@use_local_time = opts[:use_local_time] ? true : false
|
23
|
+
end
|
24
|
+
|
25
|
+
def type_cast(raw_value)
|
26
|
+
value = _format(raw_value)
|
27
|
+
if !@use_local_time && value.is_a?(::Time)
|
28
|
+
value.utc
|
29
|
+
else
|
30
|
+
value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def serialize(raw_value)
|
35
|
+
time = type_cast(raw_value)
|
36
|
+
if time.nil?
|
37
|
+
nil
|
38
|
+
elsif time.is_a?(::Time)
|
39
|
+
time.to_i
|
40
|
+
else
|
41
|
+
msg = "expected a Time value or nil, got #{time.class}"
|
42
|
+
raise ArgumentError, msg
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def _format(raw_value)
|
49
|
+
case raw_value
|
50
|
+
when nil
|
51
|
+
nil
|
52
|
+
when ''
|
53
|
+
nil
|
54
|
+
when ::Time
|
55
|
+
raw_value
|
56
|
+
when Integer # timestamp
|
57
|
+
::Time.at(raw_value)
|
58
|
+
else # Date, DateTime, or String
|
59
|
+
::Time.parse(raw_value.to_s)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -74,6 +74,19 @@ module Aws
|
|
74
74
|
# end
|
75
75
|
# end
|
76
76
|
#
|
77
|
+
# @example A model with a Time to Live attribute
|
78
|
+
# class ExpiringTokens
|
79
|
+
# string_attr :token_uuid, hash_key: true
|
80
|
+
# epoch_time_attr :ttl
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
# table_config = Aws::Record::TableConfig.define do |t|
|
84
|
+
# t.model_class ExpiringTokens
|
85
|
+
# t.read_capacity_units 10
|
86
|
+
# t.write_capacity_units 1
|
87
|
+
# t.ttl_attribute :ttl
|
88
|
+
# end
|
89
|
+
#
|
77
90
|
class TableConfig
|
78
91
|
|
79
92
|
attr_accessor :client
|
@@ -92,6 +105,8 @@ module Aws
|
|
92
105
|
# index.
|
93
106
|
# * +#write_capacity_units+ Sets the write capacity units for the
|
94
107
|
# index.
|
108
|
+
# * +#ttl_attribute+ Sets the attribute ID to be used as the TTL
|
109
|
+
# attribute, and if present, TTL will be enabled for the table.
|
95
110
|
#
|
96
111
|
# @example Defining a migration with a GSI.
|
97
112
|
# class Forum
|
@@ -170,6 +185,16 @@ module Aws
|
|
170
185
|
@client = Aws::DynamoDB::Client.new(@client_options)
|
171
186
|
end
|
172
187
|
|
188
|
+
# @api private
|
189
|
+
def ttl_attribute(attribute_symbol)
|
190
|
+
attribute = @model_class.attributes.attribute_for(attribute_symbol)
|
191
|
+
if attribute
|
192
|
+
@ttl_attribute = attribute.database_name
|
193
|
+
else
|
194
|
+
raise ArgumentError, "Invalid attribute #{attribute_symbol} for #{@model_class}"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
173
198
|
# Performs a migration, if needed, against the remote table. If
|
174
199
|
# +#compatible?+ would return true, the remote table already has the same
|
175
200
|
# throughput, key schema, attribute definitions, and global secondary
|
@@ -210,6 +235,22 @@ module Aws
|
|
210
235
|
@client.create_table(_create_table_opts)
|
211
236
|
@client.wait_until(:table_exists, table_name: @model_class.table_name)
|
212
237
|
end
|
238
|
+
# At this stage, we have a table and need to check for after-effects to
|
239
|
+
# apply.
|
240
|
+
# First up is TTL attribute. Since this migration is not exact match,
|
241
|
+
# we will only alter TTL status if we have a TTL attribute defined. We
|
242
|
+
# may someday support explicit TTL deletion, but we do not yet do this.
|
243
|
+
if @ttl_attribute
|
244
|
+
if !_ttl_compatibility_check
|
245
|
+
client.update_time_to_live(
|
246
|
+
table_name: @model_class.table_name,
|
247
|
+
time_to_live_specification: {
|
248
|
+
enabled: true,
|
249
|
+
attribute_name: @ttl_attribute
|
250
|
+
}
|
251
|
+
)
|
252
|
+
end # Else TTL is compatible and we are done.
|
253
|
+
end # Else our work is done.
|
213
254
|
end
|
214
255
|
|
215
256
|
# Checks the remote table for compatibility. Similar to +#exact_match?+,
|
@@ -224,7 +265,7 @@ module Aws
|
|
224
265
|
def compatible?
|
225
266
|
begin
|
226
267
|
resp = @client.describe_table(table_name: @model_class.table_name)
|
227
|
-
_compatible_check(resp)
|
268
|
+
_compatible_check(resp) && _ttl_compatibility_check
|
228
269
|
rescue DynamoDB::Errors::ResourceNotFoundException
|
229
270
|
false
|
230
271
|
end
|
@@ -242,13 +283,41 @@ module Aws
|
|
242
283
|
_throughput_equal(resp) &&
|
243
284
|
_keys_equal(resp) &&
|
244
285
|
_ad_equal(resp) &&
|
245
|
-
_gsi_equal(resp)
|
286
|
+
_gsi_equal(resp) &&
|
287
|
+
_ttl_match_check
|
246
288
|
rescue DynamoDB::Errors::ResourceNotFoundException
|
247
289
|
false
|
248
290
|
end
|
249
291
|
end
|
250
292
|
|
251
293
|
private
|
294
|
+
def _ttl_compatibility_check
|
295
|
+
if @ttl_attribute
|
296
|
+
ttl_status = @client.describe_time_to_live(
|
297
|
+
table_name: @model_class.table_name
|
298
|
+
)
|
299
|
+
desc = ttl_status.time_to_live_description
|
300
|
+
["ENABLED", "ENABLING"].include?(desc.time_to_live_status) &&
|
301
|
+
desc.attribute_name == @ttl_attribute
|
302
|
+
else
|
303
|
+
true
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def _ttl_match_check
|
308
|
+
ttl_status = @client.describe_time_to_live(
|
309
|
+
table_name: @model_class.table_name
|
310
|
+
)
|
311
|
+
desc = ttl_status.time_to_live_description
|
312
|
+
if @ttl_attribute
|
313
|
+
["ENABLED", "ENABLING"].include?(desc.time_to_live_status) &&
|
314
|
+
desc.attribute_name == @ttl_attribute
|
315
|
+
else
|
316
|
+
!["ENABLED", "ENABLING"].include?(desc.time_to_live_status) ||
|
317
|
+
desc.attribute_name == nil
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
252
321
|
def _compatible_check(resp)
|
253
322
|
_throughput_equal(resp) &&
|
254
323
|
_keys_equal(resp) &&
|
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: 2.1.
|
4
|
+
version: 2.1.1
|
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: 2018-
|
11
|
+
date: 2018-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-dynamodb
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- lib/aws-record/record/marshalers/boolean_marshaler.rb
|
45
45
|
- lib/aws-record/record/marshalers/date_marshaler.rb
|
46
46
|
- lib/aws-record/record/marshalers/date_time_marshaler.rb
|
47
|
+
- lib/aws-record/record/marshalers/epoch_time_marshaler.rb
|
47
48
|
- lib/aws-record/record/marshalers/float_marshaler.rb
|
48
49
|
- lib/aws-record/record/marshalers/integer_marshaler.rb
|
49
50
|
- lib/aws-record/record/marshalers/list_marshaler.rb
|