UNPKG

@bitblit/ratchet-aws

Version:

Common tools for use with AWS browser and node

140 lines 6.31 kB
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