move dynamodb table name and region to env variables, thereby decoupling application with db/backend variables

This commit is contained in:
Hikmet 2024-02-03 15:10:03 +03:00
parent cf43fb5a5a
commit 03f0a7a406
4 changed files with 41 additions and 32 deletions

View File

@ -7,6 +7,9 @@ import { DynamoDBClientSingleton } from "@/lib/utils/dynamo_db_client_singleton"
const dynamoDB = DynamoDBClientSingleton.getInstance();
export class DynamoDBActivityRepository implements IActivityRepository {
private static tableName = process.env.DYNAMODB_TABLE_NAME;
private static primaryKey = "theme";
createActivity = async (
themeId: string,
lessonId: string,
@ -17,8 +20,8 @@ export class DynamoDBActivityRepository implements IActivityRepository {
delete activityToSave.id;
const updateCommand = new UpdateItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: themeId }),
TableName: DynamoDBActivityRepository.tableName,
Key: marshall({ pk: DynamoDBActivityRepository.primaryKey, id: themeId }),
UpdateExpression: `SET #lessons.#lessonId.#activities.#idOrder = list_append(#lessons.#lessonId.#activities.#idOrder, :activityId), #lessons.#lessonId.#activities.#activityId = :activity`,
ExpressionAttributeNames: {
"#lessons": "lessons",
@ -46,8 +49,8 @@ export class DynamoDBActivityRepository implements IActivityRepository {
delete activityToSave.id;
const updateCommand = new UpdateItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: themeId }),
TableName: DynamoDBActivityRepository.tableName,
Key: marshall({ pk: DynamoDBActivityRepository.primaryKey, id: themeId }),
UpdateExpression: `SET #lessons.#lessonId.#activities.#activityId = :activity`,
ExpressionAttributeNames: {
"#lessons": "lessons",
@ -74,8 +77,8 @@ export class DynamoDBActivityRepository implements IActivityRepository {
activityId
);
const updateCommand = new UpdateItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: themeId }),
TableName: DynamoDBActivityRepository.tableName,
Key: marshall({ pk: DynamoDBActivityRepository.primaryKey, id: themeId }),
UpdateExpression: `REMOVE #lessons.#lessonId.#activities.#activityId, #lessons.#lessonId.#activities.#idOrder[${activityIndex}]`,
ExpressionAttributeNames: {
"#lessons": "lessons",
@ -95,8 +98,8 @@ export class DynamoDBActivityRepository implements IActivityRepository {
activityId: string
): Promise<DBActivity> => {
const queryCommand = new GetItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: themeId }),
TableName: DynamoDBActivityRepository.tableName,
Key: marshall({ pk: DynamoDBActivityRepository.primaryKey, id: themeId }),
ProjectionExpression: "#lessons.#lessonId.#activities.#activityId",
ExpressionAttributeNames: {
"#lessons": "lessons",
@ -118,8 +121,8 @@ export class DynamoDBActivityRepository implements IActivityRepository {
): Promise<number> => {
let activityIndex = -1;
const getIdOrderCommand = new GetItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: themeId }),
TableName: DynamoDBActivityRepository.tableName,
Key: marshall({ pk: DynamoDBActivityRepository.primaryKey, id: themeId }),
ProjectionExpression: "#lessons.#lessonId.#activities.#idOrder",
ExpressionAttributeNames: {
"#lessons": "lessons",

View File

@ -7,14 +7,17 @@ import ILessonRepository from "./lesson_repository";
const dynamoDB = DynamoDBClientSingleton.getInstance();
export class DynamoDBLessonRepository implements ILessonRepository {
private static tableName = process.env.DYNAMODB_TABLE_NAME;
private static primaryKey = "theme";
createLesson = async (
themeId: string,
lessonId: string,
lesson: DBLesson
) => {
const updateCommand = new UpdateItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: themeId }),
TableName: DynamoDBLessonRepository.tableName,
Key: marshall({ pk: DynamoDBLessonRepository.primaryKey, id: themeId }),
UpdateExpression: `SET #lessons.#idOrder = list_append(#lessons.#idOrder, :lessonId), #lessons.#lessonId = :lesson`,
ExpressionAttributeNames: {
"#lessons": "lessons",
@ -36,8 +39,8 @@ export class DynamoDBLessonRepository implements ILessonRepository {
lesson: Omit<DBLesson, "activities">
): Promise<any> => {
const command = new UpdateItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: themeId }),
TableName: DynamoDBLessonRepository.tableName,
Key: marshall({ pk: DynamoDBLessonRepository.primaryKey, id: themeId }),
UpdateExpression: `SET #lessons.#lessonId.#title = :title, #lessons.#lessonId.#explanation = :explanation`,
ConditionExpression:
"contains(#lessons.#idOrder, :lessonId) and attribute_exists(#lessons.#lessonId)",
@ -61,8 +64,8 @@ export class DynamoDBLessonRepository implements ILessonRepository {
deleteLesson = async (themeId: string, lessonId: string): Promise<any> => {
const lessonIndex = await this.getLessonOrder(themeId, lessonId);
const deleteLessonCommand = new UpdateItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: themeId }),
TableName: DynamoDBLessonRepository.tableName,
Key: marshall({ pk: DynamoDBLessonRepository.primaryKey, id: themeId }),
UpdateExpression: `REMOVE #lessons.#lessonId, #lessons.#idOrder[${lessonIndex}]`,
ExpressionAttributeNames: {
"#lessons": "lessons",
@ -79,8 +82,8 @@ export class DynamoDBLessonRepository implements ILessonRepository {
): Promise<number> => {
let lessonIndex = -1;
const getIdOrderCommand = new GetItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: themeId }),
TableName: DynamoDBLessonRepository.tableName,
Key: marshall({ pk: DynamoDBLessonRepository.primaryKey, id: themeId }),
ProjectionExpression: "lessons.idOrder",
});

