From f0c182e18058da65ffcfd6f281fd5ee5aea5ece6 Mon Sep 17 00:00:00 2001 From: apanicek Date: Wed, 2 Jan 2019 15:48:58 +0100 Subject: [PATCH 1/3] Adding support for TTL --- .../src/DataMapper.spec.ts | 41 +++++++++++++++++++ .../dynamodb-data-mapper/src/DataMapper.ts | 23 ++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/packages/dynamodb-data-mapper/src/DataMapper.spec.ts b/packages/dynamodb-data-mapper/src/DataMapper.spec.ts index 686cc6b6..122d83ef 100644 --- a/packages/dynamodb-data-mapper/src/DataMapper.spec.ts +++ b/packages/dynamodb-data-mapper/src/DataMapper.spec.ts @@ -1586,6 +1586,47 @@ describe('DataMapper', () => { }); }); + describe('#updateTimeToLive', () => { + const waitPromiseFunc = jest.fn(() => Promise.resolve()); + const updateTimeToLivePromiseFunc = jest.fn(() => Promise.resolve({})); + const mockDynamoDbClient = { + config: {}, + updateTimeToLive: jest.fn(() => ({promise: updateTimeToLivePromiseFunc})), + waitFor: jest.fn(() => ({promise: waitPromiseFunc})), + }; + + beforeEach(() => { + updateTimeToLivePromiseFunc.mockClear(); + mockDynamoDbClient.updateTimeToLive.mockClear(); + waitPromiseFunc.mockClear(); + mockDynamoDbClient.waitFor.mockClear(); + }); + + const mapper = new DataMapper({ + client: mockDynamoDbClient as any, + }); + + class Item { + get [DynamoDbTable]() { return 'foo' } + + get [DynamoDbSchema]() { + return { id: { type: 'String', keyType: 'HASH' }, date: {type: 'Date'} }; + } + } + + it('should create and send UpdateTimeToLive request', + async () => { + await mapper.updateTimeToLive(Item, true, 'date'); + + expect(mockDynamoDbClient.updateTimeToLive.mock.calls).toEqual([ + [ { TableName: 'foo', TimeToLiveSpecification: { Enabled: true, AttributeName: 'date' } } ], + ]); + + expect(mockDynamoDbClient.waitFor.mock.calls).toEqual([ + [ 'tableExists', { TableName: 'foo' } ], + ]); + }); + }); describe('#ensureGlobalSecondaryIndexExists', () => { const waitPromiseFunc = jest.fn(() => Promise.resolve()); diff --git a/packages/dynamodb-data-mapper/src/DataMapper.ts b/packages/dynamodb-data-mapper/src/DataMapper.ts index e91a0ba3..29453142 100644 --- a/packages/dynamodb-data-mapper/src/DataMapper.ts +++ b/packages/dynamodb-data-mapper/src/DataMapper.ts @@ -83,7 +83,7 @@ import { KeySchemaElement, LocalSecondaryIndexList, Projection, - PutItemInput, + PutItemInput, TimeToLiveDescription, UpdateItemInput, } from 'aws-sdk/clients/dynamodb'; import DynamoDB = require('aws-sdk/clients/dynamodb'); @@ -496,6 +496,27 @@ export class DataMapper { await this.client.waitFor('tableNotExists', {TableName}).promise(); } + /** + * Perform a UpdateTimeToLive on provided table. + * + * According to AWS documentation, applying across all partitions can take 1 hour. + * That's why this feature doesn't wait for complete process. + * + * @param valueConstructor The constructor used for values in the table. + * @param Enabled Boolean value that represents desired state of TTL + * @param AttributeName "Expiration" attribute which is used for TTL mechanism + * Must be type of Number and contain unix epoch time of record's expiration + * @throws Throws exception if TTL is currently set to desired state or when you exceed maximum number of commands + * in some period of time + */ + async updateTimeToLive(valueConstructor: ZeroArgumentsConstructor, Enabled: boolean, AttributeName: string) { + const TableName = this.getTableName(valueConstructor.prototype); + await this.client.updateTimeToLive({ + TableName, + TimeToLiveSpecification: { Enabled, AttributeName } + }).promise(); + } + /** * If the table does not already exist, perform a CreateTable operation * using the schema accessible via the {DynamoDbSchema} property and the From c2ae722ae93c3fead5185192a92b0fa677a03e35 Mon Sep 17 00:00:00 2001 From: apanicek Date: Wed, 2 Jan 2019 15:59:24 +0100 Subject: [PATCH 2/3] Removing unused import --- packages/dynamodb-data-mapper/src/DataMapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dynamodb-data-mapper/src/DataMapper.ts b/packages/dynamodb-data-mapper/src/DataMapper.ts index 29453142..9b6d8b54 100644 --- a/packages/dynamodb-data-mapper/src/DataMapper.ts +++ b/packages/dynamodb-data-mapper/src/DataMapper.ts @@ -83,7 +83,7 @@ import { KeySchemaElement, LocalSecondaryIndexList, Projection, - PutItemInput, TimeToLiveDescription, + PutItemInput, UpdateItemInput, } from 'aws-sdk/clients/dynamodb'; import DynamoDB = require('aws-sdk/clients/dynamodb'); From 224ccaba36862e2856a4d0bf2ea02ca53420cedb Mon Sep 17 00:00:00 2001 From: apanicek Date: Wed, 2 Jan 2019 16:02:36 +0100 Subject: [PATCH 3/3] Removing unused waitFor call check from tests --- packages/dynamodb-data-mapper/src/DataMapper.spec.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/dynamodb-data-mapper/src/DataMapper.spec.ts b/packages/dynamodb-data-mapper/src/DataMapper.spec.ts index 122d83ef..a49e6c81 100644 --- a/packages/dynamodb-data-mapper/src/DataMapper.spec.ts +++ b/packages/dynamodb-data-mapper/src/DataMapper.spec.ts @@ -1621,10 +1621,6 @@ describe('DataMapper', () => { expect(mockDynamoDbClient.updateTimeToLive.mock.calls).toEqual([ [ { TableName: 'foo', TimeToLiveSpecification: { Enabled: true, AttributeName: 'date' } } ], ]); - - expect(mockDynamoDbClient.waitFor.mock.calls).toEqual([ - [ 'tableExists', { TableName: 'foo' } ], - ]); }); });