aws-record 1.0.0.pre.3 → 1.0.0.pre.4
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 +4 -4
- data/lib/aws-record.rb +1 -0
- data/lib/aws-record/record.rb +1 -0
- data/lib/aws-record/record/attributes.rb +16 -3
- data/lib/aws-record/record/attributes/date_marshaler.rb +2 -10
- data/lib/aws-record/record/attributes/date_time_marshaler.rb +2 -10
- data/lib/aws-record/record/attributes/float_marshaler.rb +1 -1
- data/lib/aws-record/record/attributes/integer_marshaler.rb +1 -1
- data/lib/aws-record/record/dirty_tracking.rb +302 -0
- data/lib/aws-record/record/errors.rb +1 -0
- data/lib/aws-record/record/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 102f5cb13fee3789030badc882c2d171ddb800e8
|
4
|
+
data.tar.gz: e4bad779188f59b940492fb2644636901826f41e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3ef6f71866145568e25d6cac31ebd31c33ad37bfa776ae648e4a0424f69e2e7c6fa46b8d22e5b0c5d5231f1fbde98d1460e5f83e88a812ea85dd4d87e3d3b68
|
7
|
+
data.tar.gz: 9cb2cf7a7644a0a6754c7e32452dbf5b83e422e6d7e94ca8a5c0442aa1532ac81ed47519bb00175a1a5e8107f193c1612a0a2ebd3df66a046763daa6c51378a5
|
data/lib/aws-record.rb
CHANGED
@@ -19,6 +19,7 @@ module Aws
|
|
19
19
|
module Record
|
20
20
|
autoload :Attribute, 'aws-record/record/attribute'
|
21
21
|
autoload :Attributes, 'aws-record/record/attributes'
|
22
|
+
autoload :DirtyTracking, 'aws-record/record/dirty_tracking'
|
22
23
|
autoload :Errors, 'aws-record/record/errors'
|
23
24
|
autoload :ItemCollection, 'aws-record/record/item_collection'
|
24
25
|
autoload :ItemOperations, 'aws-record/record/item_operations'
|
data/lib/aws-record/record.rb
CHANGED
@@ -26,6 +26,7 @@ module Aws
|
|
26
26
|
sub_class.send(:extend, RecordClassMethods)
|
27
27
|
sub_class.send(:include, Attributes)
|
28
28
|
sub_class.send(:include, ItemOperations)
|
29
|
+
sub_class.send(:include, DirtyTracking)
|
29
30
|
sub_class.send(:include, Query)
|
30
31
|
sub_class.send(:include, SecondaryIndexes)
|
31
32
|
end
|
@@ -33,6 +33,20 @@ module Aws
|
|
33
33
|
@data.dup
|
34
34
|
end
|
35
35
|
|
36
|
+
private
|
37
|
+
|
38
|
+
# @private
|
39
|
+
def read_attribute(name, attribute)
|
40
|
+
raw = @data[name]
|
41
|
+
attribute.type_cast(raw)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @private
|
45
|
+
def write_attribute(name, attribute, value)
|
46
|
+
@data[name] = value
|
47
|
+
end
|
48
|
+
|
49
|
+
|
36
50
|
module ClassMethods
|
37
51
|
|
38
52
|
# Define an attribute for your model, providing your own attribute type.
|
@@ -304,12 +318,11 @@ module Aws
|
|
304
318
|
private
|
305
319
|
def define_attr_methods(name, attribute)
|
306
320
|
define_method(name) do
|
307
|
-
|
308
|
-
attribute.type_cast(raw)
|
321
|
+
read_attribute(name, attribute)
|
309
322
|
end
|
310
323
|
|
311
324
|
define_method("#{name}=") do |value|
|
312
|
-
|
325
|
+
write_attribute(name, attribute, value)
|
313
326
|
end
|
314
327
|
end
|
315
328
|
|
@@ -29,17 +29,9 @@ module Aws
|
|
29
29
|
when Date
|
30
30
|
raw_value
|
31
31
|
when Integer
|
32
|
-
|
33
|
-
Date.parse(Time.at(raw_value).to_s) # assumed timestamp
|
34
|
-
rescue
|
35
|
-
nil
|
36
|
-
end
|
32
|
+
Date.parse(Time.at(raw_value).to_s) # assumed timestamp
|
37
33
|
else
|
38
|
-
|
39
|
-
Date.parse(raw_value.to_s) # Time, DateTime or String
|
40
|
-
rescue
|
41
|
-
nil
|
42
|
-
end
|
34
|
+
Date.parse(raw_value.to_s) # Time, DateTime or String
|
43
35
|
end
|
44
36
|
end
|
45
37
|
|
@@ -29,17 +29,9 @@ module Aws
|
|
29
29
|
when DateTime
|
30
30
|
raw_value
|
31
31
|
when Integer
|
32
|
-
|
33
|
-
DateTime.parse(Time.at(raw_value).to_s) # timestamp
|
34
|
-
rescue
|
35
|
-
nil
|
36
|
-
end
|
32
|
+
DateTime.parse(Time.at(raw_value).to_s) # timestamp
|
37
33
|
else
|
38
|
-
|
39
|
-
DateTime.parse(raw_value.to_s) # Time, Date or String
|
40
|
-
rescue
|
41
|
-
nil
|
42
|
-
end
|
34
|
+
DateTime.parse(raw_value.to_s) # Time, Date or String
|
43
35
|
end
|
44
36
|
end
|
45
37
|
|
@@ -0,0 +1,302 @@
|
|
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 DirtyTracking
|
17
|
+
|
18
|
+
def self.included(sub_class)
|
19
|
+
sub_class.extend(DirtyTrackingClassMethods)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @private
|
23
|
+
#
|
24
|
+
# @override initialize(*)
|
25
|
+
def initialize(*)
|
26
|
+
super.tap { @dirty_data = {} }
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns +true+ if the specified attribute has any dirty changes, +false+ otherwise.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# class Model
|
33
|
+
# include Aws::Record
|
34
|
+
# integer_attr :id, hash_key: true
|
35
|
+
# string_attr :name
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# model.name_dirty? # => false
|
39
|
+
# model.name # => 'Alex'
|
40
|
+
# model.name = 'Nick'
|
41
|
+
# model.name_dirty? # => true
|
42
|
+
#
|
43
|
+
# @param [String, Symbol] name The name of the attribute to to check for dirty changes.
|
44
|
+
# @return [Boolean] +true+ if the specified attribute has any dirty changes, +false+ otherwise.
|
45
|
+
def attribute_dirty?(name)
|
46
|
+
@dirty_data.has_key?(name)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns the original value of the specified attribute.
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
# class Model
|
53
|
+
# include Aws::Record
|
54
|
+
# integer_attr :id, hash_key: true
|
55
|
+
# string_attr :name
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# model.name # => 'Alex'
|
59
|
+
# model.name = 'Nick'
|
60
|
+
# model.name_was # => 'Alex'
|
61
|
+
#
|
62
|
+
# @param [String, Symbol] name The name of the attribute to retrieve the original value of.
|
63
|
+
# @return [Object] The original value of the specified attribute.
|
64
|
+
def attribute_was(name)
|
65
|
+
attribute_dirty?(name) ? @dirty_data[name] : @data[name]
|
66
|
+
end
|
67
|
+
|
68
|
+
# Mark that an attribute is changing. This is useful in situations where it is necessary to track that the value of an
|
69
|
+
# attribute is changing in-place.
|
70
|
+
#
|
71
|
+
# @example
|
72
|
+
# class Model
|
73
|
+
# include Aws::Record
|
74
|
+
# integer_attr :id, hash_key: true
|
75
|
+
# string_attr :name
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# model.name # => 'Alex'
|
79
|
+
# model.name_dirty? # => false
|
80
|
+
# model.name_was # => 'Alex'
|
81
|
+
#
|
82
|
+
# model.name << 'i'
|
83
|
+
# model.name # => 'Alexi'
|
84
|
+
#
|
85
|
+
# # The change was made in place. Since the String instance representing
|
86
|
+
# # the value of name is the same as it was originally, the change is not
|
87
|
+
# # detected.
|
88
|
+
# model.name_dirty? # => false
|
89
|
+
# model.name_was # => 'Alexi'
|
90
|
+
#
|
91
|
+
# model.name_dirty!
|
92
|
+
# model.name_dirty? # => true
|
93
|
+
# model.name_was # => 'Alexi'
|
94
|
+
#
|
95
|
+
# model.name << 's'
|
96
|
+
# model.name # => 'Alexis'
|
97
|
+
# model.name_dirty? # => true
|
98
|
+
# model.name_was # => 'Alexi'
|
99
|
+
#
|
100
|
+
# @param [String, Symbol] name The name of the attribute to mark as
|
101
|
+
# changing.
|
102
|
+
def attribute_dirty!(name)
|
103
|
+
return if attribute_dirty?(name)
|
104
|
+
|
105
|
+
current_value = @data[name]
|
106
|
+
|
107
|
+
@dirty_data[name] =
|
108
|
+
begin
|
109
|
+
current_value.clone
|
110
|
+
rescue TypeError
|
111
|
+
current_value
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Marks the changes as applied by clearing the current changes and making
|
116
|
+
# them accessible through +previous_changes+.
|
117
|
+
#
|
118
|
+
# # @example
|
119
|
+
# class Model
|
120
|
+
# include Aws::Record
|
121
|
+
# integer_attr :id, hash_key: true
|
122
|
+
# string_attr :name
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# model.name # => 'Alex'
|
126
|
+
# model.name = 'Nick'
|
127
|
+
# model.dirty? # => true
|
128
|
+
#
|
129
|
+
# model.clean!
|
130
|
+
# model.dirty? # false
|
131
|
+
#
|
132
|
+
def clean!
|
133
|
+
@dirty_data.clear
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns an array with the name of the attributes with dirty changes.
|
137
|
+
#
|
138
|
+
# @example
|
139
|
+
# class Model
|
140
|
+
# include Aws::Record
|
141
|
+
# integer_attr :id, hash_key: true
|
142
|
+
# string_attr :name
|
143
|
+
# end
|
144
|
+
#
|
145
|
+
# model.dirty # => []
|
146
|
+
# model.name # => 'Alex'
|
147
|
+
# model.name = 'Nick'
|
148
|
+
# model.dirty # => ['name']
|
149
|
+
#
|
150
|
+
# @return [Array] The names of attributes with dirty changes.
|
151
|
+
def dirty
|
152
|
+
@dirty_data.keys
|
153
|
+
end
|
154
|
+
|
155
|
+
# Returns +true+ if any attributes have dirty changes, +false+ otherwise.
|
156
|
+
#
|
157
|
+
# @example
|
158
|
+
# class Model
|
159
|
+
# include Aws::Record
|
160
|
+
# integer_attr :id, hash_key: true
|
161
|
+
# string_attr :name
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
# model.dirty? # => false
|
165
|
+
# model.name # => 'Alex'
|
166
|
+
# model.name = 'Nick'
|
167
|
+
# model.dirty? # => true
|
168
|
+
#
|
169
|
+
# @return [Boolean] +true+ if any attributes have dirty changes, +false+
|
170
|
+
# otherwise.
|
171
|
+
def dirty?
|
172
|
+
@dirty_data.size > 0
|
173
|
+
end
|
174
|
+
|
175
|
+
# Fetches attributes for this instance of an item from Amazon DynamoDB
|
176
|
+
# using its primary key and the +find(*)+ class method.
|
177
|
+
#
|
178
|
+
# @raise [Aws::Record::Errors::NotFound] if no record exists in the
|
179
|
+
# database matching the primary key of the item instance.
|
180
|
+
#
|
181
|
+
# @return [self] Returns the item instance.
|
182
|
+
def reload!
|
183
|
+
primary_key = self.class.keys.values.inject({}) do |memo, key|
|
184
|
+
memo[key] = send(key)
|
185
|
+
memo
|
186
|
+
end
|
187
|
+
|
188
|
+
record = self.class.find(primary_key)
|
189
|
+
|
190
|
+
unless record.nil?
|
191
|
+
@data = record.instance_variable_get("@data")
|
192
|
+
else
|
193
|
+
raise Errors::NotFound.new("No record found")
|
194
|
+
end
|
195
|
+
|
196
|
+
clean!
|
197
|
+
|
198
|
+
self
|
199
|
+
end
|
200
|
+
|
201
|
+
# Restores the attribute specified to its original value.
|
202
|
+
#
|
203
|
+
# @example
|
204
|
+
# class Model
|
205
|
+
# include Aws::Record
|
206
|
+
# integer_attr :id, hash_key: true
|
207
|
+
# string_attr :name
|
208
|
+
# end
|
209
|
+
#
|
210
|
+
# model.name # => 'Alex'
|
211
|
+
# model.name = 'Nick'
|
212
|
+
# model.rollback_attribute!(:name)
|
213
|
+
# model.name # => 'Alex'
|
214
|
+
#
|
215
|
+
# @param [String, Symbol] name The name of the attribute to restore
|
216
|
+
def rollback_attribute!(name)
|
217
|
+
return unless attribute_dirty?(name)
|
218
|
+
|
219
|
+
@data[name] = @dirty_data.delete(name)
|
220
|
+
end
|
221
|
+
|
222
|
+
# Restores all attributes to their original values.
|
223
|
+
#
|
224
|
+
# @example
|
225
|
+
# class Model
|
226
|
+
# include Aws::Record
|
227
|
+
# integer_attr :id, hash_key: true
|
228
|
+
# string_attr :name
|
229
|
+
# end
|
230
|
+
#
|
231
|
+
# model.name # => 'Alex'
|
232
|
+
# model.name = 'Nick'
|
233
|
+
# model.rollback!
|
234
|
+
# model.name # => 'Alex'
|
235
|
+
#
|
236
|
+
# @param [Array, String, Symbol] names The names of attributes to restore.
|
237
|
+
def rollback!(names = dirty)
|
238
|
+
Array(names).each { |name| rollback_attribute!(name) }
|
239
|
+
end
|
240
|
+
|
241
|
+
# @private
|
242
|
+
#
|
243
|
+
# @override save(*)
|
244
|
+
def save(*)
|
245
|
+
super.tap { clean! }
|
246
|
+
end
|
247
|
+
|
248
|
+
private
|
249
|
+
|
250
|
+
# @private
|
251
|
+
#
|
252
|
+
# @override write_attribute(*)
|
253
|
+
def write_attribute(name, attribute, value)
|
254
|
+
if value == attribute_was(name)
|
255
|
+
@dirty_data.delete(name)
|
256
|
+
else
|
257
|
+
attribute_dirty!(name)
|
258
|
+
end
|
259
|
+
|
260
|
+
super
|
261
|
+
end
|
262
|
+
|
263
|
+
|
264
|
+
module DirtyTrackingClassMethods
|
265
|
+
|
266
|
+
private
|
267
|
+
|
268
|
+
# @private
|
269
|
+
#
|
270
|
+
# @override build_item_from_resp(*)
|
271
|
+
def build_item_from_resp(*)
|
272
|
+
super.tap { |item| item.clean! }
|
273
|
+
end
|
274
|
+
|
275
|
+
# @private
|
276
|
+
#
|
277
|
+
# @override define_attr_methods(*)
|
278
|
+
def define_attr_methods(name, attribute)
|
279
|
+
super.tap do
|
280
|
+
define_method("#{name}_dirty?") do
|
281
|
+
attribute_dirty?(name)
|
282
|
+
end
|
283
|
+
|
284
|
+
define_method("#{name}_dirty!") do
|
285
|
+
attribute_dirty!(name)
|
286
|
+
end
|
287
|
+
|
288
|
+
define_method("#{name}_was") do
|
289
|
+
attribute_was(name)
|
290
|
+
end
|
291
|
+
|
292
|
+
define_method("rollback_#{name}!") do
|
293
|
+
rollback_attribute!(name)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
@@ -18,6 +18,7 @@ module Aws
|
|
18
18
|
class KeyMissing < RuntimeError; end
|
19
19
|
class NameCollision < RuntimeError; end
|
20
20
|
class ReservedName < RuntimeError; end
|
21
|
+
class NotFound < RuntimeError; end
|
21
22
|
class InvalidModel < RuntimeError; end
|
22
23
|
class TableDoesNotExist < RuntimeError; end
|
23
24
|
|
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.4
|
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-02-
|
11
|
+
date: 2016-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-resources
|
@@ -45,6 +45,7 @@ files:
|
|
45
45
|
- lib/aws-record/record/attributes/numeric_set_marshaler.rb
|
46
46
|
- lib/aws-record/record/attributes/string_marshaler.rb
|
47
47
|
- lib/aws-record/record/attributes/string_set_marshaler.rb
|
48
|
+
- lib/aws-record/record/dirty_tracking.rb
|
48
49
|
- lib/aws-record/record/errors.rb
|
49
50
|
- lib/aws-record/record/item_collection.rb
|
50
51
|
- lib/aws-record/record/item_operations.rb
|