@bitblit/ratchet-aws
Version:
Common tools for use with AWS browser and node
140 lines • 6.31 kB
JavaScript
import { CreateTableCommand, DeleteTableCommand, DescribeTableCommand, ListTablesCommand, ResourceNotFoundException, } from '@aws-sdk/client-dynamodb';
import { RequireRatchet } from '@bitblit/ratchet-common/lang/require-ratchet';
import { Logger } from '@bitblit/ratchet-common/logger/logger';
import { ErrorRatchet } from '@bitblit/ratchet-common/lang/error-ratchet';
import { PromiseRatchet } from '@bitblit/ratchet-common/lang/promise-ratchet';
export class DynamoTableRatchet {
awsDDB;
constructor(awsDDB) {
this.awsDDB = awsDDB;
if (!awsDDB) {
throw 'awsDDB may not be null';
}
}
async deleteTable(tableName, waitForDelete = true) {
RequireRatchet.notNullOrUndefined(tableName);
const input = {
TableName: tableName,
};
Logger.debug('Deleting ddb table %s', tableName);
const rval = await this.awsDDB.send(new DeleteTableCommand(input));
if (waitForDelete) {
Logger.debug('Table marked for delete, waiting for deletion');
await this.waitForTableDelete(tableName);
}
return rval;
}
async createTable(input, waitForReady = true, replaceIfExists = false) {
RequireRatchet.notNullOrUndefined(input);
RequireRatchet.notNullOrUndefined(input.TableName);
Logger.debug('Creating new table : %j', input);
const exists = await this.tableExists(input.TableName);
if (exists) {
if (replaceIfExists) {
Logger.debug('Table %s exists and replace specified - deleting', input.TableName);
await this.deleteTable(input.TableName);
}
else {
ErrorRatchet.throwFormattedErr('Cannot create table %s - exists already and replace not specified', input.TableName);
}
}
const rval = await this.awsDDB.send(new CreateTableCommand(input));
if (waitForReady) {
Logger.debug('Table created, awaiting ready');
await this.waitForTableReady(input.TableName);
}
return rval;
}
async waitForTableReady(tableName) {
let rval = true;
let out = await this.safeDescribeTable(tableName);
while (!!out && !!out.Table && out.Table.TableStatus !== 'ACTIVE') {
Logger.silly('Table not ready - waiting 2 seconds');
await PromiseRatchet.wait(2000);
out = await this.safeDescribeTable(tableName);
}
if (!out && !out.Table) {
Logger.warn('Cannot wait for %s to be ready - table does not exist', tableName);
rval = false;
}
return rval;
}
async waitForTableDelete(tableName) {
let out = await this.safeDescribeTable(tableName);
while (out) {
Logger.silly('Table %s still exists, waiting 2 seconds (State is %s)', tableName, out.Table.TableStatus);
await PromiseRatchet.wait(2000);
out = await this.safeDescribeTable(tableName);
}
}
async tableExists(tableName) {
const desc = await this.safeDescribeTable(tableName);
return !!desc;
}
async listAllTables() {
const input = {};
let rval = [];
do {
const out = await this.awsDDB.send(new ListTablesCommand(input));
rval = rval.concat(out.TableNames);
input.ExclusiveStartTableName = out.LastEvaluatedTableName;
} while (input.ExclusiveStartTableName);
return rval;
}
async safeDescribeTable(tableName) {
try {
const out = await this.awsDDB.send(new DescribeTableCommand({ TableName: tableName }));
return out;
}
catch (err) {
if (err instanceof ResourceNotFoundException) {
return null;
}
else {
throw err;
}
}
}
async copyTable(srcTableName, dstTableName, overrides, copyData) {
RequireRatchet.notNullUndefinedOrOnlyWhitespaceString(srcTableName, 'srcTableName');
RequireRatchet.notNullUndefinedOrOnlyWhitespaceString(dstTableName, 'dstTableName');
if (copyData) {
throw ErrorRatchet.fErr('Cannot copy %s to %s - copy data not supported yet', srcTableName, dstTableName);
}
const srcTableDef = await this.safeDescribeTable(srcTableName);
if (await this.tableExists(dstTableName)) {
throw ErrorRatchet.fErr('Cannot copy to %s - table already exists', dstTableName);
}
if (!srcTableDef) {
throw ErrorRatchet.fErr('Cannot copy %s - doesnt exist', srcTableName);
}
const _ads = srcTableDef.Table.AttributeDefinitions;
const _ks = srcTableDef.Table.KeySchema;
const _gi = srcTableDef.Table.GlobalSecondaryIndexes;
const createInput = Object.assign({}, overrides || {}, {
AttributeDefinitions: srcTableDef.Table.AttributeDefinitions,
TableName: dstTableName,
KeySchema: srcTableDef.Table.KeySchema,
LocalSecondaryIndexes: srcTableDef.Table.LocalSecondaryIndexes,
GlobalSecondaryIndexes: srcTableDef.Table.GlobalSecondaryIndexes.map((gi) => {
const output = gi;
if (output.ProvisionedThroughput?.WriteCapacityUnits === 0 || output.ProvisionedThroughput?.ReadCapacityUnits === 0) {
output.ProvisionedThroughput = undefined;
}
return output;
}),
BillingMode: srcTableDef.Table.BillingModeSummary.BillingMode,
ProvisionedThroughput: srcTableDef.Table.BillingModeSummary.BillingMode === 'PROVISIONED'
? srcTableDef.Table.ProvisionedThroughput
: undefined,
StreamSpecification: srcTableDef.Table.StreamSpecification,
SSESpecification: srcTableDef.Table.SSEDescription,
Tags: undefined,
TableClass: srcTableDef.Table.TableClassSummary?.TableClass,
DeletionProtectionEnabled: srcTableDef.Table.DeletionProtectionEnabled,
});
const rval = await this.awsDDB.send(new CreateTableCommand(createInput));
return rval;
}
}
//# sourceMappingURL=dynamo-table-ratchet.js.map