summaryrefslogtreecommitdiff
path: root/Homework/cs5260/consumer/dao/DynamoWidgetDAO.ts
diff options
context:
space:
mode:
Diffstat (limited to 'Homework/cs5260/consumer/dao/DynamoWidgetDAO.ts')
-rw-r--r--Homework/cs5260/consumer/dao/DynamoWidgetDAO.ts100
1 files changed, 100 insertions, 0 deletions
diff --git a/Homework/cs5260/consumer/dao/DynamoWidgetDAO.ts b/Homework/cs5260/consumer/dao/DynamoWidgetDAO.ts
new file mode 100644
index 0000000..a90788f
--- /dev/null
+++ b/Homework/cs5260/consumer/dao/DynamoWidgetDAO.ts
@@ -0,0 +1,100 @@
+import { Widget, WidgetT } from "@/shared/schema";
+import { WidgetDAO } from ".";
+import { TracingLogger } from "@/consumer/log";
+import {
+ AttributeValue,
+ DeleteItemCommand,
+ DynamoDBClient,
+ GetItemCommand,
+ PutItemCommand,
+} from "@aws-sdk/client-dynamodb";
+
+export class DynamoWidgetDAO implements WidgetDAO {
+ private table: string;
+ private ddbClient: DynamoDBClient;
+ private logger: TracingLogger;
+
+ constructor(table: string, ddbClient: DynamoDBClient, logger: TracingLogger) {
+ this.table = table;
+ this.ddbClient = ddbClient;
+ this.logger = logger;
+ }
+
+ public async retrieve(widget: WidgetT) {
+ const getReq = new GetItemCommand({
+ TableName: this.table,
+ Key: {
+ id: {
+ S: widget.id,
+ },
+ },
+ });
+
+ const response = await this.ddbClient.send(getReq);
+ if (response.Item) {
+ this.logger.info(`sucessfully retrieved Widget=(${widget.id})`);
+ return this.deflate(response.Item);
+ }
+ }
+
+ public async save(widget: WidgetT) {
+ const putReq = new PutItemCommand({
+ TableName: this.table,
+ Item: this.inflate(widget),
+ });
+
+ await this.ddbClient.send(putReq);
+
+ this.logger.info(`sucessfully saved Widget=(${widget.id})`);
+ return widget;
+ }
+
+ public async delete(widget: WidgetT) {
+ const deleteReq = new DeleteItemCommand({
+ TableName: this.table,
+ Key: {
+ id: { S: widget.id },
+ },
+ });
+
+ await this.ddbClient.send(deleteReq);
+
+ this.logger.info(`sucessfully deleted Widget=(${widget.id})`);
+ return widget;
+ }
+
+ private inflate(widget: WidgetT): Record<string, AttributeValue> {
+ const additionalAttributes =
+ widget.otherAttributes?.reduce((acc, { name, value }) => {
+ acc[name] = { S: value };
+ return acc;
+ }, {} as Record<string, { S: string }>) ?? {};
+ if (widget.label) additionalAttributes["label"] = { S: widget.label };
+ if (widget.description)
+ additionalAttributes["description"] = { S: widget.description };
+
+ return {
+ id: { S: widget.id },
+ owner: { S: widget.owner },
+ ...additionalAttributes,
+ };
+ }
+
+ private deflate(item: Record<string, AttributeValue>): WidgetT {
+ const respWidget = Object.keys(item).reduce((widge, key: string) => {
+ const attributeValue = item![key];
+ if (["id", "owner", "label", "description"].includes(key)) {
+ widge[key] = attributeValue.S;
+ return widge;
+ }
+
+ const attribute = { name: key, value: attributeValue.S! };
+ widge["otherAttributes"] = widge["otherAttributes"]?.concat([
+ attribute,
+ ]) ?? [attribute];
+
+ return widge;
+ }, {} as Record<string, any>);
+ return Widget.parse(respWidget);
+ }
+}