diff --git a/api/src/controllers/movies.ts b/api/src/controllers/movies.ts index 78155c60..13242ec6 100644 --- a/api/src/controllers/movies.ts +++ b/api/src/controllers/movies.ts @@ -2,34 +2,35 @@ import { Elysia, t } from "elysia"; import { Movie } from "../models/movie"; import { db } from "../db"; import { shows, showTranslations } from "../db/schema/shows"; -import { eq, and, sql, or, inArray, getTableColumns } from "drizzle-orm"; +import { eq, and, sql, or, inArray } from "drizzle-orm"; +import { getColumns } from "../db/schema/utils"; + +const translations = db + .selectDistinctOn([showTranslations.language]) + .from(showTranslations) + .where( + or( + inArray(showTranslations.language, sql.placeholder("langs")), + eq(showTranslations.language, shows.originalLanguage), + ), + ) + .orderBy( + sql`array_position(${showTranslations.language}, ${sql.placeholder("langs")})`, + ) + .as("t"); + +const { pk: _, kind, startAir, endAir, ...moviesCol } = getColumns(shows); +const { pk, language, ...translationsCol } = getColumns(translations); -const { pk: _, kind, startAir, endAir, ...moviesCol } = getTableColumns(shows); -const { pk, language, ...translationsCol } = getTableColumns(showTranslations); const findMovie = db .select({ ...moviesCol, airDate: startAir, - ...translationsCol, + translations: translationsCol, }) .from(shows) - .innerJoin( - db - .selectDistinctOn([showTranslations.language]) - .from(showTranslations) - .where( - or( - inArray(showTranslations.language, sql.placeholder("langs")), - eq(showTranslations.language, shows.originalLanguage), - ), - ) - .orderBy( - sql`array_position(${showTranslations.language}, ${sql.placeholder("langs")})`, - ) - .as("t"), - eq(shows.pk, showTranslations.pk), - ) + .innerJoin(translations, eq(shows.pk, translations.pk)) .where( and( eq(shows.kind, "movie"), diff --git a/api/src/db/schema/utils.ts b/api/src/db/schema/utils.ts index 02f6e8af..f314ccd3 100644 --- a/api/src/db/schema/utils.ts +++ b/api/src/db/schema/utils.ts @@ -1,4 +1,20 @@ -import { jsonb, pgSchema, varchar } from "drizzle-orm/pg-core"; +import { + is, + type ColumnsSelection, + type Subquery, + Table, + View, + ViewBaseConfig, +} from "drizzle-orm"; +import type { AnyMySqlSelect } from "drizzle-orm/mysql-core"; +import { + type AnyPgSelect, + jsonb, + pgSchema, + varchar, +} from "drizzle-orm/pg-core"; +import type { AnySQLiteSelect } from "drizzle-orm/sqlite-core"; +import type { WithSubquery } from "drizzle-orm/subquery"; export const schema = pgSchema("kyoo"); @@ -20,3 +36,30 @@ export const externalid = () => >() .notNull() .default({}); + +// https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts#L58 +type Simplify = {[KeyType in keyof T]: T[KeyType]} & {}; + +// See https://github.com/drizzle-team/drizzle-orm/pull/1789 +type Select = AnyPgSelect | AnyMySqlSelect | AnySQLiteSelect; +type AnySelect = Simplify & Partial>>; +export function getColumns< + T extends + | Table + | View + | Subquery + | WithSubquery + | AnySelect, +>( + table: T, +): T extends Table + ? T["_"]["columns"] + : T extends View | Subquery | WithSubquery | AnySelect + ? T["_"]["selectedFields"] + : never { + return is(table, Table) + ? (table as any)[(Table as any).Symbol.Columns] + : is(table, View) + ? (table as any)[ViewBaseConfig].selectedFields + : table._.selectedFields; +}