-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
aws-cdk-dynamodb: Initial external release
Co-authored-by: Romain Marcadier-Muller <rmuller@amazon.com> Co-authored-by: Breland Miley <brelandm@amazon.com> Co-authored-by: Mitch Garnaat <garnaat@amazon.com> Co-authored-by: Shiv Lakshminarayan <shivlaks@amazon.com> Co-authored-by: Max Hall <hallmaxw@amazon.com> Co-authored-by: Doug Schwartz <dougsch@amazon.com>
- Loading branch information
1 parent
284177d
commit 9b34fe8
Showing
8 changed files
with
3,805 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
*.js | ||
*.js.map | ||
*.d.ts | ||
node_modules | ||
dist | ||
tsconfig.json |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
## AWS DynamoDB Construct Library | ||
Add a DynamoDB table to you stack like so: | ||
```ts | ||
import { Table } from 'aws-cdk-dynamodb'; | ||
|
||
const defaultTable = new Table(stack, 'TableName'); | ||
|
||
const customTable = new Table(stack, 'CustomTable', { | ||
readCapacity: readUnits, // Default is 5 | ||
writeCapacity: writeUnits, // Default is 5 | ||
tableName: 'MyTableName' // Default is CloudFormation-generated, which is the preferred approach | ||
}) | ||
``` |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { Construct } from 'aws-cdk'; | ||
import { dynamodb } from 'aws-cdk-resources'; | ||
|
||
const HASH_KEY_TYPE = 'HASH'; | ||
const RANGE_KEY_TYPE = 'RANGE'; | ||
|
||
export interface TableProps { | ||
/** | ||
* The read capacity for the table. Careful if you add Global Secondary Indexes, as | ||
* those will share the table's provisioned throughput. | ||
* @default 5 | ||
*/ | ||
readCapacity?: number; | ||
/** | ||
* The write capacity for the table. Careful if you add Global Secondary Indexes, as | ||
* those will share the table's provisioned throughput. | ||
* @default 5 | ||
*/ | ||
writeCapacity?: number; | ||
|
||
/** | ||
* Enforces a particular physical table name. | ||
* @default <generated> | ||
*/ | ||
tableName?: string; | ||
} | ||
|
||
/** | ||
* Provides a DynamoDB table. | ||
*/ | ||
export class Table extends Construct { | ||
private readonly table: dynamodb.TableResource; | ||
|
||
private readonly keySchema = new Array<dynamodb.TableResource.KeySchemaProperty>(); | ||
private readonly attributeDefinitions = new Array<dynamodb.TableResource.AttributeDefinitionProperty>(); | ||
|
||
constructor(parent: Construct, name: string, props: TableProps = {}) { | ||
super(parent, name); | ||
|
||
const readCapacityUnits = props.readCapacity || 5; | ||
const writeCapacityUnits = props.writeCapacity || 5; | ||
|
||
this.table = new dynamodb.TableResource(this, 'Resource', { | ||
tableName: props.tableName, | ||
keySchema: this.keySchema, | ||
attributeDefinitions: this.attributeDefinitions, | ||
provisionedThroughput: { readCapacityUnits, writeCapacityUnits } | ||
}); | ||
|
||
if (props.tableName) { this.addMetadata('aws:cdk:hasPhysicalName', props.tableName); } | ||
} | ||
|
||
public get tableArn() { | ||
return this.table.tableArn; | ||
} | ||
|
||
public get tableName() { | ||
return this.table.ref; | ||
} | ||
|
||
public get tableStreamArn() { | ||
return this.table.tableStreamArn; | ||
} | ||
|
||
public addPartitionKey(name: string, type: KeyAttributeType): this { | ||
this.addKey(name, type, HASH_KEY_TYPE); | ||
return this; | ||
} | ||
|
||
public addSortKey(name: string, type: KeyAttributeType): this { | ||
this.addKey(name, type, RANGE_KEY_TYPE); | ||
return this; | ||
} | ||
|
||
public validate(): string[] { | ||
const errors = new Array<string>(); | ||
if (!this.findKey(HASH_KEY_TYPE)) { | ||
errors.push('a partition key must be specified'); | ||
} | ||
return errors; | ||
} | ||
|
||
private findKey(keyType: string) { | ||
return this.keySchema.find(prop => prop.keyType === keyType); | ||
} | ||
|
||
private addKey(name: string, type: KeyAttributeType, keyType: string) { | ||
const existingProp = this.findKey(keyType); | ||
if (existingProp) { | ||
throw new Error(`Unable to set ${name} as a ${keyType} key, because ${existingProp.attributeName} is a ${keyType} key`); | ||
} | ||
this.registerAttribute(name, type); | ||
this.keySchema.push({ | ||
attributeName: name, | ||
keyType | ||
}); | ||
return this; | ||
} | ||
|
||
private registerAttribute(name: string, type: KeyAttributeType) { | ||
const existingDef = this.attributeDefinitions.find(def => def.attributeName === name); | ||
if (existingDef && existingDef.attributeType !== type) { | ||
throw new Error(`Unable to specify ${name} as ${type} because it was already defined as ${existingDef.attributeType}`); | ||
} | ||
if (!existingDef) { | ||
this.attributeDefinitions.push({ | ||
attributeName: name, | ||
attributeType: type | ||
}); | ||
} | ||
} | ||
} | ||
|
||
export enum KeyAttributeType { | ||
Binary = 'B', | ||
Number = 'N', | ||
String = 'S', | ||
} |
Oops, something went wrong.