From 9207355ed3f18022a3081ad9c621bf2fd1d58ffa Mon Sep 17 00:00:00 2001 From: Simon Mumenthaler Date: Tue, 26 Mar 2019 16:29:18 +0100 Subject: [PATCH 1/2] fix(update-expression-builder): index in attribute path closes #200 --- .../update-expression-builder.spec.ts | 20 +++++++++++++++++++ .../expression/update-expression-builder.ts | 2 +- .../request/update/update.request.spec.ts | 12 ++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/dynamo/expression/update-expression-builder.spec.ts b/src/dynamo/expression/update-expression-builder.spec.ts index f23d87a4a..3aa1a476b 100644 --- a/src/dynamo/expression/update-expression-builder.spec.ts +++ b/src/dynamo/expression/update-expression-builder.spec.ts @@ -26,6 +26,16 @@ describe('buildUpdateExpression', () => { }) }) + it('should build expression for number at document path ', () => { + const exp = buildUpdateExpression('numberValues[0]', op, [23], [], metaDataU) + expect(exp).toEqual({ + attributeNames: { '#numberValues': 'numberValues' }, + attributeValues: { ':numberValues_at_0': { N: '23' } }, + statement: '#numberValues[0] = #numberValues[0] + :numberValues_at_0', + type: 'SET', + }) + }) + it('should throw when not number', () => { expect(() => buildUpdateExpression('age', op, ['notANumber'], [], metaDataS)).toThrow() }) @@ -43,6 +53,16 @@ describe('buildUpdateExpression', () => { }) }) + it('should build expression for number at document path ', () => { + const exp = buildUpdateExpression('numberValues[0]', op, [23], [], metaDataU) + expect(exp).toEqual({ + attributeNames: { '#numberValues': 'numberValues' }, + attributeValues: { ':numberValues_at_0': { N: '23' } }, + statement: '#numberValues[0] = #numberValues[0] - :numberValues_at_0', + type: 'SET', + }) + }) + it('should throw when not number', () => { expect(() => buildUpdateExpression('age', op, ['notANumber'], [], metaDataS)).toThrow() }) diff --git a/src/dynamo/expression/update-expression-builder.ts b/src/dynamo/expression/update-expression-builder.ts index bd35dab43..ddc308d37 100644 --- a/src/dynamo/expression/update-expression-builder.ts +++ b/src/dynamo/expression/update-expression-builder.ts @@ -100,7 +100,7 @@ function buildDefaultExpression( // special case: [same as in buildDefaultConditionExpression] // we have the metadata for an Array/Set of an Object, // but only get a single item when using `attribute('myCollectionProp[0]').set({})` - if (operator.action === 'set' && /\[\d+\]$/.test(attributePath)) { + if (/\[\d+\]$/.test(attributePath)) { attribute = toDbOne(values[0], getPropertyPath(propertyMetadata, attributePath), alterCollectionPropertyMetadataForSingleItem(propertyMetadata)) } else { attribute = toDbOne(values[0], propertyMetadata) diff --git a/src/dynamo/request/update/update.request.spec.ts b/src/dynamo/request/update/update.request.spec.ts index fa98fea2d..cb3e50baa 100644 --- a/src/dynamo/request/update/update.request.spec.ts +++ b/src/dynamo/request/update/update.request.spec.ts @@ -53,7 +53,7 @@ describe('update request', () => { expect(req.params.ReturnValues).toEqual('UPDATED_OLD') }) - it('should add operations', () => { + it('should add operation 1', () => { const now = new Date() const request = new UpdateRequest(null, UpdateModel, 'myId') request.operations(update('lastUpdated').set(now)) @@ -64,6 +64,16 @@ describe('update request', () => { ':lastUpdated': { S: now.toISOString() }, }) }) + it('should add operation 2', () => { + const request = new UpdateRequest(null, UpdateModel, 'myId') + request.operations(update('numberValues[1]').incrementBy(42)) + + expect(request.params.UpdateExpression).toBe('SET #numberValues[1] = #numberValues[1] + :numberValues_at_1') + expect(request.params.ExpressionAttributeNames).toEqual({ '#numberValues': 'numberValues' }) + expect(request.params.ExpressionAttributeValues).toEqual({ + ':numberValues_at_1': { N: '42' }, + }) + }) it('should allow to add multiple operations', () => { const request = new UpdateRequest(null, UpdateModel, 'myId').operations( From 7267f5dd13b9a24b15c69692df21c66ab7d5ff2a Mon Sep 17 00:00:00 2001 From: Simon Mumenthaler Date: Wed, 27 Mar 2019 13:59:38 +0100 Subject: [PATCH 2/2] docs(update-expression-builder): edit comment for special case --- src/dynamo/expression/update-expression-builder.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dynamo/expression/update-expression-builder.ts b/src/dynamo/expression/update-expression-builder.ts index ddc308d37..3cd5e92db 100644 --- a/src/dynamo/expression/update-expression-builder.ts +++ b/src/dynamo/expression/update-expression-builder.ts @@ -99,7 +99,9 @@ function buildDefaultExpression( // special case: [same as in buildDefaultConditionExpression] // we have the metadata for an Array/Set of an Object, - // but only get a single item when using `attribute('myCollectionProp[0]').set({})` + // but only get a single item when using list indexes in attributePath + // e.g. `attribute('myCollectionProp[0]').set(...)` + // (not exclusive to `.set(...)` but all updateActions) if (/\[\d+\]$/.test(attributePath)) { attribute = toDbOne(values[0], getPropertyPath(propertyMetadata, attributePath), alterCollectionPropertyMetadataForSingleItem(propertyMetadata)) } else {