View File

@ -15,12 +15,15 @@ import { IThemeRepository } from "./theme_repository";
const dynamoDB = DynamoDBClientSingleton.getInstance();
export class DynamoDBThemeRepository implements IThemeRepository {
private static tableName = process.env.DYNAMODB_TABLE_NAME;
private static primaryKey = "theme";
relocateTheme = async (oldThemeId: string, theme: DBTheme): Promise<any> => {
const command = new TransactWriteItemsCommand({
TransactItems: [
{
Put: {
TableName: "themes",
TableName: DynamoDBThemeRepository.tableName,
Item: marshall({
...theme,
}),
@ -29,9 +32,9 @@ export class DynamoDBThemeRepository implements IThemeRepository {
},
{
Delete: {
TableName: "themes",
TableName: DynamoDBThemeRepository.tableName,
Key: marshall({
pk: "theme",
pk: DynamoDBThemeRepository.primaryKey,
id: oldThemeId,
}),
ConditionExpression: "attribute_exists(pk)",
@ -45,7 +48,7 @@ export class DynamoDBThemeRepository implements IThemeRepository {
createTheme = async (theme: DBTheme): Promise<any> => {
const command = new PutItemCommand({
TableName: "themes",
TableName: DynamoDBThemeRepository.tableName,
Item: marshall({
...theme,
}),
@ -58,8 +61,8 @@ export class DynamoDBThemeRepository implements IThemeRepository {
theme: Pick<DBTheme, "id" | "explanation" | "image" | "youtubeVideoUrl">
): Promise<any> => {
const updateCommand = new UpdateItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: theme.id }),
TableName: DynamoDBThemeRepository.tableName,
Key: marshall({ pk: DynamoDBThemeRepository.primaryKey, id: theme.id }),
UpdateExpression:
"SET #explanation = :explanation, #image = :image, #youtubeVideoUrl = :youtubeVideoUrl",
ExpressionAttributeNames: {
@ -79,8 +82,8 @@ export class DynamoDBThemeRepository implements IThemeRepository {
deleteTheme = async (themeId: string): Promise<any> => {
const deleteCommand = new DeleteItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: themeId }),
TableName: DynamoDBThemeRepository.tableName,
Key: marshall({ pk: DynamoDBThemeRepository.primaryKey, id: themeId }),
});
return await dynamoDB.send(deleteCommand);
@ -88,8 +91,8 @@ export class DynamoDBThemeRepository implements IThemeRepository {
getTheme = async (themeId: string): Promise<DBTheme> => {
const queryCommand = new GetItemCommand({
TableName: "themes",
Key: marshall({ pk: "theme", id: themeId }),
TableName: DynamoDBThemeRepository.tableName,
Key: marshall({ pk: DynamoDBThemeRepository.primaryKey, id: themeId }),
});
const resItem = (await dynamoDB.send(queryCommand)).Item;
@ -99,7 +102,7 @@ export class DynamoDBThemeRepository implements IThemeRepository {
getThemeIds = async (): Promise<string[]> => {
const queryCommand = new QueryCommand({
TableName: "themes",
TableName: DynamoDBThemeRepository.tableName,
KeyConditionExpression: "#pk = :pk",
ExpressionAttributeNames: {
"#pk": "pk",
@ -119,7 +122,7 @@ export class DynamoDBThemeRepository implements IThemeRepository {
Pick<DBTheme, "id" | "title" | "image" | "lessons" | "createdAt">[]
> => {
const queryCommand = new QueryCommand({
TableName: "themes",
TableName: DynamoDBThemeRepository.tableName,
KeyConditionExpression: "#pk = :pk",
ExpressionAttributeNames: {
"#pk": "pk",
@ -137,7 +140,7 @@ export class DynamoDBThemeRepository implements IThemeRepository {
getThemeId = async (pathName: string): Promise<string> => {
const command = new ScanCommand({
TableName: "themes",
TableName: DynamoDBThemeRepository.tableName,
FilterExpression: "#pathName = :pathName",
ProjectionExpression: "id",
ExpressionAttributeNames: {

View File

@ -8,7 +8,7 @@ export class DynamoDBClientSingleton {
public static getInstance(): DynamoDBClient {
if (!DynamoDBClientSingleton.instance) {
DynamoDBClientSingleton.instance = new DynamoDBClient({
region: "eu-west-2",
region: process.env.DYNAMODB_REGION,
});
}