Skip to content

Commit c753c13

Browse files
authored
Merge pull request dynamodb-toolbox#82 from whahoo/v0.2
Fix problems with falsy values and defaults on Entity Update
2 parents 7d4428b + b513bce commit c753c13

File tree

2 files changed

+34
-18
lines changed

2 files changed

+34
-18
lines changed

__tests__/entity.update.unit.test.js

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ const TestEntity = new Entity({
1717
attributes: {
1818
email: { type: 'string', partitionKey: true },
1919
sort: { type: 'string', sortKey: true },
20-
test_string: { type: 'string', coerce: false, default: 'test string' },
20+
test_string: { type: 'string', coerce: false, default: 'default string' },
2121
test_string_coerce: { type: 'string' },
2222
test_number: { type: 'number', alias: 'count', coerce: false },
2323
test_number_coerce: { type: 'number', default: 0 },
2424
test_boolean: { type: 'boolean', coerce: false },
2525
test_boolean_coerce: { type: 'boolean' },
26+
test_boolean_default: { type: 'boolean', default: false },
2627
test_list: { type: 'list' },
2728
test_list_coerce: { type: 'list', coerce: true },
2829
test_map: { type: 'map', alias: 'contents' },
@@ -101,12 +102,13 @@ describe('update',()=>{
101102
it('creates default update', () => {
102103
let { TableName, Key, UpdateExpression, ExpressionAttributeNames, ExpressionAttributeValues } = TestEntity.updateParams({ pk: 'test-pk', sk: 'test-sk' })
103104

104-
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = :test_number_coerce, #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et)')
105-
expect(ExpressionAttributeNames).toEqual({ '#_md': '_md', '#_ct': '_ct', '#test_string': 'test_string', '#test_number_coerce':'test_number_coerce', '#_et': '_et' })
105+
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = if_not_exists(#test_number_coerce,:test_number_coerce), #test_boolean_default = if_not_exists(#test_boolean_default,:test_boolean_default), #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et)')
106+
expect(ExpressionAttributeNames).toEqual({ '#_md': '_md', '#_ct': '_ct', '#test_string': 'test_string', '#test_boolean_default': 'test_boolean_default', '#test_number_coerce':'test_number_coerce', '#_et': '_et' })
106107
expect(ExpressionAttributeValues).toHaveProperty(':_ct')
107108
expect(ExpressionAttributeValues).toHaveProperty(':_md')
108109
expect(ExpressionAttributeValues).toHaveProperty(':test_string')
109110
expect(ExpressionAttributeValues).toHaveProperty(':test_number_coerce')
111+
expect(ExpressionAttributeValues).toHaveProperty(':test_boolean_default')
110112
expect(ExpressionAttributeValues).toHaveProperty(':_et')
111113
expect(ExpressionAttributeValues[':_et']).toBe('TestEntity')
112114
expect(Key).toEqual({ pk: 'test-pk', sk: 'test-sk' })
@@ -125,14 +127,15 @@ describe('update',()=>{
125127
sk: 'test-sk',
126128
test_string: 'test string'
127129
})
128-
expect(UpdateExpression).toBe('SET #test_string = :test_string, #test_number_coerce = :test_number_coerce, #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et)')
129-
expect(ExpressionAttributeNames).toEqual({ '#_md': '_md', '#_ct': '_ct', '#test_string': 'test_string', '#test_number_coerce':'test_number_coerce', '#_et': '_et' })
130+
expect(UpdateExpression).toBe('SET #test_string = :test_string, #test_number_coerce = if_not_exists(#test_number_coerce,:test_number_coerce), #test_boolean_default = if_not_exists(#test_boolean_default,:test_boolean_default), #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et)')
131+
expect(ExpressionAttributeNames).toEqual({ '#_md': '_md', '#_ct': '_ct', '#test_string': 'test_string', '#test_boolean_default': 'test_boolean_default', '#test_number_coerce':'test_number_coerce', '#_et': '_et' })
130132
expect(ExpressionAttributeValues).toHaveProperty(':_md')
131133
expect(ExpressionAttributeValues).toHaveProperty(':_ct')
132134
expect(ExpressionAttributeValues).not.toHaveProperty(':pk')
133135
expect(ExpressionAttributeValues).not.toHaveProperty(':sk')
134136
expect(ExpressionAttributeValues[':test_string']).toBe('test string')
135137
expect(ExpressionAttributeValues).toHaveProperty(':test_number_coerce')
138+
expect(ExpressionAttributeValues).toHaveProperty(':test_boolean_default')
136139
expect(ExpressionAttributeValues).toHaveProperty(':_et')
137140
expect(ExpressionAttributeValues[':_et']).toBe('TestEntity')
138141
expect(Key).toEqual({ pk: 'test-pk', sk: 'test-sk' })
@@ -221,11 +224,17 @@ describe('update',()=>{
221224
test_boolean: false,
222225
test_list: ['a','b','c'],
223226
test_map: { a: 1, b: 2 },
224-
test_binary: Buffer.from('test')
227+
test_binary: Buffer.from('test'),
228+
test_boolean_default: false,
229+
test_number_coerce: 0
225230
})
231+
expect(UpdateExpression).toBe('SET #test_string = :test_string, #test_number_coerce = :test_number_coerce, #test_boolean_default = :test_boolean_default, #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et), #test_number = :test_number, #test_boolean = :test_boolean, #test_list = :test_list, #test_map = :test_map, #test_binary = :test_binary')
232+
226233
expect(ExpressionAttributeValues[':test_string']).toBe('test')
227234
expect(ExpressionAttributeValues[':test_number']).toBe(1)
235+
expect(ExpressionAttributeValues[':test_number_coerce']).toBe(0)
228236
expect(ExpressionAttributeValues[':test_boolean']).toBe(false)
237+
expect(ExpressionAttributeValues[':test_boolean_default']).toBe(false)
229238
expect(ExpressionAttributeValues[':test_list']).toEqual(['a','b','c'])
230239
expect(ExpressionAttributeValues[':test_map']).toEqual({ a: 1, b: 2 })
231240
expect(ExpressionAttributeValues[':test_binary']).toEqual(Buffer.from('test'))
@@ -289,8 +298,8 @@ describe('update',()=>{
289298
test_number: { $add: 10 },
290299
test_number_set_type: { $add: [1,2,3] }
291300
})
292-
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = :test_number_coerce, #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et) ADD #test_number :test_number, #test_number_set_type :test_number_set_type')
293-
expect(ExpressionAttributeNames).toEqual({ '#_md': '_md', '#_ct': '_ct', '#test_string': 'test_string', '#_et': '_et', '#test_number': 'test_number', '#test_number_set_type': 'test_number_set_type', '#test_number_coerce': 'test_number_coerce' })
301+
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = if_not_exists(#test_number_coerce,:test_number_coerce), #test_boolean_default = if_not_exists(#test_boolean_default,:test_boolean_default), #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et) ADD #test_number :test_number, #test_number_set_type :test_number_set_type')
302+
expect(ExpressionAttributeNames).toEqual({ '#_md': '_md', '#_ct': '_ct', '#test_string': 'test_string', '#_et': '_et','#test_boolean_default': 'test_boolean_default', '#test_number': 'test_number', '#test_number_set_type': 'test_number_set_type', '#test_number_coerce': 'test_number_coerce' })
294303
expect(ExpressionAttributeValues).toHaveProperty(':_md')
295304
expect(ExpressionAttributeValues).toHaveProperty(':_ct')
296305
expect(ExpressionAttributeValues).not.toHaveProperty(':pk')
@@ -311,12 +320,13 @@ describe('update',()=>{
311320
test_string_set_type: { $delete: ['1','2','3'] },
312321
test_number_set_type: { $delete: [1,2,3] }
313322
})
314-
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = :test_number_coerce, #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et) DELETE #test_string_set_type :test_string_set_type, #test_number_set_type :test_number_set_type')
323+
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = if_not_exists(#test_number_coerce,:test_number_coerce), #test_boolean_default = if_not_exists(#test_boolean_default,:test_boolean_default), #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et) DELETE #test_string_set_type :test_string_set_type, #test_number_set_type :test_number_set_type')
315324
expect(ExpressionAttributeNames).toEqual({
316325
'#test_string': 'test_string',
317326
'#_et': '_et',
318327
'#_ct': '_ct',
319328
'#_md': '_md',
329+
'#test_boolean_default': 'test_boolean_default',
320330
'#test_string_set_type': 'test_string_set_type',
321331
'#test_number_set_type': 'test_number_set_type',
322332
'#test_number_coerce': 'test_number_coerce'
@@ -340,12 +350,13 @@ describe('update',()=>{
340350
sk: 'test-sk',
341351
test_list: { $remove: [2,3,8] }
342352
})
343-
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = :test_number_coerce, #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et) REMOVE #test_list[2], #test_list[3], #test_list[8]')
353+
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = if_not_exists(#test_number_coerce,:test_number_coerce), #test_boolean_default = if_not_exists(#test_boolean_default,:test_boolean_default), #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et) REMOVE #test_list[2], #test_list[3], #test_list[8]')
344354
expect(ExpressionAttributeNames).toEqual({
345355
'#test_string': 'test_string',
346356
'#_et': '_et',
347357
'#_ct': '_ct',
348358
'#_md': '_md',
359+
'#test_boolean_default': 'test_boolean_default',
349360
'#test_list': 'test_list',
350361
'#test_number_coerce': 'test_number_coerce'
351362
})
@@ -365,12 +376,13 @@ describe('update',()=>{
365376
sk: 'test-sk',
366377
test_list: { 2: 'Test2', 5: 'Test5' }
367378
})
368-
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = :test_number_coerce, #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et), #test_list[2] = :test_list_2, #test_list[5] = :test_list_5')
379+
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = if_not_exists(#test_number_coerce,:test_number_coerce), #test_boolean_default = if_not_exists(#test_boolean_default,:test_boolean_default), #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et), #test_list[2] = :test_list_2, #test_list[5] = :test_list_5')
369380
expect(ExpressionAttributeNames).toEqual({
370381
'#test_string': 'test_string',
371382
'#_et': '_et',
372383
'#_ct': '_ct',
373384
'#_md': '_md',
385+
'#test_boolean_default': 'test_boolean_default',
374386
'#test_list': 'test_list',
375387
'#test_number_coerce': 'test_number_coerce'
376388
})
@@ -394,12 +406,13 @@ describe('update',()=>{
394406
test_list: { $append: [1,2,3] },
395407
test_list_coerce: { $prepend: [1,2,3] }
396408
})
397-
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = :test_number_coerce, #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et), #test_list = list_append(#test_list,:test_list), #test_list_coerce = list_append(:test_list_coerce,#test_list_coerce)')
409+
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = if_not_exists(#test_number_coerce,:test_number_coerce), #test_boolean_default = if_not_exists(#test_boolean_default,:test_boolean_default), #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et), #test_list = list_append(#test_list,:test_list), #test_list_coerce = list_append(:test_list_coerce,#test_list_coerce)')
398410
expect(ExpressionAttributeNames).toEqual({
399411
'#test_string': 'test_string',
400412
'#_et': '_et',
401413
'#_ct': '_ct',
402414
'#_md': '_md',
415+
'#test_boolean_default': 'test_boolean_default',
403416
'#test_list': 'test_list',
404417
'#test_list_coerce': 'test_list_coerce',
405418
'#test_number_coerce': 'test_number_coerce'
@@ -429,11 +442,12 @@ describe('update',()=>{
429442
'prop5': [1,2,3]
430443
}}
431444
})
432-
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = :test_number_coerce, #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et), #test_map.#test_map_prop1 = :test_map_prop1, #test_map.#test_map_prop2[1] = :test_map_prop2_1, #test_map.#test_map_prop2[4] = :test_map_prop2_4, #test_map.#test_map_prop3.#test_map_prop3_prop4 = :test_map_prop3_prop4, #test_map.#test_map_prop5 = :test_map_prop5')
445+
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = if_not_exists(#test_number_coerce,:test_number_coerce), #test_boolean_default = if_not_exists(#test_boolean_default,:test_boolean_default), #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et), #test_map.#test_map_prop1 = :test_map_prop1, #test_map.#test_map_prop2[1] = :test_map_prop2_1, #test_map.#test_map_prop2[4] = :test_map_prop2_4, #test_map.#test_map_prop3.#test_map_prop3_prop4 = :test_map_prop3_prop4, #test_map.#test_map_prop5 = :test_map_prop5')
433446
expect(ExpressionAttributeNames).toEqual({
434447
'#_et': '_et',
435448
'#_ct': '_ct',
436449
'#_md': '_md',
450+
'#test_boolean_default': 'test_boolean_default',
437451
'#test_string': 'test_string',
438452
'#test_map_prop1': 'prop1',
439453
'#test_map_prop2': 'prop2',
@@ -445,7 +459,7 @@ describe('update',()=>{
445459
})
446460
expect(ExpressionAttributeValues).toHaveProperty(':_et')
447461
expect(ExpressionAttributeValues[':_et']).toBe('TestEntity')
448-
expect(ExpressionAttributeValues[':test_string']).toBe('test string')
462+
expect(ExpressionAttributeValues[':test_string']).toBe('default string')
449463
expect(ExpressionAttributeValues[':test_map_prop1']).toBe('some value')
450464
expect(ExpressionAttributeValues[':test_map_prop2_1']).toBe('list value')
451465
expect(ExpressionAttributeValues[':test_map_prop2_4']).toBe('list value4')
@@ -463,19 +477,20 @@ describe('update',()=>{
463477
count: { $add: 10 },
464478
contents: { a: 1, b: 2 }
465479
})
466-
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = :test_number_coerce, #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et), #test_map = :test_map ADD #test_number :test_number')
480+
expect(UpdateExpression).toBe('SET #test_string = if_not_exists(#test_string,:test_string), #test_number_coerce = if_not_exists(#test_number_coerce,:test_number_coerce), #test_boolean_default = if_not_exists(#test_boolean_default,:test_boolean_default), #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et), #test_map = :test_map ADD #test_number :test_number')
467481
expect(ExpressionAttributeNames).toEqual({
468482
'#_et': '_et',
469483
'#_ct': '_ct',
470484
'#_md': '_md',
485+
'#test_boolean_default': 'test_boolean_default',
471486
'#test_string': 'test_string',
472487
'#test_number': 'test_number',
473488
'#test_map': 'test_map',
474489
'#test_number_coerce': 'test_number_coerce'
475490
})
476491
expect(ExpressionAttributeValues).toHaveProperty(':_et')
477492
expect(ExpressionAttributeValues[':_et']).toBe('TestEntity')
478-
expect(ExpressionAttributeValues[':test_string']).toBe('test string')
493+
expect(ExpressionAttributeValues[':test_string']).toBe('default string')
479494
expect(ExpressionAttributeValues[':test_number']).toBe(10)
480495
expect(ExpressionAttributeValues[':test_map']).toEqual({ a: 1, b: 2 })
481496
expect(Key).toEqual({ pk: 'test@test.com', sk: 'test-sk' })
@@ -653,6 +668,7 @@ describe('update',()=>{
653668
'#_md': '_md',
654669
'#_et': '_et',
655670
'#attr1': 'pk',
671+
'#test_boolean_default': 'test_boolean_default',
656672
'#test_number_coerce': 'test_number_coerce'
657673
})
658674
expect(ExpressionAttributeValues).toHaveProperty(':attr1')

classes/Entity.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ class Entity {
625625
// if (hasValue(value)) {
626626
if (value !== undefined) {
627627
// Push the update to SET
628-
SET.push(mapping.default && !item[field] && !mapping.onUpdate ?
628+
SET.push(mapping.default !== undefined && item[field] === undefined && !mapping.onUpdate ?
629629
`#${field} = if_not_exists(#${field},:${field})`
630630
: `#${field} = :${field}`)
631631
// Add names and values
@@ -828,4 +828,4 @@ class Entity {
828828
} // end Entity
829829

830830
// Export the Entity class
831-
module.exports = Entity
831+
module.exports = Entity

0 commit comments

Comments
 (0)