Last active
November 21, 2018 04:02
-
-
Save njamaleddine/269d63a5fa4dc6350cb0ae8c8cfc32c4 to your computer and use it in GitHub Desktop.
fun with dynamodb (also install and start scripts for local dev)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const AWS = require('aws-sdk'); | |
| const moment = require('moment'); | |
| const config = require('../config'); | |
| const dynamodb = new AWS.DynamoDB({ | |
| apiVersion: config.dynamodb.apiVersion, | |
| endpoint: config.dynamodb.endpoint, | |
| region: config.dynamodb.region, | |
| maxRetries: config.dynamodb.maxRetries, | |
| retryDelayOptions: { | |
| base: config.dynamodb.retryDelayOptions.base, | |
| }, | |
| }); | |
| const documentClient = new AWS.DynamoDB.DocumentClient({ service: dynamodb }); | |
| /** | |
| * @description Maps JavaScript types to DynamoDB types | |
| * @param {*} Any - JavaScript Primitive or Object Type part of the JSON spec | |
| * @returns {*} new field mapped to a supported DynamoDB type | |
| */ | |
| function mapToDb(field) { | |
| const nullTypes = ['', null, undefined]; | |
| if (nullTypes.includes(field)) { | |
| return null; | |
| } if (field instanceof moment) { | |
| return field.toDate().toISOString(); | |
| } if (field instanceof Date) { | |
| return field.toISOString(); | |
| } if (field instanceof Array) { | |
| return field.map(item => mapToDb(item)); | |
| } if (typeof field === 'object') { | |
| const newObject = {}; | |
| Object.keys(field).forEach((key) => { | |
| newObject[key] = mapToDb(field[key]); | |
| }); | |
| return newObject; | |
| } | |
| // passthrough for every other type | |
| return field; | |
| } | |
| /** | |
| * @description Maps the fields of a JavaScript Object to DynamoDB types | |
| * @param {Object} | |
| * @returns {Object} new Object with the mapped types | |
| */ | |
| function getTableNameForEnv(table) { | |
| const environment = config.env ? config.env : 'local'; | |
| return `${environment}.${table}`; | |
| } | |
| module.exports = { | |
| dynamodb, | |
| documentClient, | |
| mapToDb, | |
| getTableNameForEnv, | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* global expect, describe, test */ | |
| const moment = require('moment'); | |
| const { mapToDb } = require('./dynamodb'); | |
| describe('mapToDb', () => { | |
| test('it converts empty strings to null', () => { | |
| expect(mapToDb('')).toEqual(null); | |
| }); | |
| test('it converts undefined to null', () => { | |
| expect(mapToDb(undefined)).toEqual(null); | |
| }); | |
| test('it converts null to null', () => { | |
| expect(mapToDb(null)).toEqual(null); | |
| }); | |
| test('it converts Dates to an iso8601 datetime string', () => { | |
| const date = new Date('2018-10-01'); | |
| expect(mapToDb(date)).toEqual('2018-10-01T00:00:00.000Z'); | |
| }); | |
| test('it converts a moment instance to an iso8601 datetime string', () => { | |
| const momentInstance = moment('2018-10-01'); | |
| expect(mapToDb(momentInstance)).toEqual('2018-10-01T00:00:00.000Z'); | |
| }); | |
| test('it converts fields of an Array to DynamoDB types', () => { | |
| const array = ['', new Date('2018-10-01')]; | |
| const dynamoArray = [null, '2018-10-01T00:00:00.000Z']; | |
| expect(mapToDb(array)).toEqual(dynamoArray); | |
| }); | |
| test('it converts a flat object to a dynamodb object', () => { | |
| const obj = { | |
| name: 'Bob', | |
| hometown: '', | |
| dateJoined: new Date('2018-10-11'), | |
| }; | |
| const expectedDynamoObject = { | |
| name: 'Bob', | |
| hometown: null, | |
| dateJoined: '2018-10-11T00:00:00.000Z', | |
| }; | |
| expect(mapToDb(obj)).toEqual(expectedDynamoObject); | |
| }); | |
| test('it converts object fields to DynamoDB types', () => { | |
| const obj = { | |
| name: 'Bob', | |
| hometown: '', | |
| dateJoined: new Date('2018-10-11'), | |
| locations: [ | |
| { | |
| name: 'Tokyo', | |
| arrival: new Date('2017-01-01'), | |
| }, | |
| ], | |
| }; | |
| const expectedDynamoObject = { | |
| name: 'Bob', | |
| hometown: null, | |
| dateJoined: '2018-10-11T00:00:00.000Z', | |
| locations: [ | |
| { | |
| name: 'Tokyo', | |
| arrival: '2017-01-01T00:00:00.000Z', | |
| }, | |
| ], | |
| }; | |
| expect(mapToDb(obj)).toEqual(expectedDynamoObject); | |
| }); | |
| test('it converts a multi-level nested object to a DynamoDB object', () => { | |
| const obj = { | |
| name: 'Bob', | |
| hometown: '', | |
| dateJoined: new Date('2018-10-11'), | |
| skills: { | |
| js: { | |
| node: { | |
| notes: '', | |
| dateLearned: new Date('2018-10-11'), | |
| }, | |
| }, | |
| }, | |
| countries: [ | |
| { | |
| name: 'Japan', | |
| cities: { | |
| name: 'Tokyo', | |
| arrival: new Date('2017-01-01'), | |
| }, | |
| }, | |
| { | |
| name: 'Spain', | |
| cities: { | |
| name: 'Madrid', | |
| arrival: new Date('2015-12-01'), | |
| }, | |
| }, | |
| ], | |
| }; | |
| const expectedDynamoObject = { | |
| name: 'Bob', | |
| hometown: null, | |
| dateJoined: '2018-10-11T00:00:00.000Z', | |
| skills: { | |
| js: { | |
| node: { | |
| notes: null, | |
| dateLearned: '2018-10-11T00:00:00.000Z', | |
| }, | |
| }, | |
| }, | |
| countries: [ | |
| { | |
| name: 'Japan', | |
| cities: { | |
| name: 'Tokyo', | |
| arrival: '2017-01-01T00:00:00.000Z', | |
| }, | |
| }, | |
| { | |
| name: 'Spain', | |
| cities: { | |
| name: 'Madrid', | |
| arrival: '2015-12-01T00:00:00.000Z', | |
| }, | |
| }, | |
| ], | |
| }; | |
| expect(mapToDb(obj)).toEqual(expectedDynamoObject); | |
| }); | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Setup script for Local Dynamodb | |
| # https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.DownloadingAndRunning.html | |
| DYNAMODB_LOCAL_TAR_URL="https://s3-us-west-2.amazonaws.com/dynamodb-local/dynamodb_local_latest.tar.gz" | |
| PRIVATE_DIRECTORY=".private" | |
| SETUP_DIRECTORY="$PRIVATE_DIRECTORY/setup" | |
| LOCAL_DYNAMODB_DIRECTORY="$SETUP_DIRECTORY/DynamoDBLocal_lib" | |
| LOCAL_DYNAMODB_JAR_FILE="$SETUP_DIRECTORY/DynamoDBLocal.jar" | |
| if [ -f "$LOCAL_DYNAMODB_JAR_FILE" ] && [ -d "$LOCAL_DYNAMODB_DIRECTORY" ]; then | |
| # Exit setup if local dynamodb exists | |
| exit 1 | |
| else | |
| echo "$LOCAL_DYNAMODB_JAR_FILE does not exist, starting setup" | |
| fi | |
| if [ ! -d "$SETUP_DIRECTORY" ]; then | |
| echo "No $SETUP_DIRECTORY directory, creating one ..." | |
| mkdir -p $SETUP_DIRECTORY | |
| fi | |
| echo "Downloading local dynamodb to $SETUP_DIRECTORY ..." | |
| curl $DYNAMODB_LOCAL_TAR_URL -o "$SETUP_DIRECTORY/dynamodb_local_latest.tar.gz" | |
| tar -xvzf $SETUP_DIRECTORY/dynamodb_local_latest.tar.gz -C $SETUP_DIRECTORY | |
| echo "Done setting up local dynamodb environment!" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| SETUP_DIRECTORY=".private/setup/" | |
| LOCAL_DYNAMODB_DIRECTORY="$SETUP_DIRECTORY/DynamoDBLocal_lib" | |
| LOCAL_DYNAMODB_JAR_FILE="$SETUP_DIRECTORY/DynamoDBLocal.jar" | |
| if [ ! -f "$LOCAL_DYNAMODB_JAR_FILE" ] || [ ! -d "$LOCAL_DYNAMODB_DIRECTORY" ]; then | |
| scripts/local_dynamodb/install.sh | |
| fi | |
| echo "Starting local dynamodb ..." | |
| java -Djava.library.path=$LOCAL_DYNAMODB_DIRECTORY -jar "$SETUP_DIRECTORY/DynamoDBLocal.jar" -sharedDb |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment