aws-record 1.0.0.pre.8 → 1.0.0.pre.9
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 +11 -11
- data/lib/aws-record/record.rb +21 -0
- data/lib/aws-record/record/attribute.rb +35 -3
- data/lib/aws-record/record/attributes.rb +137 -16
- data/lib/aws-record/record/dirty_tracking.rb +48 -8
- data/lib/aws-record/record/item_operations.rb +96 -48
- data/lib/aws-record/record/marshalers/boolean_marshaler.rb +53 -0
- data/lib/aws-record/record/marshalers/date_marshaler.rb +61 -0
- data/lib/aws-record/record/marshalers/date_time_marshaler.rb +72 -0
- data/lib/aws-record/record/marshalers/float_marshaler.rb +52 -0
- data/lib/aws-record/record/marshalers/integer_marshaler.rb +52 -0
- data/lib/aws-record/record/marshalers/list_marshaler.rb +56 -0
- data/lib/aws-record/record/marshalers/map_marshaler.rb +56 -0
- data/lib/aws-record/record/marshalers/numeric_set_marshaler.rb +69 -0
- data/lib/aws-record/record/marshalers/string_marshaler.rb +52 -0
- data/lib/aws-record/record/marshalers/string_set_marshaler.rb +69 -0
- data/lib/aws-record/record/version.rb +1 -1
- metadata +12 -13
- data/lib/aws-record/record/attributes/boolean_marshaler.rb +0 -54
- data/lib/aws-record/record/attributes/date_marshaler.rb +0 -54
- data/lib/aws-record/record/attributes/date_time_marshaler.rb +0 -55
- data/lib/aws-record/record/attributes/float_marshaler.rb +0 -53
- data/lib/aws-record/record/attributes/integer_marshaler.rb +0 -53
- data/lib/aws-record/record/attributes/list_marshaler.rb +0 -66
- data/lib/aws-record/record/attributes/map_marshaler.rb +0 -66
- data/lib/aws-record/record/attributes/numeric_set_marshaler.rb +0 -72
- data/lib/aws-record/record/attributes/string_marshaler.rb +0 -60
- data/lib/aws-record/record/attributes/string_set_marshaler.rb +0 -70
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e20ddd5caa633c5ac1a7acb5e0e6cacfeed52595
|
4
|
+
data.tar.gz: 7317f916341e270b2418d54753a7c0d20540cd7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be783b2361e461595023f044f6147d0bf6935c5a15bbfa585d9cf97b92f63faad4c4d585da6827ec4a93dc1e8581c8e1c7774a400463236695554647a6edb5b0
|
7
|
+
data.tar.gz: 6c22f85ad6a3ca6455d0ac8d04de0bc8849605818605130a430ee7789c47f9088d219f4d363790e6dc3224fc4b22c352b0447b4e61e4be141af7a8295a7f972a
|
data/lib/aws-record.rb
CHANGED
@@ -28,17 +28,17 @@ module Aws
|
|
28
28
|
autoload :TableMigration, 'aws-record/record/table_migration'
|
29
29
|
autoload :VERSION, 'aws-record/record/version'
|
30
30
|
|
31
|
-
module
|
32
|
-
autoload :StringMarshaler,
|
33
|
-
autoload :BooleanMarshaler,
|
34
|
-
autoload :IntegerMarshaler,
|
35
|
-
autoload :FloatMarshaler,
|
36
|
-
autoload :DateMarshaler,
|
37
|
-
autoload :DateTimeMarshaler,
|
38
|
-
autoload :ListMarshaler,
|
39
|
-
autoload :MapMarshaler,
|
40
|
-
autoload :StringSetMarshaler,
|
41
|
-
autoload :NumericSetMarshaler, 'aws-record/record/
|
31
|
+
module Marshalers
|
32
|
+
autoload :StringMarshaler, 'aws-record/record/marshalers/string_marshaler'
|
33
|
+
autoload :BooleanMarshaler, 'aws-record/record/marshalers/boolean_marshaler'
|
34
|
+
autoload :IntegerMarshaler, 'aws-record/record/marshalers/integer_marshaler'
|
35
|
+
autoload :FloatMarshaler, 'aws-record/record/marshalers/float_marshaler'
|
36
|
+
autoload :DateMarshaler, 'aws-record/record/marshalers/date_marshaler'
|
37
|
+
autoload :DateTimeMarshaler, 'aws-record/record/marshalers/date_time_marshaler'
|
38
|
+
autoload :ListMarshaler, 'aws-record/record/marshalers/list_marshaler'
|
39
|
+
autoload :MapMarshaler, 'aws-record/record/marshalers/map_marshaler'
|
40
|
+
autoload :StringSetMarshaler, 'aws-record/record/marshalers/string_set_marshaler'
|
41
|
+
autoload :NumericSetMarshaler, 'aws-record/record/marshalers/numeric_set_marshaler'
|
42
42
|
end
|
43
43
|
|
44
44
|
end
|
data/lib/aws-record/record.rb
CHANGED
@@ -50,6 +50,7 @@ module Aws
|
|
50
50
|
# # Attribute definitions go here...
|
51
51
|
# end
|
52
52
|
def self.included(sub_class)
|
53
|
+
@track_mutations = true
|
53
54
|
sub_class.send(:extend, RecordClassMethods)
|
54
55
|
sub_class.send(:include, Attributes)
|
55
56
|
sub_class.send(:include, ItemOperations)
|
@@ -183,6 +184,26 @@ module Aws
|
|
183
184
|
@dynamodb_client ||= configure_client
|
184
185
|
end
|
185
186
|
|
187
|
+
# Turns off mutation tracking for all attributes in the model.
|
188
|
+
def disable_mutation_tracking
|
189
|
+
@track_mutations = false
|
190
|
+
end
|
191
|
+
|
192
|
+
# Turns on mutation tracking for all attributes in the model. Note that
|
193
|
+
# mutation tracking is on by default, so you generally would not need to
|
194
|
+
# call this. It is provided in case there is a need to dynamically turn
|
195
|
+
# this feature on and off, though that would be generally discouraged and
|
196
|
+
# could cause inaccurate mutation tracking at runtime.
|
197
|
+
def enable_mutation_tracking
|
198
|
+
@track_mutations = true
|
199
|
+
end
|
200
|
+
|
201
|
+
# @return [Boolean] true if mutation tracking is enabled at the model
|
202
|
+
# level, false otherwise.
|
203
|
+
def mutation_tracking_enabled?
|
204
|
+
@track_mutations == false ? false : true
|
205
|
+
end
|
206
|
+
|
186
207
|
private
|
187
208
|
def _user_agent(custom)
|
188
209
|
if custom
|
@@ -21,7 +21,7 @@ module Aws
|
|
21
21
|
# within the model class and item instances.
|
22
22
|
class Attribute
|
23
23
|
|
24
|
-
attr_reader :name, :database_name, :dynamodb_type
|
24
|
+
attr_reader :name, :database_name, :dynamodb_type, :default_value
|
25
25
|
|
26
26
|
# @param [Symbol] name Name of the attribute. It should be a name that is
|
27
27
|
# safe to use as a method.
|
@@ -39,11 +39,27 @@ module Aws
|
|
39
39
|
# "M", "L". Optional if this attribute will never be used for a key or
|
40
40
|
# secondary index, but most convenience methods for setting attributes
|
41
41
|
# will provide this.
|
42
|
+
# @option options [Boolean] :mutation_tracking Optional attribute used to
|
43
|
+
# indicate whether mutations to values should be explicitly tracked when
|
44
|
+
# determining if a value is "dirty". Important for collection types
|
45
|
+
# which are often primarily modified by mutation of a single object
|
46
|
+
# reference. By default, is false.
|
47
|
+
# @option options [Boolean] :persist_nil Optional attribute used to
|
48
|
+
# indicate whether nil values should be persisted. If true, explicitly
|
49
|
+
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
50
|
+
# nil values will be ignored and not persisted. By default, is false.
|
51
|
+
# @option options [Object] :default_value Optional attribute used to
|
52
|
+
# define a "default value" to be used if the attribute's value on an
|
53
|
+
# item is nil or not set at persistence time.
|
42
54
|
def initialize(name, options = {})
|
43
55
|
@name = name
|
44
56
|
@database_name = options[:database_attribute_name] || name.to_s
|
45
57
|
@dynamodb_type = options[:dynamodb_type]
|
46
58
|
@marshaler = options[:marshaler] || DefaultMarshaler
|
59
|
+
@mutation_tracking = options[:mutation_tracking]
|
60
|
+
@persist_nil = options[:persist_nil]
|
61
|
+
dv = options[:default_value]
|
62
|
+
@default_value = type_cast(dv) unless dv.nil?
|
47
63
|
end
|
48
64
|
|
49
65
|
# Attempts to type cast a raw value into the attribute's type. This call
|
@@ -52,7 +68,9 @@ module Aws
|
|
52
68
|
# @return [Object] the type cast object. Return type is dependent on the
|
53
69
|
# marshaler used. See your attribute's marshaler class for details.
|
54
70
|
def type_cast(raw_value)
|
55
|
-
@marshaler.type_cast(raw_value)
|
71
|
+
cast_value = @marshaler.type_cast(raw_value)
|
72
|
+
cast_value = default_value if cast_value.nil?
|
73
|
+
cast_value
|
56
74
|
end
|
57
75
|
|
58
76
|
# Attempts to serialize a raw value into the attribute's serialized
|
@@ -62,7 +80,21 @@ module Aws
|
|
62
80
|
# @return [Object] the serialized object. Return type is dependent on the
|
63
81
|
# marshaler used. See your attribute's marshaler class for details.
|
64
82
|
def serialize(raw_value)
|
65
|
-
|
83
|
+
cast_value = type_cast(raw_value)
|
84
|
+
cast_value = default_value if cast_value.nil?
|
85
|
+
@marshaler.serialize(cast_value)
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [Boolean] true if this attribute should do active mutation
|
89
|
+
# tracking, false otherwise. Default: false
|
90
|
+
def track_mutations?
|
91
|
+
@mutation_tracking ? true : false
|
92
|
+
end
|
93
|
+
|
94
|
+
# @return [Boolean] true if this attribute will actively persist nil
|
95
|
+
# values, false otherwise. Default: false
|
96
|
+
def persist_nil?
|
97
|
+
@persist_nil ? true : false
|
66
98
|
end
|
67
99
|
|
68
100
|
# @api private
|
@@ -87,6 +87,18 @@ module Aws
|
|
87
87
|
# "M", "L". Optional if this attribute will never be used for a key or
|
88
88
|
# secondary index, but most convenience methods for setting attributes
|
89
89
|
# will provide this.
|
90
|
+
# @option opts [Boolean] :mutation_tracking Optional attribute used to
|
91
|
+
# indicate whether mutations to values should be explicitly tracked
|
92
|
+
# when determining if a value is "dirty". Important for collection
|
93
|
+
# types which are often primarily modified by mutation of a single
|
94
|
+
# object reference. By default, is false.
|
95
|
+
# @option opts [Boolean] :persist_nil Optional attribute used to
|
96
|
+
# indicate whether nil values should be persisted. If true, explicitly
|
97
|
+
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
98
|
+
# nil values will be ignored and not persisted. By default, is false.
|
99
|
+
# @option opts [Object] :default_value Optional attribute used to
|
100
|
+
# define a "default value" to be used if the attribute's value on an
|
101
|
+
# item is nil or not set at persistence time.
|
90
102
|
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
91
103
|
# the hash key for the table.
|
92
104
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
@@ -118,9 +130,21 @@ module Aws
|
|
118
130
|
# the hash key for the table.
|
119
131
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
120
132
|
# the range key for the table.
|
133
|
+
# @option opts [Boolean] :mutation_tracking Optional attribute used to
|
134
|
+
# indicate if mutations to values should be explicitly tracked when
|
135
|
+
# determining if a value is "dirty". Important for collection types
|
136
|
+
# which are often primarily modified by mutation of a single object
|
137
|
+
# reference. By default, is false.
|
138
|
+
# @option opts [Boolean] :persist_nil Optional attribute used to
|
139
|
+
# indicate whether nil values should be persisted. If true, explicitly
|
140
|
+
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
141
|
+
# nil values will be ignored and not persisted. By default, is false.
|
142
|
+
# @option opts [Object] :default_value Optional attribute used to
|
143
|
+
# define a "default value" to be used if the attribute's value on an
|
144
|
+
# item is nil or not set at persistence time.
|
121
145
|
def string_attr(name, opts = {})
|
122
146
|
opts[:dynamodb_type] = "S"
|
123
|
-
attr(name,
|
147
|
+
attr(name, Marshalers::StringMarshaler.new(opts), opts)
|
124
148
|
end
|
125
149
|
|
126
150
|
# Define a boolean-type attribute for your model.
|
@@ -132,9 +156,21 @@ module Aws
|
|
132
156
|
# the hash key for the table.
|
133
157
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
134
158
|
# the range key for the table.
|
159
|
+
# @option opts [Boolean] :mutation_tracking Optional attribute used to
|
160
|
+
# indicate if mutations to values should be explicitly tracked when
|
161
|
+
# determining if a value is "dirty". Important for collection types
|
162
|
+
# which are often primarily modified by mutation of a single object
|
163
|
+
# reference. By default, is false.
|
164
|
+
# @option opts [Boolean] :persist_nil Optional attribute used to
|
165
|
+
# indicate whether nil values should be persisted. If true, explicitly
|
166
|
+
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
167
|
+
# nil values will be ignored and not persisted. By default, is false.
|
168
|
+
# @option opts [Object] :default_value Optional attribute used to
|
169
|
+
# define a "default value" to be used if the attribute's value on an
|
170
|
+
# item is nil or not set at persistence time.
|
135
171
|
def boolean_attr(name, opts = {})
|
136
172
|
opts[:dynamodb_type] = "BOOL"
|
137
|
-
attr(name,
|
173
|
+
attr(name, Marshalers::BooleanMarshaler.new(opts), opts)
|
138
174
|
end
|
139
175
|
|
140
176
|
# Define a integer-type attribute for your model.
|
@@ -146,9 +182,21 @@ module Aws
|
|
146
182
|
# the hash key for the table.
|
147
183
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
148
184
|
# the range key for the table.
|
185
|
+
# @option opts [Boolean] :mutation_tracking Optional attribute used to
|
186
|
+
# indicate if mutations to values should be explicitly tracked when
|
187
|
+
# determining if a value is "dirty". Important for collection types
|
188
|
+
# which are often primarily modified by mutation of a single object
|
189
|
+
# reference. By default, is false.
|
190
|
+
# @option opts [Boolean] :persist_nil Optional attribute used to
|
191
|
+
# indicate whether nil values should be persisted. If true, explicitly
|
192
|
+
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
193
|
+
# nil values will be ignored and not persisted. By default, is false.
|
194
|
+
# @option opts [Object] :default_value Optional attribute used to
|
195
|
+
# define a "default value" to be used if the attribute's value on an
|
196
|
+
# item is nil or not set at persistence time.
|
149
197
|
def integer_attr(name, opts = {})
|
150
198
|
opts[:dynamodb_type] = "N"
|
151
|
-
attr(name,
|
199
|
+
attr(name, Marshalers::IntegerMarshaler.new(opts), opts)
|
152
200
|
end
|
153
201
|
|
154
202
|
# Define a float-type attribute for your model.
|
@@ -160,9 +208,21 @@ module Aws
|
|
160
208
|
# the hash key for the table.
|
161
209
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
162
210
|
# the range key for the table.
|
211
|
+
# @option opts [Boolean] :mutation_tracking Optional attribute used to
|
212
|
+
# indicate if mutations to values should be explicitly tracked when
|
213
|
+
# determining if a value is "dirty". Important for collection types
|
214
|
+
# which are often primarily modified by mutation of a single object
|
215
|
+
# reference. By default, is false.
|
216
|
+
# @option opts [Boolean] :persist_nil Optional attribute used to
|
217
|
+
# indicate whether nil values should be persisted. If true, explicitly
|
218
|
+
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
219
|
+
# nil values will be ignored and not persisted. By default, is false.
|
220
|
+
# @option opts [Object] :default_value Optional attribute used to
|
221
|
+
# define a "default value" to be used if the attribute's value on an
|
222
|
+
# item is nil or not set at persistence time.
|
163
223
|
def float_attr(name, opts = {})
|
164
224
|
opts[:dynamodb_type] = "N"
|
165
|
-
attr(name,
|
225
|
+
attr(name, Marshalers::FloatMarshaler.new(opts), opts)
|
166
226
|
end
|
167
227
|
|
168
228
|
# Define a date-type attribute for your model.
|
@@ -174,9 +234,21 @@ module Aws
|
|
174
234
|
# the hash key for the table.
|
175
235
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
176
236
|
# the range key for the table.
|
237
|
+
# @option opts [Boolean] :mutation_tracking Optional attribute used to
|
238
|
+
# indicate if mutations to values should be explicitly tracked when
|
239
|
+
# determining if a value is "dirty". Important for collection types
|
240
|
+
# which are often primarily modified by mutation of a single object
|
241
|
+
# reference. By default, is false.
|
242
|
+
# @option opts [Boolean] :persist_nil Optional attribute used to
|
243
|
+
# indicate whether nil values should be persisted. If true, explicitly
|
244
|
+
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
245
|
+
# nil values will be ignored and not persisted. By default, is false.
|
246
|
+
# @option options [Object] :default_value Optional attribute used to
|
247
|
+
# define a "default value" to be used if the attribute's value on an
|
248
|
+
# item is nil or not set at persistence time.
|
177
249
|
def date_attr(name, opts = {})
|
178
250
|
opts[:dynamodb_type] = "S"
|
179
|
-
attr(name,
|
251
|
+
attr(name, Marshalers::DateMarshaler.new(opts), opts)
|
180
252
|
end
|
181
253
|
|
182
254
|
# Define a datetime-type attribute for your model.
|
@@ -188,9 +260,21 @@ module Aws
|
|
188
260
|
# the hash key for the table.
|
189
261
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
190
262
|
# the range key for the table.
|
263
|
+
# @option opts [Boolean] :mutation_tracking Optional attribute used to
|
264
|
+
# indicate if mutations to values should be explicitly tracked when
|
265
|
+
# determining if a value is "dirty". Important for collection types
|
266
|
+
# which are often primarily modified by mutation of a single object
|
267
|
+
# reference. By default, is false.
|
268
|
+
# @option opts [Boolean] :persist_nil Optional attribute used to
|
269
|
+
# indicate whether nil values should be persisted. If true, explicitly
|
270
|
+
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
271
|
+
# nil values will be ignored and not persisted. By default, is false.
|
272
|
+
# @option opts [Object] :default_value Optional attribute used to
|
273
|
+
# define a "default value" to be used if the attribute's value on an
|
274
|
+
# item is nil or not set at persistence time.
|
191
275
|
def datetime_attr(name, opts = {})
|
192
276
|
opts[:dynamodb_type] = "S"
|
193
|
-
attr(name,
|
277
|
+
attr(name, Marshalers::DateTimeMarshaler.new(opts), opts)
|
194
278
|
end
|
195
279
|
|
196
280
|
# Define a list-type attribute for your model.
|
@@ -216,16 +300,22 @@ module Aws
|
|
216
300
|
# @param [Symbol] name Name of this attribute. It should be a name that
|
217
301
|
# is safe to use as a method.
|
218
302
|
# @param [Hash] opts
|
219
|
-
# @option opts [Boolean] :nil_as_empty_list Set to true if this
|
220
|
-
# attribute should interpret nil values as an empty list. If false,
|
221
|
-
# nil values will remain nil.
|
222
303
|
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
223
304
|
# the hash key for the table.
|
224
305
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
225
306
|
# the range key for the table.
|
307
|
+
# @option opts [Boolean] :mutation_tracking Optional attribute used to
|
308
|
+
# indicate if mutations to values should be explicitly tracked when
|
309
|
+
# determining if a value is "dirty". Important for collection types
|
310
|
+
# which are often primarily modified by mutation of a single object
|
311
|
+
# reference. By default, is true.
|
312
|
+
# @option opts [Object] :default_value Optional attribute used to
|
313
|
+
# define a "default value" to be used if the attribute's value on an
|
314
|
+
# item is nil or not set at persistence time.
|
226
315
|
def list_attr(name, opts = {})
|
227
316
|
opts[:dynamodb_type] = "L"
|
228
|
-
|
317
|
+
opts[:mutation_tracking] = true if opts[:mutation_tracking].nil?
|
318
|
+
attr(name, Marshalers::ListMarshaler.new(opts), opts)
|
229
319
|
end
|
230
320
|
|
231
321
|
# Define a map-type attribute for your model.
|
@@ -251,16 +341,22 @@ module Aws
|
|
251
341
|
# @param [Symbol] name Name of this attribute. It should be a name that
|
252
342
|
# is safe to use as a method.
|
253
343
|
# @param [Hash] opts
|
254
|
-
# @option opts [Boolean] :nil_as_empty_map Set to true if this
|
255
|
-
# attribute should interpret nil values as an empty hash. If false,
|
256
|
-
# nil values will remain nil.
|
257
344
|
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
258
345
|
# the hash key for the table.
|
259
346
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
260
347
|
# the range key for the table.
|
348
|
+
# @option opts [Boolean] :mutation_tracking Optional attribute used to
|
349
|
+
# indicate if mutations to values should be explicitly tracked when
|
350
|
+
# determining if a value is "dirty". Important for collection types
|
351
|
+
# which are often primarily modified by mutation of a single object
|
352
|
+
# reference. By default, is true.
|
353
|
+
# @option opts [Object] :default_value Optional attribute used to
|
354
|
+
# define a "default value" to be used if the attribute's value on an
|
355
|
+
# item is nil or not set at persistence time.
|
261
356
|
def map_attr(name, opts = {})
|
262
357
|
opts[:dynamodb_type] = "M"
|
263
|
-
|
358
|
+
opts[:mutation_tracking] = true if opts[:mutation_tracking].nil?
|
359
|
+
attr(name, Marshalers::MapMarshaler.new(opts), opts)
|
264
360
|
end
|
265
361
|
|
266
362
|
# Define a string set attribute for your model.
|
@@ -280,9 +376,18 @@ module Aws
|
|
280
376
|
# the hash key for the table.
|
281
377
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
282
378
|
# the range key for the table.
|
379
|
+
# @option opts [Boolean] :mutation_tracking Optional attribute used to
|
380
|
+
# indicate if mutations to values should be explicitly tracked when
|
381
|
+
# determining if a value is "dirty". Important for collection types
|
382
|
+
# which are often primarily modified by mutation of a single object
|
383
|
+
# reference. By default, is true.
|
384
|
+
# @option opts [Object] :default_value Optional attribute used to
|
385
|
+
# define a "default value" to be used if the attribute's value on an
|
386
|
+
# item is nil or not set at persistence time.
|
283
387
|
def string_set_attr(name, opts = {})
|
284
388
|
opts[:dynamodb_type] = "SS"
|
285
|
-
|
389
|
+
opts[:mutation_tracking] = true if opts[:mutation_tracking].nil?
|
390
|
+
attr(name, Marshalers::StringSetMarshaler.new(opts), opts)
|
286
391
|
end
|
287
392
|
|
288
393
|
# Define a numeric set attribute for your model.
|
@@ -302,9 +407,18 @@ module Aws
|
|
302
407
|
# the hash key for the table.
|
303
408
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
304
409
|
# the range key for the table.
|
410
|
+
# @option opts [Boolean] :mutation_tracking Optional attribute used to
|
411
|
+
# indicate if mutations to values should be explicitly tracked when
|
412
|
+
# determining if a value is "dirty". Important for collection types
|
413
|
+
# which are often primarily modified by mutation of a single object
|
414
|
+
# reference. By default, is true.
|
415
|
+
# @option opts [Object] :default_value Optional attribute used to
|
416
|
+
# define a "default value" to be used if the attribute's value on an
|
417
|
+
# item is nil or not set at persistence time.
|
305
418
|
def numeric_set_attr(name, opts = {})
|
306
419
|
opts[:dynamodb_type] = "NS"
|
307
|
-
|
420
|
+
opts[:mutation_tracking] = true if opts[:mutation_tracking].nil?
|
421
|
+
attr(name, Marshalers::NumericSetMarshaler.new(opts), opts)
|
308
422
|
end
|
309
423
|
|
310
424
|
# @return [Hash] hash of symbolized attribute names to attribute objects
|
@@ -333,6 +447,13 @@ module Aws
|
|
333
447
|
@keys
|
334
448
|
end
|
335
449
|
|
450
|
+
# @param [Symbol] attr_sym The symbolized name of the attribute.
|
451
|
+
# @return [Boolean] true if object mutations are tracked for dirty
|
452
|
+
# checking of that attribute, false if mutations are not tracked.
|
453
|
+
def track_mutations?(attr_sym)
|
454
|
+
mutation_tracking_enabled? && attributes[attr_sym].track_mutations?
|
455
|
+
end
|
456
|
+
|
336
457
|
private
|
337
458
|
def define_attr_methods(name, attribute)
|
338
459
|
define_method(name) do
|
@@ -24,6 +24,7 @@ module Aws
|
|
24
24
|
# @override initialize(*)
|
25
25
|
def initialize(*)
|
26
26
|
@dirty_data = {}
|
27
|
+
@mutation_copies = {}
|
27
28
|
super
|
28
29
|
end
|
29
30
|
|
@@ -44,7 +45,7 @@ module Aws
|
|
44
45
|
# @param [String, Symbol] name The name of the attribute to to check for dirty changes.
|
45
46
|
# @return [Boolean] +true+ if the specified attribute has any dirty changes, +false+ otherwise.
|
46
47
|
def attribute_dirty?(name)
|
47
|
-
@dirty_data.has_key?(name)
|
48
|
+
@dirty_data.has_key?(name) || _mutated?(name)
|
48
49
|
end
|
49
50
|
|
50
51
|
# Returns the original value of the specified attribute.
|
@@ -63,7 +64,11 @@ module Aws
|
|
63
64
|
# @param [String, Symbol] name The name of the attribute to retrieve the original value of.
|
64
65
|
# @return [Object] The original value of the specified attribute.
|
65
66
|
def attribute_was(name)
|
66
|
-
|
67
|
+
if @mutation_copies.has_key?(name)
|
68
|
+
@mutation_copies[name]
|
69
|
+
else
|
70
|
+
attribute_dirty?(name) ? @dirty_data[name] : @data[name]
|
71
|
+
end
|
67
72
|
end
|
68
73
|
|
69
74
|
# Mark that an attribute is changing. This is useful in situations where it is necessary to track that the value of an
|
@@ -107,7 +112,7 @@ module Aws
|
|
107
112
|
|
108
113
|
@dirty_data[name] =
|
109
114
|
begin
|
110
|
-
current_value
|
115
|
+
_deep_copy(current_value)
|
111
116
|
rescue TypeError
|
112
117
|
current_value
|
113
118
|
end
|
@@ -132,6 +137,13 @@ module Aws
|
|
132
137
|
#
|
133
138
|
def clean!
|
134
139
|
@dirty_data.clear
|
140
|
+
self.class.attributes.each do |name, attribute|
|
141
|
+
if self.class.track_mutations?(name)
|
142
|
+
if @data[name]
|
143
|
+
@mutation_copies[name] = _deep_copy(@data[name])
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
135
147
|
end
|
136
148
|
|
137
149
|
# Returns an array with the name of the attributes with dirty changes.
|
@@ -150,7 +162,13 @@ module Aws
|
|
150
162
|
#
|
151
163
|
# @return [Array] The names of attributes with dirty changes.
|
152
164
|
def dirty
|
153
|
-
@dirty_data.keys
|
165
|
+
ret = @dirty_data.keys.dup
|
166
|
+
@mutation_copies.each do |key, value|
|
167
|
+
if @data[key] != value
|
168
|
+
ret << key unless ret.include?(key)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
ret
|
154
172
|
end
|
155
173
|
|
156
174
|
# Returns +true+ if any attributes have dirty changes, +false+ otherwise.
|
@@ -170,7 +188,10 @@ module Aws
|
|
170
188
|
# @return [Boolean] +true+ if any attributes have dirty changes, +false+
|
171
189
|
# otherwise.
|
172
190
|
def dirty?
|
173
|
-
@dirty_data.size > 0
|
191
|
+
return true if @dirty_data.size > 0
|
192
|
+
@mutation_copies.any? do |name, value|
|
193
|
+
@mutation_copies[name] != @data[name]
|
194
|
+
end
|
174
195
|
end
|
175
196
|
|
176
197
|
# Fetches attributes for this instance of an item from Amazon DynamoDB
|
@@ -188,7 +209,7 @@ module Aws
|
|
188
209
|
|
189
210
|
record = self.class.find(primary_key)
|
190
211
|
|
191
|
-
unless record.nil?
|
212
|
+
unless record.nil?
|
192
213
|
@data = record.instance_variable_get("@data")
|
193
214
|
else
|
194
215
|
raise Errors::NotFound.new("No record found")
|
@@ -217,7 +238,12 @@ module Aws
|
|
217
238
|
def rollback_attribute!(name)
|
218
239
|
return unless attribute_dirty?(name)
|
219
240
|
|
220
|
-
|
241
|
+
if @mutation_copies.has_key?(name)
|
242
|
+
@data[name] = @mutation_copies[name]
|
243
|
+
@dirty_data.delete(name) if @dirty_data.has_key?(name)
|
244
|
+
else
|
245
|
+
@data[name] = @dirty_data.delete(name)
|
246
|
+
end
|
221
247
|
end
|
222
248
|
|
223
249
|
# Restores all attributes to their original values.
|
@@ -252,15 +278,29 @@ module Aws
|
|
252
278
|
#
|
253
279
|
# @override write_attribute(*)
|
254
280
|
def write_attribute(name, attribute, value)
|
281
|
+
_dirty_write_attribute(name, attribute, value)
|
282
|
+
super
|
283
|
+
end
|
284
|
+
|
285
|
+
def _dirty_write_attribute(name, attribute, value)
|
255
286
|
if value == attribute_was(name)
|
256
287
|
@dirty_data.delete(name)
|
257
288
|
else
|
258
289
|
attribute_dirty!(name)
|
259
290
|
end
|
291
|
+
end
|
260
292
|
|
261
|
-
|
293
|
+
def _mutated?(name)
|
294
|
+
if @mutation_copies.has_key?(name)
|
295
|
+
@data[name] != @mutation_copies[name]
|
296
|
+
else
|
297
|
+
false
|
298
|
+
end
|
262
299
|
end
|
263
300
|
|
301
|
+
def _deep_copy(obj)
|
302
|
+
Marshal.load(Marshal.dump(obj))
|
303
|
+
end
|
264
304
|
|
265
305
|
module DirtyTrackingClassMethods
|
266
306
|
|