Skip to content

Instantly share code, notes, and snippets.

@robzhu
Created May 3, 2019 20:42
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save robzhu/3a6017c85758a682c759176f92e00fa7 to your computer and use it in GitHub Desktop.
Save robzhu/3a6017c85758a682c759176f92e00fa7 to your computer and use it in GitHub Desktop.
// credentials are stored in a .env file with the following contents:
//
// accessKeyId=
// secretAccessKey=
// region=
// tableName=
// See: https://github.com/motdotla/dotenv
require("dotenv").config();
import * as AWS from "aws-sdk";
import { ConfigurationOptions } from "aws-sdk/lib/config";
const AwsConfig = {
accessKeyId: process.env.accessKeyId,
secretAccessKey: process.env.secretAccessKey,
region: process.env.region
};
AWS.config.update(AwsConfig as ConfigurationOptions);
const DynamoDB = new AWS.DynamoDB.DocumentClient();
const TableName = process.env.tableName;
interface Person {
id: string;
name: string;
friends: string[];
}
async function writeInitialDoc() {
await DynamoDB.put({
TableName,
Item: {
id: "1234",
name: "carl",
friends: ["meatwad", "frylock", "shake"]
}
}).promise();
}
async function writeDocWithSet() {
await DynamoDB.put({
TableName,
Item: {
id: "1234",
name: "carl",
friends: DynamoDB.createSet(["meatwad", "frylock", "shake"])
}
}).promise();
const result = await DynamoDB.get({
TableName,
Key: { id: "1234" }
}).promise();
console.log(result.Item.friends);
console.log(typeof result.Item.friends);
console.log(Array.isArray(result.Item.friends.values));
}
async function removeFriendByValue(friendName: string) {
const Key = { id: "1234" };
// fetch the document
let result = await DynamoDB.get({
TableName,
Key
}).promise();
// find the index
const indexToRemove = result.Item.friends.indexOf(friendName);
if (indexToRemove === -1) {
// element not found
return;
}
// remove-by-index
await DynamoDB.update({
TableName,
Key,
UpdateExpression: `REMOVE friends[${indexToRemove}]`
}).promise();
}
// helper function to return the error in a promise
async function updateWithErrorWrapper(params: any): Promise<any> {
return new Promise(resolve => {
DynamoDB.update(params, (err, data) => {
resolve({ err, data });
});
});
}
async function conditionalRemoveFriendByValue(friendName: string) {
const Key = { id: "1234" };
// fetch the document
let result = await DynamoDB.get({
TableName,
Key
}).promise();
// find the index
let indexToRemove = result.Item.friends.indexOf(friendName);
if (indexToRemove === -1) {
// element not found
return false;
}
// remove-by-index IFF the attribute contains the element we want to remove.
const { err, data } = await updateWithErrorWrapper({
TableName,
Key,
UpdateExpression: `REMOVE friends[${indexToRemove}]`,
ConditionExpression: `friends[${indexToRemove}] = :valueToRemove`,
ExpressionAttributeValues: {
":valueToRemove": friendName
}
});
if (err) {
if (err.code === "ConditionalCheckFailedException") {
console.error("condition expression failed");
} else {
console.error("unhandled error: " + err);
}
return false;
}
return true;
}
async function conditionalVersionRemoveFriendByValue(friendName: string) {
const Key = { id: "1234" };
// fetch the document
let document = (await DynamoDB.get({
TableName,
Key
}).promise()).Item;
// find the index
let indexToRemove = document.friends.indexOf(friendName);
let version = document.version;
if (indexToRemove === -1) {
// element not found
return false;
}
// remove-by-index IFF the version field matches
const { err, data } = await updateWithErrorWrapper({
TableName,
Key,
UpdateExpression: `
REMOVE friends[${indexToRemove}]
ADD version :incrementVersionBy
`,
ConditionExpression: `version = :version`,
ExpressionAttributeValues: {
":version": version,
":incrementVersionBy": 1
}
});
if (err) {
if (err.code === "ConditionalCheckFailedException") {
console.error("condition expression failed");
} else {
console.error("unhandled error: " + err);
}
return false;
}
return true;
}
async function deleteFriendByValue(friendName: string) {
const Key = { id: "1234" };
// Delete the value from the set. This operation is idempotent and will not
// produce an error if the value(s) are missing.
const { err, data } = await updateWithErrorWrapper({
TableName,
Key,
UpdateExpression: `DELETE friends :valuesToRemove`,
ExpressionAttributeValues: {
":valuesToRemove": DynamoDB.createSet([friendName])
}
});
if (err) {
console.error("unhandled error: " + err);
return false;
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment