mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-11-01 19:17:16 -04:00
125 lines
2.8 KiB
TypeScript
125 lines
2.8 KiB
TypeScript
import { relations, sql } from "drizzle-orm";
|
|
import {
|
|
check,
|
|
date,
|
|
index,
|
|
integer,
|
|
jsonb,
|
|
primaryKey,
|
|
real,
|
|
text,
|
|
timestamp,
|
|
unique,
|
|
uuid,
|
|
varchar,
|
|
} from "drizzle-orm/pg-core";
|
|
import { shows } from "./shows";
|
|
import { image, language, schema } from "./utils";
|
|
import { entryVideoJoin } from "./videos";
|
|
|
|
export const entryType = schema.enum("entry_type", [
|
|
"unknown",
|
|
"episode",
|
|
"movie",
|
|
"special",
|
|
"extra",
|
|
]);
|
|
|
|
export const entry_extid = () =>
|
|
jsonb()
|
|
.$type<
|
|
Record<
|
|
string,
|
|
| {
|
|
// used for movies
|
|
dataId: string;
|
|
link: string | null;
|
|
}
|
|
| {
|
|
// used for episodes, specials & extra
|
|
serieId: string;
|
|
season: number | null;
|
|
episode: number;
|
|
link: string | null;
|
|
}
|
|
>
|
|
>()
|
|
.notNull()
|
|
.default({});
|
|
|
|
export const entries = schema.table(
|
|
"entries",
|
|
{
|
|
pk: integer().primaryKey().generatedAlwaysAsIdentity(),
|
|
id: uuid().notNull().unique().defaultRandom(),
|
|
slug: varchar({ length: 255 }).notNull().unique(),
|
|
showPk: integer()
|
|
.notNull()
|
|
.references(() => shows.pk, { onDelete: "cascade" }),
|
|
order: real(),
|
|
seasonNumber: integer(),
|
|
episodeNumber: integer(),
|
|
kind: entryType().notNull(),
|
|
// only when kind=extra
|
|
extraKind: text(),
|
|
airDate: date(),
|
|
runtime: integer(),
|
|
thumbnail: image(),
|
|
|
|
externalId: entry_extid(),
|
|
|
|
createdAt: timestamp({ withTimezone: true, mode: "string" })
|
|
.notNull()
|
|
.defaultNow(),
|
|
updatedAt: timestamp({ withTimezone: true, mode: "string" })
|
|
.notNull()
|
|
.$onUpdate(() => sql`now()`),
|
|
availableSince: timestamp({ withTimezone: true, mode: "string" }),
|
|
nextRefresh: timestamp({ withTimezone: true, mode: "string" }).notNull(),
|
|
},
|
|
(t) => [
|
|
unique().on(t.showPk, t.seasonNumber, t.episodeNumber),
|
|
check("order_positive", sql`${t.order} >= 0`),
|
|
|
|
index("entry_kind").using("hash", t.kind),
|
|
index("entry_order").on(t.order),
|
|
],
|
|
);
|
|
|
|
export const entryTranslations = schema.table(
|
|
"entry_translations",
|
|
{
|
|
pk: integer()
|
|
.notNull()
|
|
.references(() => entries.pk, { onDelete: "cascade" }),
|
|
language: language().notNull(),
|
|
name: text(),
|
|
description: text(),
|
|
// those two are only used if kind === "movie"
|
|
tagline: text(),
|
|
poster: image(),
|
|
},
|
|
(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 }) => ({
|
|
translations: many(entryTranslations, { relationName: "entry_translations" }),
|
|
evj: many(entryVideoJoin, { relationName: "evj_entry" }),
|
|
show: one(shows, {
|
|
relationName: "show_entries",
|
|
fields: [entries.showPk],
|
|
references: [shows.pk],
|
|
}),
|
|
}));
|
|
|
|
export const entryTrRelations = relations(entryTranslations, ({ one }) => ({
|
|
entry: one(entries, {
|
|
relationName: "entry_translations",
|
|
fields: [entryTranslations.pk],
|
|
references: [entries.pk],
|
|
}),
|
|
}));
|