From 8d6121d8b0eb030e162fd2301966c851b5d800d1 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sun, 26 Jan 2025 18:37:49 +0100 Subject: [PATCH] Handle video joint creation with entries --- api/src/controllers/movies.ts | 7 +-- api/src/controllers/seed/insert/entries.ts | 56 +++++++++++++++++++--- api/src/controllers/seed/movies.ts | 48 ++++--------------- api/src/controllers/seed/series.ts | 8 ++++ api/src/db/schema/videos.ts | 2 +- 5 files changed, 69 insertions(+), 52 deletions(-) diff --git a/api/src/controllers/movies.ts b/api/src/controllers/movies.ts index 7c83f5b4..024f9bb0 100644 --- a/api/src/controllers/movies.ts +++ b/api/src/controllers/movies.ts @@ -1,11 +1,6 @@ import { type SQL, and, eq, exists, sql } from "drizzle-orm"; import { Elysia, t } from "elysia"; -import { - entries, - entryVideoJointure as entryVideoJoint, - showTranslations, - shows, -} from "~/db/schema"; +import { entries, entryVideoJoint, showTranslations, shows } from "~/db/schema"; import { getColumns, sqlarr } from "~/db/utils"; import { KError } from "~/models/error"; import { bubble } from "~/models/examples"; diff --git a/api/src/controllers/seed/insert/entries.ts b/api/src/controllers/seed/insert/entries.ts index 914255ec..ad346e81 100644 --- a/api/src/controllers/seed/insert/entries.ts +++ b/api/src/controllers/seed/insert/entries.ts @@ -1,13 +1,16 @@ +import { eq, sql } from "drizzle-orm"; import { db } from "~/db"; -import { entries, entryTranslations } from "~/db/schema"; +import { + entries, + entryTranslations, + entryVideoJoint as entryVideoJoin, + videos, +} from "~/db/schema"; import { conflictUpdateAllExcept } from "~/db/utils"; -import type { Entry, SeedEntry } from "~/models/entry"; +import type { SeedEntry } from "~/models/entry"; import { processOptImage } from "../images"; import { guessNextRefresh } from "../refresh"; -type EntryI = typeof entries.$inferInsert; -type EntryTrans = typeof entryTranslations.$inferInsert; - const generateSlug = (showSlug: string, entry: SeedEntry): string => { switch (entry.kind) { case "episode": @@ -67,5 +70,46 @@ export const insertEntries = async ( return ret; }); - return retEntries; + + const vids = items.flatMap( + (seed, i) => + seed.videos?.map((x) => ({ videoId: x, entryPk: retEntries[i].pk })) ?? + [], + ); + + if (vids.length === 0) + return retEntries.map((x) => ({ id: x.id, slug: x.slug, videos: [] })); + + const hasRenderingQ = db + .select() + .from(entryVideoJoin) + .where(eq(entryVideoJoin.entry, sql`vids.entryPk`)); + + const retVideos = await db + .insert(entryVideoJoin) + .select( + db + .select({ + entry: sql`vids.entryPk`.as("entry"), + video: videos.pk, + slug: sql` + concat( + ${show.slug}::text, + case when ${videos.part} <> null then ('-p' || ${videos.part}) else '' end, + case when ${videos.version} <> 1 then ('-v' || ${videos.version}) else '' end, + case when exists(${hasRenderingQ}) then concat('-', ${videos.rendering}) else '' end + ) + `.as("slug"), + }) + .from(sql`values(${vids}) as vids(videoId, entryPk)`) + .innerJoin(videos, eq(videos.id, sql`vids.videoId`)), + ) + .onConflictDoNothing() + .returning({ slug: entryVideoJoin.slug, entryPk: sql`vids.entryPk` }); + + return retEntries.map((entry) => ({ + id: entry.id, + slug: entry.slug, + videos: retVideos.filter((x) => x.entryPk === entry.pk), + })); }; diff --git a/api/src/controllers/seed/movies.ts b/api/src/controllers/seed/movies.ts index 32e7f700..eeab21f5 100644 --- a/api/src/controllers/seed/movies.ts +++ b/api/src/controllers/seed/movies.ts @@ -1,13 +1,4 @@ -import { inArray, sql } from "drizzle-orm"; import { t } from "elysia"; -import { db } from "~/db"; -import { - type entries, - entryTranslations, - entryVideoJointure as evj, - videos, -} from "~/db/schema"; -import { conflictUpdateAllExcept } from "~/db/utils"; import type { SeedMovie } from "~/models/movie"; import { getYear } from "~/utils"; import { insertEntries } from "./insert/entries"; @@ -40,7 +31,7 @@ export const seedMovie = async ( seed.slug = `random-${getYear(seed.airDate)}`; } - const { translations, videos: vids, ...bMovie } = seed; + const { translations, videos, ...bMovie } = seed; const nextRefresh = guessNextRefresh(bMovie.airDate ?? new Date()); const show = await insertShow( @@ -57,43 +48,22 @@ export const seedMovie = async ( // even if never shown to the user, a movie still has an entry. const [entry] = await insertEntries(show, [ { + ...bMovie, kind: "movie", order: 1, - nextRefresh, - ...bMovie, + thumbnail: (bMovie.originalLanguage + ? translations[bMovie.originalLanguage] + : Object.values(translations)[0] + )?.thumbnail, + translations, + videos, }, ]); - let retVideos: { slug: string }[] = []; - if (vids) { - retVideos = await db - .insert(evj) - .select( - db - .select({ - entry: sql`${show.entry}`.as("entry"), - video: videos.pk, - // TODO: do not add rendering if all videos of the entry have the same rendering - slug: sql` - concat( - ${show.slug}::text, - case when ${videos.part} <> null then concat('-p', ${videos.part}) else '' end, - case when ${videos.version} <> 1 then concat('-v', ${videos.version}) else '' end - ) - `.as("slug"), - // case when (select count(1) from ${evj} where ${evj.entry} = ${ret.entry}) <> 0 then concat('-', ${videos.rendering}) else '' end - }) - .from(videos) - .where(inArray(videos.id, vids)), - ) - .onConflictDoNothing() - .returning({ slug: evj.slug }); - } - return { updated: show.updated, id: show.id, slug: show.slug, - videos: retVideos, + videos: entry.videos, }; }; diff --git a/api/src/controllers/seed/series.ts b/api/src/controllers/seed/series.ts index bd421493..3bf8dd9b 100644 --- a/api/src/controllers/seed/series.ts +++ b/api/src/controllers/seed/series.ts @@ -12,6 +12,14 @@ export const SeedSerieResponse = t.Object({ t.Object({ id: t.String({ format: "uuid" }), slug: t.String({ format: "slug", examples: ["made-in-abyss-s1e1"] }), + videos: t.Array( + t.Object({ + slug: t.String({ + format: "slug", + examples: ["mode-in-abyss-s1e1v2"], + }), + }), + ), }), ), }); diff --git a/api/src/db/schema/videos.ts b/api/src/db/schema/videos.ts index ad8adad9..c233b0bc 100644 --- a/api/src/db/schema/videos.ts +++ b/api/src/db/schema/videos.ts @@ -33,7 +33,7 @@ export const videos = schema.table( ], ); -export const entryVideoJointure = schema.table( +export const entryVideoJoint = schema.table( "entry_video_jointure", { entry: integer()