aws-record 1.0.0.pre.9 → 1.0.0.pre.10
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 +3 -0
- data/lib/aws-record/record.rb +6 -0
- data/lib/aws-record/record/attribute.rb +0 -12
- data/lib/aws-record/record/attributes.rb +27 -164
- data/lib/aws-record/record/dirty_tracking.rb +12 -103
- data/lib/aws-record/record/item_collection.rb +3 -2
- data/lib/aws-record/record/item_data.rb +123 -0
- data/lib/aws-record/record/item_operations.rb +21 -35
- data/lib/aws-record/record/key_attributes.rb +54 -0
- data/lib/aws-record/record/model_attributes.rb +99 -0
- data/lib/aws-record/record/secondary_indexes.rb +5 -5
- data/lib/aws-record/record/table_migration.rb +6 -11
- data/lib/aws-record/record/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c99f94d8f0401d3de3c1886e58cc8af973cd5ec
|
4
|
+
data.tar.gz: b824eac6e13b8d37927ec34eb4cb24d39cf15063
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5e381404cc144a57792316da027c990f0d7b5600187e38afa9eb84c559fc1d0e896da300beee534f76eca4dbed21d90198db7b6740c3f261d2db5719a045865
|
7
|
+
data.tar.gz: 3c985a0bb11eed715c941f3138cc3195be3b34bad7b12f21d3e4ae0eccaf5de783015c4fab5bc099ea37c3e1bf64814c94b5644f9b8df8fc33a6661828ff496c
|
data/lib/aws-record.rb
CHANGED
@@ -22,7 +22,10 @@ module Aws
|
|
22
22
|
autoload :DirtyTracking, 'aws-record/record/dirty_tracking'
|
23
23
|
autoload :Errors, 'aws-record/record/errors'
|
24
24
|
autoload :ItemCollection, 'aws-record/record/item_collection'
|
25
|
+
autoload :ItemData, 'aws-record/record/item_data'
|
25
26
|
autoload :ItemOperations, 'aws-record/record/item_operations'
|
27
|
+
autoload :KeyAttributes, 'aws-record/record/key_attributes'
|
28
|
+
autoload :ModelAttributes, 'aws-record/record/model_attributes'
|
26
29
|
autoload :Query, 'aws-record/record/query'
|
27
30
|
autoload :SecondaryIndexes, 'aws-record/record/secondary_indexes'
|
28
31
|
autoload :TableMigration, 'aws-record/record/table_migration'
|
data/lib/aws-record/record.rb
CHANGED
@@ -204,6 +204,12 @@ module Aws
|
|
204
204
|
@track_mutations == false ? false : true
|
205
205
|
end
|
206
206
|
|
207
|
+
def model_valid?
|
208
|
+
if @keys.hash_key.nil?
|
209
|
+
raise Errors::InvalidModel.new("Table models must include a hash key")
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
207
213
|
private
|
208
214
|
def _user_agent(custom)
|
209
215
|
if custom
|
@@ -39,11 +39,6 @@ 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
42
|
# @option options [Boolean] :persist_nil Optional attribute used to
|
48
43
|
# indicate whether nil values should be persisted. If true, explicitly
|
49
44
|
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
@@ -56,7 +51,6 @@ module Aws
|
|
56
51
|
@database_name = options[:database_attribute_name] || name.to_s
|
57
52
|
@dynamodb_type = options[:dynamodb_type]
|
58
53
|
@marshaler = options[:marshaler] || DefaultMarshaler
|
59
|
-
@mutation_tracking = options[:mutation_tracking]
|
60
54
|
@persist_nil = options[:persist_nil]
|
61
55
|
dv = options[:default_value]
|
62
56
|
@default_value = type_cast(dv) unless dv.nil?
|
@@ -85,12 +79,6 @@ module Aws
|
|
85
79
|
@marshaler.serialize(cast_value)
|
86
80
|
end
|
87
81
|
|
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
82
|
# @return [Boolean] true if this attribute will actively persist nil
|
95
83
|
# values, false otherwise. Default: false
|
96
84
|
def persist_nil?
|
@@ -17,9 +17,9 @@ module Aws
|
|
17
17
|
|
18
18
|
def self.included(sub_class)
|
19
19
|
sub_class.extend(ClassMethods)
|
20
|
-
|
21
|
-
sub_class.instance_variable_set("@attributes",
|
22
|
-
sub_class.instance_variable_set("@
|
20
|
+
model_attributes = ModelAttributes.new(self)
|
21
|
+
sub_class.instance_variable_set("@attributes", model_attributes)
|
22
|
+
sub_class.instance_variable_set("@keys", KeyAttributes.new(model_attributes))
|
23
23
|
end
|
24
24
|
|
25
25
|
# @example Usage Example
|
@@ -40,7 +40,10 @@ module Aws
|
|
40
40
|
# attribute values you wish to set.
|
41
41
|
# @return [Aws::Record] An item instance for your model.
|
42
42
|
def initialize(attr_values = {})
|
43
|
-
|
43
|
+
opts = {
|
44
|
+
track_mutations: self.class.mutation_tracking_enabled?
|
45
|
+
}
|
46
|
+
@data = ItemData.new(self.class.attributes, opts)
|
44
47
|
attr_values.each do |attr_name, attr_value|
|
45
48
|
send("#{attr_name}=", attr_value)
|
46
49
|
end
|
@@ -50,23 +53,9 @@ module Aws
|
|
50
53
|
#
|
51
54
|
# @return [Hash] Map of attribute names to raw values.
|
52
55
|
def to_h
|
53
|
-
@data.
|
56
|
+
@data.hash_copy
|
54
57
|
end
|
55
58
|
|
56
|
-
private
|
57
|
-
|
58
|
-
# @private
|
59
|
-
def read_attribute(name, attribute)
|
60
|
-
raw = @data[name]
|
61
|
-
attribute.type_cast(raw)
|
62
|
-
end
|
63
|
-
|
64
|
-
# @private
|
65
|
-
def write_attribute(name, attribute, value)
|
66
|
-
@data[name] = value
|
67
|
-
end
|
68
|
-
|
69
|
-
|
70
59
|
module ClassMethods
|
71
60
|
|
72
61
|
# Define an attribute for your model, providing your own attribute type.
|
@@ -87,11 +76,6 @@ module Aws
|
|
87
76
|
# "M", "L". Optional if this attribute will never be used for a key or
|
88
77
|
# secondary index, but most convenience methods for setting attributes
|
89
78
|
# 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
79
|
# @option opts [Boolean] :persist_nil Optional attribute used to
|
96
80
|
# indicate whether nil values should be persisted. If true, explicitly
|
97
81
|
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
@@ -104,21 +88,9 @@ module Aws
|
|
104
88
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
105
89
|
# the range key for the table.
|
106
90
|
def attr(name, marshaler, opts = {})
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
attribute = Attribute.new(name, opts)
|
111
|
-
|
112
|
-
storage_name = attribute.database_name
|
113
|
-
|
114
|
-
check_for_naming_collisions(name, storage_name)
|
115
|
-
check_if_reserved(name)
|
116
|
-
|
117
|
-
@attributes[name] = attribute
|
118
|
-
@storage_attributes[storage_name] = name
|
119
|
-
|
120
|
-
define_attr_methods(name, attribute)
|
121
|
-
key_attributes(name, opts)
|
91
|
+
@attributes.register_attribute(name, marshaler, opts)
|
92
|
+
_define_attr_methods(name)
|
93
|
+
_key_attributes(name, opts)
|
122
94
|
end
|
123
95
|
|
124
96
|
# Define a string-type attribute for your model.
|
@@ -130,11 +102,6 @@ module Aws
|
|
130
102
|
# the hash key for the table.
|
131
103
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
132
104
|
# 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
105
|
# @option opts [Boolean] :persist_nil Optional attribute used to
|
139
106
|
# indicate whether nil values should be persisted. If true, explicitly
|
140
107
|
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
@@ -156,11 +123,6 @@ module Aws
|
|
156
123
|
# the hash key for the table.
|
157
124
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
158
125
|
# 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
126
|
# @option opts [Boolean] :persist_nil Optional attribute used to
|
165
127
|
# indicate whether nil values should be persisted. If true, explicitly
|
166
128
|
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
@@ -182,11 +144,6 @@ module Aws
|
|
182
144
|
# the hash key for the table.
|
183
145
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
184
146
|
# 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
147
|
# @option opts [Boolean] :persist_nil Optional attribute used to
|
191
148
|
# indicate whether nil values should be persisted. If true, explicitly
|
192
149
|
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
@@ -208,11 +165,6 @@ module Aws
|
|
208
165
|
# the hash key for the table.
|
209
166
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
210
167
|
# 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
168
|
# @option opts [Boolean] :persist_nil Optional attribute used to
|
217
169
|
# indicate whether nil values should be persisted. If true, explicitly
|
218
170
|
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
@@ -234,11 +186,6 @@ module Aws
|
|
234
186
|
# the hash key for the table.
|
235
187
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
236
188
|
# 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
189
|
# @option opts [Boolean] :persist_nil Optional attribute used to
|
243
190
|
# indicate whether nil values should be persisted. If true, explicitly
|
244
191
|
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
@@ -260,11 +207,6 @@ module Aws
|
|
260
207
|
# the hash key for the table.
|
261
208
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
262
209
|
# 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
210
|
# @option opts [Boolean] :persist_nil Optional attribute used to
|
269
211
|
# indicate whether nil values should be persisted. If true, explicitly
|
270
212
|
# set nil values will be saved to DynamoDB as a "null" type. If false,
|
@@ -304,17 +246,11 @@ module Aws
|
|
304
246
|
# the hash key for the table.
|
305
247
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
306
248
|
# 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
249
|
# @option opts [Object] :default_value Optional attribute used to
|
313
250
|
# define a "default value" to be used if the attribute's value on an
|
314
251
|
# item is nil or not set at persistence time.
|
315
252
|
def list_attr(name, opts = {})
|
316
253
|
opts[:dynamodb_type] = "L"
|
317
|
-
opts[:mutation_tracking] = true if opts[:mutation_tracking].nil?
|
318
254
|
attr(name, Marshalers::ListMarshaler.new(opts), opts)
|
319
255
|
end
|
320
256
|
|
@@ -345,17 +281,11 @@ module Aws
|
|
345
281
|
# the hash key for the table.
|
346
282
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
347
283
|
# 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
284
|
# @option opts [Object] :default_value Optional attribute used to
|
354
285
|
# define a "default value" to be used if the attribute's value on an
|
355
286
|
# item is nil or not set at persistence time.
|
356
287
|
def map_attr(name, opts = {})
|
357
288
|
opts[:dynamodb_type] = "M"
|
358
|
-
opts[:mutation_tracking] = true if opts[:mutation_tracking].nil?
|
359
289
|
attr(name, Marshalers::MapMarshaler.new(opts), opts)
|
360
290
|
end
|
361
291
|
|
@@ -376,17 +306,11 @@ module Aws
|
|
376
306
|
# the hash key for the table.
|
377
307
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
378
308
|
# 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
309
|
# @option opts [Object] :default_value Optional attribute used to
|
385
310
|
# define a "default value" to be used if the attribute's value on an
|
386
311
|
# item is nil or not set at persistence time.
|
387
312
|
def string_set_attr(name, opts = {})
|
388
313
|
opts[:dynamodb_type] = "SS"
|
389
|
-
opts[:mutation_tracking] = true if opts[:mutation_tracking].nil?
|
390
314
|
attr(name, Marshalers::StringSetMarshaler.new(opts), opts)
|
391
315
|
end
|
392
316
|
|
@@ -407,118 +331,57 @@ module Aws
|
|
407
331
|
# the hash key for the table.
|
408
332
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
409
333
|
# 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
334
|
# @option opts [Object] :default_value Optional attribute used to
|
416
335
|
# define a "default value" to be used if the attribute's value on an
|
417
336
|
# item is nil or not set at persistence time.
|
418
337
|
def numeric_set_attr(name, opts = {})
|
419
338
|
opts[:dynamodb_type] = "NS"
|
420
|
-
opts[:mutation_tracking] = true if opts[:mutation_tracking].nil?
|
421
339
|
attr(name, Marshalers::NumericSetMarshaler.new(opts), opts)
|
422
340
|
end
|
423
341
|
|
424
|
-
# @return [
|
425
|
-
def attributes
|
426
|
-
@attributes
|
427
|
-
end
|
428
|
-
|
429
|
-
# @return [Hash] hash of database names to attribute names
|
430
|
-
def storage_attributes
|
431
|
-
@storage_attributes
|
432
|
-
end
|
433
|
-
|
434
|
-
# @return [Aws::Record::Attribute,nil]
|
342
|
+
# @return [Symbol,nil]
|
435
343
|
def hash_key
|
436
|
-
@
|
344
|
+
@keys.hash_key
|
437
345
|
end
|
438
346
|
|
439
|
-
# @return [
|
347
|
+
# @return [Symbol,nil]
|
440
348
|
def range_key
|
441
|
-
@
|
349
|
+
@keys.range_key
|
442
350
|
end
|
443
351
|
|
444
|
-
# @
|
445
|
-
|
446
|
-
|
447
|
-
@keys
|
352
|
+
# @api private
|
353
|
+
def attributes
|
354
|
+
@attributes
|
448
355
|
end
|
449
356
|
|
450
|
-
# @
|
451
|
-
|
452
|
-
|
453
|
-
def track_mutations?(attr_sym)
|
454
|
-
mutation_tracking_enabled? && attributes[attr_sym].track_mutations?
|
357
|
+
# @api private
|
358
|
+
def keys
|
359
|
+
@keys.keys
|
455
360
|
end
|
456
361
|
|
457
362
|
private
|
458
|
-
def
|
363
|
+
def _define_attr_methods(name)
|
459
364
|
define_method(name) do
|
460
|
-
|
365
|
+
@data.get_attribute(name)
|
461
366
|
end
|
462
367
|
|
463
368
|
define_method("#{name}=") do |value|
|
464
|
-
|
369
|
+
@data.set_attribute(name, value)
|
465
370
|
end
|
466
371
|
end
|
467
372
|
|
468
|
-
def
|
373
|
+
def _key_attributes(id, opts)
|
469
374
|
if opts[:hash_key] == true && opts[:range_key] == true
|
470
375
|
raise ArgumentError.new(
|
471
376
|
"Cannot have the same attribute be a hash and range key."
|
472
377
|
)
|
473
378
|
elsif opts[:hash_key] == true
|
474
|
-
|
379
|
+
@keys.hash_key = id
|
475
380
|
elsif opts[:range_key] == true
|
476
|
-
|
477
|
-
end
|
478
|
-
end
|
479
|
-
|
480
|
-
def define_key(id, type)
|
481
|
-
@keys[type] = id
|
482
|
-
end
|
483
|
-
|
484
|
-
def validate_attr_name(name)
|
485
|
-
unless name.is_a?(Symbol)
|
486
|
-
raise ArgumentError.new("Must use symbolized :name attribute.")
|
487
|
-
end
|
488
|
-
if @attributes[name]
|
489
|
-
raise Errors::NameCollision.new(
|
490
|
-
"Cannot overwrite existing attribute #{name}"
|
491
|
-
)
|
381
|
+
@keys.range_key = id
|
492
382
|
end
|
493
383
|
end
|
494
384
|
|
495
|
-
def check_if_reserved(name)
|
496
|
-
if instance_methods.include?(name)
|
497
|
-
raise Errors::ReservedName.new(
|
498
|
-
"Cannot name an attribute #{name}, that would collide with an"\
|
499
|
-
" existing instance method."
|
500
|
-
)
|
501
|
-
end
|
502
|
-
end
|
503
|
-
|
504
|
-
def check_for_naming_collisions(name, storage_name)
|
505
|
-
if @attributes[storage_name.to_sym]
|
506
|
-
raise Errors::NameCollision.new(
|
507
|
-
"Custom storage name #{storage_name} already exists as an"\
|
508
|
-
" attribute name in #{@attributes}"
|
509
|
-
)
|
510
|
-
elsif @storage_attributes[name.to_s]
|
511
|
-
raise Errors::NameCollision.new(
|
512
|
-
"Attribute name #{name} already exists as a custom storage"\
|
513
|
-
" name in #{@storage_attributes}"
|
514
|
-
)
|
515
|
-
elsif @storage_attributes[storage_name]
|
516
|
-
raise Errors::NameCollision.new(
|
517
|
-
"Custom storage name #{storage_name} already in use in"\
|
518
|
-
" #{@storage_attributes}"
|
519
|
-
)
|
520
|
-
end
|
521
|
-
end
|
522
385
|
end
|
523
386
|
|
524
387
|
end
|
@@ -19,15 +19,6 @@ module Aws
|
|
19
19
|
sub_class.extend(DirtyTrackingClassMethods)
|
20
20
|
end
|
21
21
|
|
22
|
-
# @private
|
23
|
-
#
|
24
|
-
# @override initialize(*)
|
25
|
-
def initialize(*)
|
26
|
-
@dirty_data = {}
|
27
|
-
@mutation_copies = {}
|
28
|
-
super
|
29
|
-
end
|
30
|
-
|
31
22
|
# Returns +true+ if the specified attribute has any dirty changes, +false+ otherwise.
|
32
23
|
#
|
33
24
|
# @example
|
@@ -45,7 +36,7 @@ module Aws
|
|
45
36
|
# @param [String, Symbol] name The name of the attribute to to check for dirty changes.
|
46
37
|
# @return [Boolean] +true+ if the specified attribute has any dirty changes, +false+ otherwise.
|
47
38
|
def attribute_dirty?(name)
|
48
|
-
@
|
39
|
+
@data.attribute_dirty?(name)
|
49
40
|
end
|
50
41
|
|
51
42
|
# Returns the original value of the specified attribute.
|
@@ -64,11 +55,7 @@ module Aws
|
|
64
55
|
# @param [String, Symbol] name The name of the attribute to retrieve the original value of.
|
65
56
|
# @return [Object] The original value of the specified attribute.
|
66
57
|
def attribute_was(name)
|
67
|
-
|
68
|
-
@mutation_copies[name]
|
69
|
-
else
|
70
|
-
attribute_dirty?(name) ? @dirty_data[name] : @data[name]
|
71
|
-
end
|
58
|
+
@data.attribute_was(name)
|
72
59
|
end
|
73
60
|
|
74
61
|
# Mark that an attribute is changing. This is useful in situations where it is necessary to track that the value of an
|
@@ -106,44 +93,7 @@ module Aws
|
|
106
93
|
# @param [String, Symbol] name The name of the attribute to mark as
|
107
94
|
# changing.
|
108
95
|
def attribute_dirty!(name)
|
109
|
-
|
110
|
-
|
111
|
-
current_value = @data[name]
|
112
|
-
|
113
|
-
@dirty_data[name] =
|
114
|
-
begin
|
115
|
-
_deep_copy(current_value)
|
116
|
-
rescue TypeError
|
117
|
-
current_value
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
# Marks the changes as applied by clearing the current changes and making
|
122
|
-
# them accessible through +previous_changes+.
|
123
|
-
#
|
124
|
-
# # @example
|
125
|
-
# class Model
|
126
|
-
# include Aws::Record
|
127
|
-
# integer_attr :id, hash_key: true
|
128
|
-
# string_attr :name
|
129
|
-
# end
|
130
|
-
#
|
131
|
-
# model.name # => 'Alex'
|
132
|
-
# model.name = 'Nick'
|
133
|
-
# model.dirty? # => true
|
134
|
-
#
|
135
|
-
# model.clean!
|
136
|
-
# model.dirty? # false
|
137
|
-
#
|
138
|
-
def clean!
|
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
|
96
|
+
@data.attribute_dirty!(name)
|
147
97
|
end
|
148
98
|
|
149
99
|
# Returns an array with the name of the attributes with dirty changes.
|
@@ -162,13 +112,7 @@ module Aws
|
|
162
112
|
#
|
163
113
|
# @return [Array] The names of attributes with dirty changes.
|
164
114
|
def dirty
|
165
|
-
|
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
|
115
|
+
@data.dirty
|
172
116
|
end
|
173
117
|
|
174
118
|
# Returns +true+ if any attributes have dirty changes, +false+ otherwise.
|
@@ -188,10 +132,7 @@ module Aws
|
|
188
132
|
# @return [Boolean] +true+ if any attributes have dirty changes, +false+
|
189
133
|
# otherwise.
|
190
134
|
def dirty?
|
191
|
-
|
192
|
-
@mutation_copies.any? do |name, value|
|
193
|
-
@mutation_copies[name] != @data[name]
|
194
|
-
end
|
135
|
+
@data.dirty?
|
195
136
|
end
|
196
137
|
|
197
138
|
# Fetches attributes for this instance of an item from Amazon DynamoDB
|
@@ -236,14 +177,7 @@ module Aws
|
|
236
177
|
#
|
237
178
|
# @param [String, Symbol] name The name of the attribute to restore
|
238
179
|
def rollback_attribute!(name)
|
239
|
-
|
240
|
-
|
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
|
180
|
+
@data.rollback_attribute!(name)
|
247
181
|
end
|
248
182
|
|
249
183
|
# Restores all attributes to their original values.
|
@@ -265,6 +199,11 @@ module Aws
|
|
265
199
|
Array(names).each { |name| rollback_attribute!(name) }
|
266
200
|
end
|
267
201
|
|
202
|
+
# @api private
|
203
|
+
def clean!
|
204
|
+
@data.clean!
|
205
|
+
end
|
206
|
+
|
268
207
|
# @private
|
269
208
|
#
|
270
209
|
# @override save(*)
|
@@ -272,36 +211,6 @@ module Aws
|
|
272
211
|
super.tap { clean! }
|
273
212
|
end
|
274
213
|
|
275
|
-
private
|
276
|
-
|
277
|
-
# @private
|
278
|
-
#
|
279
|
-
# @override write_attribute(*)
|
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)
|
286
|
-
if value == attribute_was(name)
|
287
|
-
@dirty_data.delete(name)
|
288
|
-
else
|
289
|
-
attribute_dirty!(name)
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
def _mutated?(name)
|
294
|
-
if @mutation_copies.has_key?(name)
|
295
|
-
@data[name] != @mutation_copies[name]
|
296
|
-
else
|
297
|
-
false
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
def _deep_copy(obj)
|
302
|
-
Marshal.load(Marshal.dump(obj))
|
303
|
-
end
|
304
|
-
|
305
214
|
module DirtyTrackingClassMethods
|
306
215
|
|
307
216
|
private
|
@@ -316,7 +225,7 @@ module Aws
|
|
316
225
|
# @private
|
317
226
|
#
|
318
227
|
# @override define_attr_methods(*)
|
319
|
-
def
|
228
|
+
def _define_attr_methods(name)
|
320
229
|
super.tap do
|
321
230
|
define_method("#{name}_dirty?") do
|
322
231
|
attribute_dirty?(name)
|
@@ -43,9 +43,10 @@ module Aws
|
|
43
43
|
items.each do |item|
|
44
44
|
record = model.new
|
45
45
|
data = record.instance_variable_get("@data")
|
46
|
-
model.attributes.each do |name, attr|
|
47
|
-
data
|
46
|
+
model.attributes.attributes.each do |name, attr|
|
47
|
+
data.set_attribute(name, attr.extract(item))
|
48
48
|
end
|
49
|
+
data.clean!
|
49
50
|
ret << record
|
50
51
|
end
|
51
52
|
ret
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# Copyright 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
|
+
|
17
|
+
# @api private
|
18
|
+
class ItemData
|
19
|
+
def initialize(model_attributes, opts)
|
20
|
+
@data = {}
|
21
|
+
@clean_copies = {}
|
22
|
+
@dirty_flags = {}
|
23
|
+
@model_attributes = model_attributes
|
24
|
+
@track_mutations = opts[:track_mutations]
|
25
|
+
@track_mutations = true if opts[:track_mutations].nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_attribute(name)
|
29
|
+
@model_attributes.attribute_for(name).type_cast(@data[name])
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_attribute(name, value)
|
33
|
+
@data[name] = value
|
34
|
+
end
|
35
|
+
|
36
|
+
def raw_value(name)
|
37
|
+
@data[name]
|
38
|
+
end
|
39
|
+
|
40
|
+
def clean!
|
41
|
+
@dirty_flags = {}
|
42
|
+
@model_attributes.attributes.each_key do |name|
|
43
|
+
populate_default_values
|
44
|
+
value = get_attribute(name)
|
45
|
+
if @track_mutations
|
46
|
+
@clean_copies[name] = _deep_copy(value)
|
47
|
+
else
|
48
|
+
@clean_copies[name] = value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def attribute_dirty?(name)
|
54
|
+
if @dirty_flags[name]
|
55
|
+
true
|
56
|
+
else
|
57
|
+
value = get_attribute(name)
|
58
|
+
value != @clean_copies[name]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def attribute_was(name)
|
63
|
+
@clean_copies[name]
|
64
|
+
end
|
65
|
+
|
66
|
+
def attribute_dirty!(name)
|
67
|
+
@dirty_flags[name] = true
|
68
|
+
end
|
69
|
+
|
70
|
+
def dirty
|
71
|
+
@model_attributes.attributes.keys.inject([]) do |acc, name|
|
72
|
+
acc << name if attribute_dirty?(name)
|
73
|
+
acc
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def dirty?
|
78
|
+
dirty.empty? ? false : true
|
79
|
+
end
|
80
|
+
|
81
|
+
def rollback_attribute!(name)
|
82
|
+
if attribute_dirty?(name)
|
83
|
+
@dirty_flags.delete(name)
|
84
|
+
set_attribute(name, attribute_was(name))
|
85
|
+
end
|
86
|
+
get_attribute(name)
|
87
|
+
end
|
88
|
+
|
89
|
+
def hash_copy
|
90
|
+
@data.dup
|
91
|
+
end
|
92
|
+
|
93
|
+
def build_save_hash
|
94
|
+
@data.inject({}) do |acc, name_value_pair|
|
95
|
+
attr_name, raw_value = name_value_pair
|
96
|
+
attribute = @model_attributes.attribute_for(attr_name)
|
97
|
+
if !raw_value.nil? || attribute.persist_nil?
|
98
|
+
db_name = attribute.database_name
|
99
|
+
acc[db_name] = attribute.serialize(raw_value)
|
100
|
+
end
|
101
|
+
acc
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def populate_default_values
|
106
|
+
@model_attributes.attributes.each do |name, attribute|
|
107
|
+
unless attribute.default_value.nil?
|
108
|
+
if @data[name].nil? && @data[name].nil?
|
109
|
+
@data[name] = attribute.default_value
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
def _deep_copy(obj)
|
117
|
+
Marshal.load(Marshal.dump(obj))
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
@@ -154,33 +154,17 @@ module Aws
|
|
154
154
|
|
155
155
|
def _build_item_for_save
|
156
156
|
validate_key_values
|
157
|
-
|
158
|
-
|
159
|
-
@data.inject({}) do |acc, name_value_pair|
|
160
|
-
attr_name, raw_value = name_value_pair
|
161
|
-
attribute = attributes[attr_name]
|
162
|
-
if !raw_value.nil? || attribute.persist_nil?
|
163
|
-
db_name = attribute.database_name
|
164
|
-
acc[db_name] = attribute.serialize(raw_value)
|
165
|
-
end
|
166
|
-
acc
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def _populate_default_values(attributes)
|
171
|
-
attributes.each do |attr_name, attribute|
|
172
|
-
if !attribute.default_value.nil? && @data[attribute.name].nil?
|
173
|
-
@data[attr_name] = attribute.default_value
|
174
|
-
end
|
175
|
-
end
|
157
|
+
@data.populate_default_values
|
158
|
+
@data.build_save_hash
|
176
159
|
end
|
177
160
|
|
178
161
|
def key_values
|
179
162
|
validate_key_values
|
180
163
|
attributes = self.class.attributes
|
181
164
|
self.class.keys.inject({}) do |acc, (_, attr_name)|
|
182
|
-
db_name = attributes
|
183
|
-
acc[db_name] = attributes
|
165
|
+
db_name = attributes.storage_name_for(attr_name)
|
166
|
+
acc[db_name] = attributes.attribute_for(attr_name).
|
167
|
+
serialize(@data.raw_value(attr_name))
|
184
168
|
acc
|
185
169
|
end
|
186
170
|
end
|
@@ -196,7 +180,7 @@ module Aws
|
|
196
180
|
|
197
181
|
def missing_key_values
|
198
182
|
self.class.keys.inject([]) do |acc, key|
|
199
|
-
acc << key.last if @data
|
183
|
+
acc << key.last if @data.raw_value(key.last).nil?
|
200
184
|
acc
|
201
185
|
end
|
202
186
|
end
|
@@ -211,13 +195,14 @@ module Aws
|
|
211
195
|
def prevent_overwrite_expression
|
212
196
|
conditions = []
|
213
197
|
expression_attribute_names = {}
|
198
|
+
keys = self.class.instance_variable_get("@keys")
|
214
199
|
# Hash Key
|
215
200
|
conditions << "attribute_not_exists(#H)"
|
216
|
-
expression_attribute_names["#H"] =
|
201
|
+
expression_attribute_names["#H"] = keys.hash_key_attribute.database_name
|
217
202
|
# Range Key
|
218
203
|
if self.class.range_key
|
219
204
|
conditions << "attribute_not_exists(#R)"
|
220
|
-
expression_attribute_names["#R"] =
|
205
|
+
expression_attribute_names["#R"] = keys.range_key_attribute.database_name
|
221
206
|
end
|
222
207
|
{
|
223
208
|
condition_expression: conditions.join(" and "),
|
@@ -228,7 +213,7 @@ module Aws
|
|
228
213
|
def _dirty_changes_for_update
|
229
214
|
attributes = self.class.attributes
|
230
215
|
ret = dirty.inject({}) do |acc, attr_name|
|
231
|
-
acc[attr_name] = @data
|
216
|
+
acc[attr_name] = @data.raw_value(attr_name)
|
232
217
|
acc
|
233
218
|
end
|
234
219
|
ret
|
@@ -252,14 +237,15 @@ module Aws
|
|
252
237
|
# not include all table keys.
|
253
238
|
def find(opts)
|
254
239
|
key = {}
|
255
|
-
@keys.each_value do |attr_sym|
|
240
|
+
@keys.keys.each_value do |attr_sym|
|
256
241
|
unless opts[attr_sym]
|
257
242
|
raise Errors::KeyMissing.new(
|
258
243
|
"Missing required key #{attr_sym} in #{opts}"
|
259
244
|
)
|
260
245
|
end
|
261
|
-
attr_name = attributes
|
262
|
-
key[attr_name] = attributes
|
246
|
+
attr_name = attributes.storage_name_for(attr_sym)
|
247
|
+
key[attr_name] = attributes.attribute_for(attr_sym).
|
248
|
+
serialize(opts[attr_sym])
|
263
249
|
end
|
264
250
|
request_opts = {
|
265
251
|
table_name: table_name,
|
@@ -298,14 +284,14 @@ module Aws
|
|
298
284
|
def update(opts)
|
299
285
|
key = {}
|
300
286
|
updates = {}
|
301
|
-
@keys.each_value do |attr_sym|
|
287
|
+
@keys.keys.each_value do |attr_sym|
|
302
288
|
unless value = opts.delete(attr_sym)
|
303
289
|
raise Errors::KeyMissing.new(
|
304
290
|
"Missing required key #{attr_sym} in #{opts}"
|
305
291
|
)
|
306
292
|
end
|
307
|
-
attr_name = attributes
|
308
|
-
key[attr_name] = attributes
|
293
|
+
attr_name = attributes.storage_name_for(attr_sym)
|
294
|
+
key[attr_name] = attributes.attribute_for(attr_sym).serialize(value)
|
309
295
|
end
|
310
296
|
request_opts = {
|
311
297
|
table_name: table_name,
|
@@ -335,8 +321,8 @@ module Aws
|
|
335
321
|
name_sub_token = name_sub_token.succ
|
336
322
|
value_sub_token = value_sub_token.succ
|
337
323
|
|
338
|
-
attribute = attributes
|
339
|
-
attr_name =
|
324
|
+
attribute = attributes.attribute_for(attr_sym)
|
325
|
+
attr_name = attributes.storage_name_for(attr_sym)
|
340
326
|
exp_attr_names[name_sub] = attr_name
|
341
327
|
if _update_type_remove?(attribute, value)
|
342
328
|
remove_expressions << "#{name_sub}"
|
@@ -362,8 +348,8 @@ module Aws
|
|
362
348
|
def build_item_from_resp(resp)
|
363
349
|
record = new
|
364
350
|
data = record.instance_variable_get("@data")
|
365
|
-
attributes.each do |name, attr|
|
366
|
-
data
|
351
|
+
attributes.attributes.each do |name, attr|
|
352
|
+
data.set_attribute(name, attr.extract(resp.item))
|
367
353
|
end
|
368
354
|
record
|
369
355
|
end
|
@@ -0,0 +1,54 @@
|
|
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
|
+
|
17
|
+
# @api private
|
18
|
+
class KeyAttributes
|
19
|
+
attr_reader :keys
|
20
|
+
|
21
|
+
def initialize(model_attributes)
|
22
|
+
@keys = {}
|
23
|
+
@model_attributes = model_attributes
|
24
|
+
end
|
25
|
+
|
26
|
+
def hash_key
|
27
|
+
@hash_key
|
28
|
+
end
|
29
|
+
|
30
|
+
def hash_key_attribute
|
31
|
+
@model_attributes.attribute_for(hash_key)
|
32
|
+
end
|
33
|
+
|
34
|
+
def range_key
|
35
|
+
@range_key
|
36
|
+
end
|
37
|
+
|
38
|
+
def range_key_attribute
|
39
|
+
@model_attributes.attribute_for(range_key)
|
40
|
+
end
|
41
|
+
|
42
|
+
def hash_key=(value)
|
43
|
+
@keys[:hash] = value
|
44
|
+
@hash_key = value
|
45
|
+
end
|
46
|
+
|
47
|
+
def range_key=(value)
|
48
|
+
@keys[:range] = value
|
49
|
+
@range_key = value
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# Copyright 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
|
+
|
17
|
+
# @api private
|
18
|
+
class ModelAttributes
|
19
|
+
attr_reader :attributes, :storage_attributes
|
20
|
+
|
21
|
+
def initialize(model_class)
|
22
|
+
@model_class = model_class
|
23
|
+
@attributes = {}
|
24
|
+
@storage_attributes = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def register_attribute(name, marshaler, opts)
|
28
|
+
attribute = Attribute.new(name, opts.merge(marshaler: marshaler))
|
29
|
+
_new_attr_validation(name, attribute)
|
30
|
+
@attributes[name] = attribute
|
31
|
+
@storage_attributes[attribute.database_name] = name
|
32
|
+
attribute
|
33
|
+
end
|
34
|
+
|
35
|
+
def attribute_for(name)
|
36
|
+
@attributes[name]
|
37
|
+
end
|
38
|
+
|
39
|
+
def storage_name_for(name)
|
40
|
+
attribute_for(name).database_name
|
41
|
+
end
|
42
|
+
|
43
|
+
def present?(name)
|
44
|
+
attribute_for(name) ? true : false
|
45
|
+
end
|
46
|
+
|
47
|
+
def db_to_attribute_name(storage_name)
|
48
|
+
@storage_attributes[storage_name]
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def _new_attr_validation(name, attribute)
|
53
|
+
_validate_attr_name(name)
|
54
|
+
_check_for_naming_collisions(name, attribute.database_name)
|
55
|
+
_check_if_reserved(name)
|
56
|
+
end
|
57
|
+
|
58
|
+
def _validate_attr_name(name)
|
59
|
+
unless name.is_a?(Symbol)
|
60
|
+
raise ArgumentError.new("Must use symbolized :name attribute.")
|
61
|
+
end
|
62
|
+
if @attributes[name]
|
63
|
+
raise Errors::NameCollision.new(
|
64
|
+
"Cannot overwrite existing attribute #{name}"
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def _check_if_reserved(name)
|
70
|
+
if @model_class.instance_methods.include?(name)
|
71
|
+
raise Errors::ReservedName.new(
|
72
|
+
"Cannot name an attribute #{name}, that would collide with an"\
|
73
|
+
" existing instance method."
|
74
|
+
)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def _check_for_naming_collisions(name, storage_name)
|
79
|
+
if @attributes[storage_name.to_sym]
|
80
|
+
raise Errors::NameCollision.new(
|
81
|
+
"Custom storage name #{storage_name} already exists as an"\
|
82
|
+
" attribute name in #{@attributes}"
|
83
|
+
)
|
84
|
+
elsif @storage_attributes[name.to_s]
|
85
|
+
raise Errors::NameCollision.new(
|
86
|
+
"Attribute name #{name} already exists as a custom storage"\
|
87
|
+
" name in #{@storage_attributes}"
|
88
|
+
)
|
89
|
+
elsif @storage_attributes[storage_name]
|
90
|
+
raise Errors::NameCollision.new(
|
91
|
+
"Custom storage name #{storage_name} already in use in"\
|
92
|
+
" #{@storage_attributes}"
|
93
|
+
)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
@@ -37,7 +37,7 @@ module Aws
|
|
37
37
|
# are copied from the table to the index. See shape details in the
|
38
38
|
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Types/Projection.html AWS SDK for Ruby V2 docs}.
|
39
39
|
def local_secondary_index(name, opts)
|
40
|
-
opts[:hash_key] = hash_key
|
40
|
+
opts[:hash_key] = hash_key
|
41
41
|
_validate_required_lsi_keys(opts)
|
42
42
|
local_secondary_indexes[name] = opts
|
43
43
|
end
|
@@ -102,12 +102,12 @@ module Aws
|
|
102
102
|
def _si_key_schema(opts)
|
103
103
|
key_schema = [{
|
104
104
|
key_type: "HASH",
|
105
|
-
attribute_name: @attributes
|
105
|
+
attribute_name: @attributes.storage_name_for(opts[:hash_key])
|
106
106
|
}]
|
107
107
|
if opts[:range_key]
|
108
108
|
key_schema << {
|
109
109
|
key_type: "RANGE",
|
110
|
-
attribute_name: @attributes
|
110
|
+
attribute_name: @attributes.storage_name_for(opts[:range_key])
|
111
111
|
}
|
112
112
|
end
|
113
113
|
key_schema
|
@@ -139,13 +139,13 @@ module Aws
|
|
139
139
|
|
140
140
|
def _validate_attributes_exist(*attr_names)
|
141
141
|
missing = attr_names.select do |attr_name|
|
142
|
-
|
142
|
+
!@attributes.present?(attr_name)
|
143
143
|
end
|
144
144
|
unless missing.empty?
|
145
145
|
raise ArgumentError.new(
|
146
146
|
"#{missing.join(", ")} not present in model attributes."\
|
147
147
|
" Please ensure that attributes are defined in the model"\
|
148
|
-
" class BEFORE defining
|
148
|
+
" class BEFORE defining an index on those attributes."
|
149
149
|
)
|
150
150
|
end
|
151
151
|
end
|
@@ -133,7 +133,7 @@ module Aws
|
|
133
133
|
private
|
134
134
|
def _assert_model_valid(model)
|
135
135
|
_assert_required_include(model)
|
136
|
-
|
136
|
+
model.model_valid?
|
137
137
|
end
|
138
138
|
|
139
139
|
def _assert_required_include(model)
|
@@ -142,12 +142,6 @@ module Aws
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
-
def _assert_keys(model)
|
146
|
-
if model.hash_key.nil?
|
147
|
-
raise Errors::InvalidModel.new("Table models must include a hash key")
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
145
|
def _attribute_definitions
|
152
146
|
_keys.map do |type, attr|
|
153
147
|
{
|
@@ -158,6 +152,7 @@ module Aws
|
|
158
152
|
end
|
159
153
|
|
160
154
|
def _append_to_attribute_definitions(secondary_indexes, create_opts)
|
155
|
+
attributes = @model.attributes
|
161
156
|
attr_def = create_opts[:attribute_definitions]
|
162
157
|
secondary_indexes.each do |si|
|
163
158
|
si[:key_schema].each do |key_schema|
|
@@ -165,9 +160,9 @@ module Aws
|
|
165
160
|
a[:attribute_name] == key_schema[:attribute_name]
|
166
161
|
}
|
167
162
|
unless exists
|
168
|
-
attr =
|
169
|
-
|
170
|
-
|
163
|
+
attr = attributes.attribute_for(
|
164
|
+
attributes.db_to_attribute_name(key_schema[:attribute_name])
|
165
|
+
)
|
171
166
|
attr_def << {
|
172
167
|
attribute_name: attr.database_name,
|
173
168
|
attribute_type: attr.dynamodb_type
|
@@ -208,7 +203,7 @@ module Aws
|
|
208
203
|
|
209
204
|
def _keys
|
210
205
|
@model.keys.inject({}) do |acc, (type, name)|
|
211
|
-
acc[type] = @model.attributes
|
206
|
+
acc[type] = @model.attributes.attribute_for(name)
|
212
207
|
acc
|
213
208
|
end
|
214
209
|
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.10
|
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-
|
11
|
+
date: 2016-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-resources
|
@@ -38,7 +38,9 @@ files:
|
|
38
38
|
- lib/aws-record/record/dirty_tracking.rb
|
39
39
|
- lib/aws-record/record/errors.rb
|
40
40
|
- lib/aws-record/record/item_collection.rb
|
41
|
+
- lib/aws-record/record/item_data.rb
|
41
42
|
- lib/aws-record/record/item_operations.rb
|
43
|
+
- lib/aws-record/record/key_attributes.rb
|
42
44
|
- lib/aws-record/record/marshalers/boolean_marshaler.rb
|
43
45
|
- lib/aws-record/record/marshalers/date_marshaler.rb
|
44
46
|
- lib/aws-record/record/marshalers/date_time_marshaler.rb
|
@@ -49,6 +51,7 @@ files:
|
|
49
51
|
- lib/aws-record/record/marshalers/numeric_set_marshaler.rb
|
50
52
|
- lib/aws-record/record/marshalers/string_marshaler.rb
|
51
53
|
- lib/aws-record/record/marshalers/string_set_marshaler.rb
|
54
|
+
- lib/aws-record/record/model_attributes.rb
|
52
55
|
- lib/aws-record/record/query.rb
|
53
56
|
- lib/aws-record/record/secondary_indexes.rb
|
54
57
|
- lib/aws-record/record/table_migration.rb
|