refactor: bulk insert module
This commit is contained in:
@ -169,10 +169,11 @@ Table user_watch_histories {
|
||||
episode episodes [not null]
|
||||
updated_at DateTime [not null]
|
||||
user_id String [not null]
|
||||
episode_id String [not null]
|
||||
episode_number Int [not null]
|
||||
media_id String [not null]
|
||||
|
||||
indexes {
|
||||
(user_id, episode_id) [pk]
|
||||
(user_id, episode_number, media_id) [pk]
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,6 +255,7 @@ Table medias {
|
||||
related_media media_relations [not null]
|
||||
updated_by_id String
|
||||
deleted_by_id String
|
||||
episodes episodes [not null]
|
||||
home_media_banners home_media_banners [not null]
|
||||
saved_to_collections media_collections [not null]
|
||||
|
||||
@ -507,9 +509,7 @@ Table staff {
|
||||
}
|
||||
|
||||
Table episodes {
|
||||
id String [pk]
|
||||
media_id String [not null]
|
||||
episode Int [not null]
|
||||
episode_number Int [not null]
|
||||
mal_url String
|
||||
forum_url String
|
||||
title String [not null]
|
||||
@ -528,12 +528,18 @@ Table episodes {
|
||||
created_by_id String [not null]
|
||||
comments comments [not null]
|
||||
watch_histories user_watch_histories [not null]
|
||||
media medias [not null]
|
||||
media_id String [not null]
|
||||
|
||||
indexes {
|
||||
(media_id, episode_number) [pk]
|
||||
}
|
||||
}
|
||||
|
||||
Table videos {
|
||||
id String [pk]
|
||||
service video_services [not null]
|
||||
Episode episodes [not null]
|
||||
episode episodes [not null]
|
||||
video_code String [not null]
|
||||
short_code String
|
||||
thumbnail_code String
|
||||
@ -541,7 +547,8 @@ Table videos {
|
||||
created_at DateTime [default: `now()`, not null]
|
||||
deleted_at DateTime
|
||||
updated_at DateTime [not null]
|
||||
episode_id String [not null]
|
||||
episode_number Int [not null]
|
||||
media_id String [not null]
|
||||
created_by_id String [not null]
|
||||
video_submission video_submissions
|
||||
}
|
||||
@ -603,7 +610,8 @@ Table comments {
|
||||
updated_at DateTime [not null]
|
||||
deleted_at DateTime
|
||||
user_id String [not null]
|
||||
episode_id String [not null]
|
||||
episode_number Int [not null]
|
||||
media_id String [not null]
|
||||
likes comment_likes [not null]
|
||||
audit_logs comment_audit_logs [not null]
|
||||
reports comment_reports [not null]
|
||||
@ -795,7 +803,7 @@ Ref: user_follows.following_id > users.id
|
||||
|
||||
Ref: user_watch_histories.user_id > users.id
|
||||
|
||||
Ref: user_watch_histories.episode_id > episodes.id
|
||||
Ref: user_watch_histories.(episode_number, media_id) > episodes.(episode_number, media_id)
|
||||
|
||||
Ref: collection_members.collection_id > collections.id
|
||||
|
||||
@ -877,7 +885,9 @@ Ref: voice_actors.(media_id, character_id) > media_characters.(media_id, charact
|
||||
|
||||
Ref: episodes.created_by_id > users.id
|
||||
|
||||
Ref: videos.episode_id > episodes.id
|
||||
Ref: episodes.media_id > medias.id
|
||||
|
||||
Ref: videos.(episode_number, media_id) > episodes.(episode_number, media_id)
|
||||
|
||||
Ref: video_submissions.created_by_id > users.id
|
||||
|
||||
@ -893,7 +903,7 @@ Ref: video_service_submissions.video_service_id - video_services.id
|
||||
|
||||
Ref: comments.user_id > users.id
|
||||
|
||||
Ref: comments.episode_id > episodes.id
|
||||
Ref: comments.(episode_number, media_id) > episodes.(episode_number, media_id)
|
||||
|
||||
Ref: comment_likes.user_id > users.id
|
||||
|
||||
|
||||
@ -1,25 +1,45 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { AppError } from "../../../helpers/error/instances/app";
|
||||
import { prisma } from "../../../utils/databases/prisma/connection";
|
||||
import { generateUUIDv7 } from "../../../helpers/databases/uuidv7";
|
||||
import {AppError} from "../../../helpers/error/instances/app";
|
||||
import {prisma} from "../../../utils/databases/prisma/connection";
|
||||
import {SystemAccountId} from "../../../config/account/system";
|
||||
|
||||
|
||||
export interface BulkInsertEpisodesPayload {
|
||||
media_id: string
|
||||
episode_number: number
|
||||
title: string
|
||||
title_romanji: string
|
||||
title_origin: string
|
||||
aired_at: Date
|
||||
score: number
|
||||
filler: boolean
|
||||
recap: boolean
|
||||
forum_url: string
|
||||
created_by_id: string
|
||||
}
|
||||
|
||||
export const bulkInsertEpisodesRepository = async (
|
||||
payload: Omit<Prisma.EpisodeUncheckedCreateInput, "id">,
|
||||
payload: BulkInsertEpisodesPayload[]
|
||||
) => {
|
||||
try {
|
||||
return await prisma.episode.upsert({
|
||||
await prisma.$transaction(async (tx) => {
|
||||
await Promise.all(
|
||||
payload.map(async (episode) =>
|
||||
await tx.episode.upsert({
|
||||
where: {
|
||||
mediaId_episode: {
|
||||
mediaId: payload.mediaId as string,
|
||||
episode: payload.episode as number,
|
||||
media_id_episode_number: {
|
||||
media_id: episode.media_id,
|
||||
episode_number: episode.episode_number
|
||||
}
|
||||
},
|
||||
},
|
||||
update: payload,
|
||||
update: episode,
|
||||
create: {
|
||||
id: generateUUIDv7(),
|
||||
...payload,
|
||||
},
|
||||
});
|
||||
...episode,
|
||||
created_by_id: SystemAccountId
|
||||
}
|
||||
})
|
||||
)
|
||||
)
|
||||
})
|
||||
} catch (err) {
|
||||
throw new AppError(500, "Failed to bulk insert episodes", err);
|
||||
}
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
import {AppError} from "../../../helpers/error/instances/app";
|
||||
import {prisma} from "../../../utils/databases/prisma/connection";
|
||||
|
||||
export const findMediaWithMalIdRepository = async (malId: number) => {
|
||||
try {
|
||||
return await prisma.media.findUnique({
|
||||
where: {
|
||||
mal_id: malId
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
throw new AppError(500, "Failed to find media with malId", error)
|
||||
}
|
||||
};
|
||||
@ -1,33 +1,35 @@
|
||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
||||
import { MediaEpisodeInfoResponse } from "../../types/mediaEpisodeInfo.type";
|
||||
import { AppError } from "../../../../helpers/error/instances/app";
|
||||
import { SystemAccountId } from "../../../../config/account/system";
|
||||
import { bulkInsertEpisodesRepository } from "../../repositories/bulkInsertEpisodes.repository";
|
||||
import { getEpisodeReferenceAPI } from "../../../../config/apis/jikan/episode.reference";
|
||||
import { selectMediaByMalIdRepository } from "../../../media/repositories/SELECT/selectMediaByMalId.repository";
|
||||
import {MediaEpisodeInfoResponse} from "../../types/mediaEpisodeInfo.type";
|
||||
import {AppError} from "../../../../helpers/error/instances/app";
|
||||
import {SystemAccountId} from "../../../../config/account/system";
|
||||
import {ErrorForwarder} from "../../../../helpers/error/instances/forwarder";
|
||||
import {bulkInsertEpisodesRepository} from "../../repositories/bulkInsertEpisodes.repository";
|
||||
import {getEpisodeReferenceAPI} from "../../../../config/apis/jikan/episode.reference";
|
||||
import {findMediaWithMalIdRepository} from "../../repositories/findMediaWithMalId.repository";
|
||||
|
||||
export const bulkInsertEpisodeService = async (mal_id: number, page: number = 1) => {
|
||||
try {
|
||||
const episodeAPI = getEpisodeReferenceAPI(mal_id);
|
||||
const episodeData: MediaEpisodeInfoResponse = await fetch(
|
||||
`${episodeAPI.baseURL}${episodeAPI.getEpisodeList}?page=${page}`,
|
||||
).then((res) => res.json());
|
||||
).then((res) => res.json()) as MediaEpisodeInfoResponse;
|
||||
|
||||
const mediaData = await selectMediaByMalIdRepository(mal_id);
|
||||
if (!mediaData) throw new AppError(404, `Media with Mal ID ${mal_id} not found in database`);
|
||||
const mediaData = await findMediaWithMalIdRepository(mal_id)
|
||||
if (!mediaData) throw new AppError(404, "Media not found");
|
||||
|
||||
const insertedEpisodeData = [];
|
||||
episodeData.data.forEach(async (episode) => {
|
||||
insertedEpisodeData.push(
|
||||
await bulkInsertEpisodesRepository({
|
||||
mediaId: mediaData.id!,
|
||||
episode: episode.mal_id,
|
||||
name: episode.title,
|
||||
score: episode.score,
|
||||
uploadedBy: SystemAccountId,
|
||||
}),
|
||||
);
|
||||
});
|
||||
const constructedInput = episodeData.data.map(c => ({
|
||||
media_id: mediaData.id,
|
||||
episode_number: c.mal_id,
|
||||
title: c.title,
|
||||
title_romanji: c.title_romanji,
|
||||
title_origin: c.title_japanese,
|
||||
aired_at: c.aired,
|
||||
score: c.score,
|
||||
filler: c.filler,
|
||||
recap: c.recap,
|
||||
forum_url: c.forum_url,
|
||||
created_by_id: SystemAccountId
|
||||
}))
|
||||
const insertedEpisodes = await bulkInsertEpisodesRepository(constructedInput)
|
||||
return episodeData;
|
||||
} catch (err) {
|
||||
ErrorForwarder(err);
|
||||
|
||||
Reference in New Issue
Block a user