Add studio migration

This commit is contained in:
Zoe Roux 2025-03-02 22:24:37 +01:00
parent 12faca5fb5
commit 31d95d7fd7
No known key found for this signature in database
10 changed files with 1393 additions and 4 deletions

View File

@ -160,5 +160,5 @@ erDiagram
string name string name
} }
studios ||--|{ studio_translations : has studios ||--|{ studio_translations : has
shows ||--|{ studios : has shows }|--|{ studios : has
``` ```

View File

@ -0,0 +1,38 @@
CREATE TABLE "kyoo"."show_studio_join" (
"show" integer NOT NULL,
"studio" integer NOT NULL,
CONSTRAINT "show_studio_join_show_studio_pk" PRIMARY KEY("show","studio")
);
--> statement-breakpoint
CREATE TABLE "kyoo"."studio_translations" (
"pk" integer NOT NULL,
"language" varchar(255) NOT NULL,
"name" text NOT NULL,
"logo" jsonb,
CONSTRAINT "studio_translations_pk_language_pk" PRIMARY KEY("pk","language")
);
--> statement-breakpoint
CREATE TABLE "kyoo"."studios" (
"pk" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "kyoo"."studios_pk_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
"id" uuid DEFAULT gen_random_uuid() NOT NULL,
"slug" varchar(255) NOT NULL,
"external_id" jsonb DEFAULT '{}'::jsonb NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone NOT NULL,
CONSTRAINT "studios_id_unique" UNIQUE("id"),
CONSTRAINT "studios_slug_unique" UNIQUE("slug")
);
--> statement-breakpoint
ALTER TABLE "kyoo"."entries" ADD COLUMN "updated_at" timestamp with time zone NOT NULL;--> statement-breakpoint
ALTER TABLE "kyoo"."seasons" ADD COLUMN "updated_at" timestamp with time zone NOT NULL;--> statement-breakpoint
ALTER TABLE "kyoo"."shows" ADD COLUMN "updated_at" timestamp with time zone NOT NULL;--> statement-breakpoint
ALTER TABLE "kyoo"."videos" ADD COLUMN "updated_at" timestamp with time zone NOT NULL;--> statement-breakpoint
ALTER TABLE "kyoo"."show_studio_join" ADD CONSTRAINT "show_studio_join_show_shows_pk_fk" FOREIGN KEY ("show") REFERENCES "kyoo"."shows"("pk") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "kyoo"."show_studio_join" ADD CONSTRAINT "show_studio_join_studio_studios_pk_fk" FOREIGN KEY ("studio") REFERENCES "kyoo"."studios"("pk") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "kyoo"."studio_translations" ADD CONSTRAINT "studio_translations_pk_studios_pk_fk" FOREIGN KEY ("pk") REFERENCES "kyoo"."studios"("pk") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "studio_name_trgm" ON "kyoo"."studio_translations" USING gin ("name" gin_trgm_ops);--> statement-breakpoint
CREATE INDEX "entry_kind" ON "kyoo"."entries" USING hash ("kind");--> statement-breakpoint
CREATE INDEX "entry_order" ON "kyoo"."entries" USING btree ("order");--> statement-breakpoint
CREATE INDEX "entry_name_trgm" ON "kyoo"."entry_translations" USING gin ("name" gin_trgm_ops);--> statement-breakpoint
CREATE INDEX "season_name_trgm" ON "kyoo"."season_translations" USING gin ("name" gin_trgm_ops);--> statement-breakpoint
CREATE INDEX "season_nbr" ON "kyoo"."seasons" USING btree ("season_number");

File diff suppressed because it is too large Load Diff

View File

@ -71,6 +71,13 @@
"when": 1740872363604, "when": 1740872363604,
"tag": "0009_collections", "tag": "0009_collections",
"breakpoints": true "breakpoints": true
},
{
"idx": 10,
"version": "7",
"when": 1740950531468,
"tag": "0010_studios",
"breakpoints": true
} }
] ]
} }

View File

