Move video slug to jointure

This commit is contained in:
Zoe Roux 2024-11-25 21:19:58 +01:00
parent 92ee0b2e7f
commit c20aa862a9
No known key found for this signature in database
3 changed files with 36 additions and 42 deletions

View File

@ -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"],
},
);

View File

@ -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<SeedMovieResponse> => {
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<number>`${ret.entry}`.as("entry"),
video: videos.pk,
})
.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({
// TODO: do not add rendering if all videos of the entry have the same rendering
slug: sql<string>`
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(entries)
.where(
inArray(
videos.pk,
pks.map((x) => x.pk),
),
.from(videos)
.where(inArray(videos.id, vids)),
)
.returning({ id: videos.id, slug: videos.slug });
.onConflictDoNothing()
.returning({ id: videos.id, slug: entryVideoJointure.slug });
});
}
return ret.id;
return {
id: ret.id,
slug: ret.slug,
videos: retVideos,
};
};

View File

@ -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] })],
);