diff --git a/api/src/controllers/seed/index.ts b/api/src/controllers/seed/index.ts index 699450ac..776dc4f1 100644 --- a/api/src/controllers/seed/index.ts +++ b/api/src/controllers/seed/index.ts @@ -1,11 +1,12 @@ import Elysia, { t } from "elysia"; import { Movie, SeedMovie } from "~/models/movie"; -import { seedMovie } from "./movies"; +import { seedMovie, SeedMovieResponse } from "./movies"; export const seed = new Elysia() .model({ movie: Movie, "seed-movie": SeedMovie, + "seed-movie-response": SeedMovieResponse, error: t.String(), }) .post( @@ -15,7 +16,7 @@ export const seed = new Elysia() }, { body: "seed-movie", - response: { 200: "movie", 400: "error" }, + response: { 200: "seed-movie-response", 400: "error" }, tags: ["movies"], }, ); diff --git a/api/src/controllers/seed/movies.ts b/api/src/controllers/seed/movies.ts index 25ab4900..d35bc661 100644 --- a/api/src/controllers/seed/movies.ts +++ b/api/src/controllers/seed/movies.ts @@ -10,13 +10,23 @@ import { import type { SeedMovie } from "~/models/movie"; import { processOptImage } from "./images"; import { guessNextRefresh } from "./refresh"; -import { count, eq, inArray, sql } from "drizzle-orm"; +import { inArray, sql } from "drizzle-orm"; +import { t } from "elysia"; +import { Resource } from "~/models/utils"; type Show = typeof shows.$inferInsert; type ShowTrans = typeof showTranslations.$inferInsert; type Entry = typeof entries.$inferInsert; -export const seedMovie = async (seed: SeedMovie) => { +export const SeedMovieResponse = t.Intersect([ + Resource, + t.Object({ videos: t.Array(Resource) }), +]); +export type SeedMovieResponse = typeof SeedMovieResponse.static; + +export const seedMovie = async ( + seed: SeedMovie, +): Promise => { const { translations, videos: vids, ...bMovie } = seed; const ret = await db.transaction(async (tx) => { @@ -29,7 +39,7 @@ export const seedMovie = async (seed: SeedMovie) => { const [ret] = await tx .insert(shows) .values(movie) - .returning({ pk: shows.pk, id: shows.id }); + .returning({ pk: shows.pk, id: shows.id, slug: shows.slug }); // even if never shown to the user, a movie still has an entry. const movieEntry: Entry = { type: "movie", ...bMovie }; @@ -58,54 +68,37 @@ export const seedMovie = async (seed: SeedMovie) => { return { ...ret, entry: entry.pk }; }); + let retVideos: { id: string; slug: string }[] = []; if (vids) { - await db.transaction(async (tx) => { - const pks = await tx + retVideos = await db.transaction(async (tx) => { + return await tx .insert(entryVideoJointure) .select( tx .select({ entry: sql`${ret.entry}`.as("entry"), video: videos.pk, + // TODO: do not add rendering if all videos of the entry have the same rendering + slug: sql` + concat( + ${entries.slug}, + case when ${videos.part} <> null then concat("-p", ${videos.part}) else "" end, + case when ${videos.version} <> 1 then concat("-v", ${videos.version}) else "" end, + "-", ${videos.rendering} + ) + `.as("slug"), }) .from(videos) .where(inArray(videos.id, vids)), ) .onConflictDoNothing() - .returning({ pk: entryVideoJointure.video }); - - - const toto = tx - .select({ count: count(videos.rendering) }) - .from(videos) - .innerJoin( - entryVideoJointure, - eq(videos.pk, entryVideoJointure.video), - ) - .where(entryVideoJointure.entry, ""); - - return await tx - .update(videos) - .set({ - slug: sql` - concat( - ${entries.slug}, - case when ${videos.part} <> null then concat("-p", ${videos.part}) else "" end, - case when ${videos.version} <> 1 then concat("-v", ${videos.version}) else "" end, - ${} - ) - `, - }) - .from(entries) - .where( - inArray( - videos.pk, - pks.map((x) => x.pk), - ), - ) - .returning({ id: videos.id, slug: videos.slug }); + .returning({ id: videos.id, slug: entryVideoJointure.slug }); }); } - return ret.id; + return { + id: ret.id, + slug: ret.slug, + videos: retVideos, + }; }; diff --git a/api/src/db/schema/videos.ts b/api/src/db/schema/videos.ts index 07f129f6..dde8959a 100644 --- a/api/src/db/schema/videos.ts +++ b/api/src/db/schema/videos.ts @@ -1,4 +1,4 @@ -import { relations, sql } from "drizzle-orm"; +import { sql } from "drizzle-orm"; import { check, integer, @@ -17,7 +17,6 @@ export const videos = schema.table( { pk: integer().primaryKey().generatedAlwaysAsIdentity(), id: uuid().notNull().unique().defaultRandom(), - slug: varchar({ length: 255 }).unique(), path: text().notNull().unique(), rendering: text().notNull(), part: integer(), @@ -43,6 +42,7 @@ export const entryVideoJointure = schema.table( video: integer() .notNull() .references(() => videos.pk, { onDelete: "cascade" }), + slug: varchar({ length: 255 }).notNull().unique(), }, (t) => [primaryKey({ columns: [t.entry, t.video] })], );