@ -2,6 +2,7 @@ import { relations, sql } from "drizzle-orm";
import { import {
check, check,
date, date,
index,
integer, integer,
jsonb, jsonb,
primaryKey, primaryKey,
@ -70,11 +71,17 @@ export const entries = schema.table(
createdAt: timestamp({ withTimezone: true, mode: "string" }) createdAt: timestamp({ withTimezone: true, mode: "string" })
.notNull() .notNull()
.defaultNow(), .defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.notNull()
.$onUpdate(() => sql`now()`),
nextRefresh: timestamp({ withTimezone: true, mode: "string" }).notNull(), nextRefresh: timestamp({ withTimezone: true, mode: "string" }).notNull(),
}, },
(t) => [ (t) => [
unique().on(t.showPk, t.seasonNumber, t.episodeNumber), unique().on(t.showPk, t.seasonNumber, t.episodeNumber),
check("order_positive", sql`${t.order} >= 0`), check("order_positive", sql`${t.order} >= 0`),
index("entry_kind").using("hash", t.kind),
index("entry_order").on(t.order),
], ],
); );
@ -91,7 +98,10 @@ export const entryTranslations = schema.table(
tagline: text(), tagline: text(),
poster: image(), poster: image(),
}, },
(t) => [primaryKey({ columns: [t.pk, t.language] })], (t) => [
primaryKey({ columns: [t.pk, t.language] }),
index("entry_name_trgm").using("gin", sql`${t.name} gin_trgm_ops`),
],
); );
export const entryRelations = relations(entries, ({ one, many }) => ({ export const entryRelations = relations(entries, ({ one, many }) => ({

View File

@ -1,4 +1,5 @@
export * from "./entries"; export * from "./entries";
export * from "./seasons"; export * from "./seasons";
export * from "./shows"; export * from "./shows";
export * from "./studios";
export * from "./videos"; export * from "./videos";

View File

@ -1,4 +1,4 @@
import { relations } from "drizzle-orm"; import { relations, sql } from "drizzle-orm";
import { import {
date, date,
index, index,
@ -45,11 +45,15 @@ export const seasons = schema.table(
createdAt: timestamp({ withTimezone: true, mode: "string" }) createdAt: timestamp({ withTimezone: true, mode: "string" })
.notNull() .notNull()
.defaultNow(), .defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.notNull()
.$onUpdate(() => sql`now()`),
nextRefresh: timestamp({ withTimezone: true, mode: "string" }).notNull(), nextRefresh: timestamp({ withTimezone: true, mode: "string" }).notNull(),
}, },
(t) => [ (t) => [
unique().on(t.showPk, t.seasonNumber), unique().on(t.showPk, t.seasonNumber),
index("show_fk").using("hash", t.showPk), index("show_fk").using("hash", t.showPk),
index("season_nbr").on(t.seasonNumber),
], ],
); );
@ -66,7 +70,10 @@ export const seasonTranslations = schema.table(
thumbnail: image(), thumbnail: image(),
banner: image(), banner: image(),
}, },
(t) => [primaryKey({ columns: [t.pk, t.language] })], (t) => [
primaryKey({ columns: [t.pk, t.language] }),
index("season_name_trgm").using("gin", sql`${t.name} gin_trgm_ops`),
],
); );
export const seasonRelations = relations(seasons, ({ one, many }) => ({ export const seasonRelations = relations(seasons, ({ one, many }) => ({

View File

@ -92,6 +92,9 @@ export const shows = schema.table(
createdAt: timestamp({ withTimezone: true, mode: "string" }) createdAt: timestamp({ withTimezone: true, mode: "string" })
.notNull() .notNull()
.defaultNow(), .defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.notNull()
.$onUpdate(() => sql`now()`),
nextRefresh: timestamp({ withTimezone: true, mode: "string" }).notNull(), nextRefresh: timestamp({ withTimezone: true, mode: "string" }).notNull(),
}, },
(t) => [ (t) => [

View File

@ -0,0 +1,55 @@
import { sql } from "drizzle-orm";
import {
index,
integer,
primaryKey,
text,
timestamp,
uuid,
varchar,
} from "drizzle-orm/pg-core";
import { externalid, shows } from "./shows";
import { image, language, schema } from "./utils";
export const studios = schema.table("studios", {
pk: integer().primaryKey().generatedAlwaysAsIdentity(),
id: uuid().notNull().unique().defaultRandom(),
slug: varchar({ length: 255 }).notNull().unique(),
externalId: externalid(),
createdAt: timestamp({ withTimezone: true, mode: "string" })
.notNull()
.defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.notNull()
.$onUpdate(() => sql`now()`),
});
export const studio_translations = schema.table(
"studio_translations",
{
pk: integer()
.notNull()
.references(() => studios.pk, { onDelete: "cascade" }),
language: language().notNull(),
name: text().notNull(),
logo: image(),
},
(t) => [
primaryKey({ columns: [t.pk, t.language] }),
index("studio_name_trgm").using("gin", sql`${t.name} gin_trgm_ops`),
],
);
export const showStudioJoin = schema.table(
"show_studio_join",
{
show: integer()
.notNull()
.references(() => shows.pk, { onDelete: "cascade" }),
studio: integer()
.notNull()
.references(() => studios.pk, { onDelete: "cascade" }),
},
(t) => [primaryKey({ columns: [t.show, t.studio] })],
);

View File

@ -26,6 +26,9 @@ export const videos = schema.table(
createdAt: timestamp({ withTimezone: true, mode: "string" }) createdAt: timestamp({ withTimezone: true, mode: "string" })
.notNull() .notNull()
.defaultNow(), .defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.notNull()
.$onUpdate(() => sql`now()`),
}, },
(t) => [ (t) => [
check("part_pos", sql`${t.part} >= 0`), check("part_pos", sql`${t.part} >= 0`),