diff --git a/api/src/controllers/entries.ts b/api/src/controllers/entries.ts index c18a9787..120cb8b2 100644 --- a/api/src/controllers/entries.ts +++ b/api/src/controllers/entries.ts @@ -9,7 +9,13 @@ import { shows, videos, } from "~/db/schema"; -import { getColumns, sqlarr } from "~/db/utils"; +import { + coalesce, + getColumns, + jsonbAgg, + jsonbBuildObject, + sqlarr, +} from "~/db/utils"; import { Entry, type EntryKind, @@ -107,17 +113,16 @@ async function getEntries({ const { guess, createdAt, updatedAt, ...videosCol } = getColumns(videos); const videosQ = db - .select({ slug: entryVideoJoin.slug, ...videosCol }) + .select({ + videos: coalesce( + jsonbAgg(jsonbBuildObject({ slug: entryVideoJoin.slug, ...videosCol })), + sql`'[]'::jsonb`, + ), + }) .from(entryVideoJoin) .where(eq(entryVideoJoin.entryPk, entries.pk)) .leftJoin(videos, eq(videos.pk, entryVideoJoin.videoPk)) .as("videos"); - const videosJ = db - .select({ - videos: sql`coalesce(json_agg("videos"), '[]'::json)`.as("videos"), - }) - .from(videosQ) - .as("videos_json"); const { kind, @@ -132,7 +137,7 @@ async function getEntries({ .select({ ...entryCol, ...transCol, - videos: videosJ.videos, + videos: videosQ.videos, // specials don't have an `episodeNumber` but a `number` field. number: episodeNumber, @@ -150,7 +155,7 @@ async function getEntries({ }) .from(entries) .innerJoin(transQ, eq(entries.pk, transQ.pk)) - .leftJoinLateral(videosJ, sql`true`) + .leftJoinLateral(videosQ, sql`true`) .where( and( filter, diff --git a/api/src/db/utils.ts b/api/src/db/utils.ts index f2fe23df..59ef88ab 100644 --- a/api/src/db/utils.ts +++ b/api/src/db/utils.ts @@ -94,10 +94,18 @@ export function values(items: Record[]) { }; } +export const coalesce = (val: SQLWrapper, def: SQLWrapper) => { + return sql`coalesce(${val}, ${def})`; +}; + export const jsonbObjectAgg = (key: SQLWrapper, value: SQLWrapper) => { return sql`jsonb_object_agg(${sql.join([key, value], sql.raw(","))})`; }; +export const jsonbAgg = (val: SQLWrapper) => { + return sql`jsonb_agg(${val})`; +}; + export const jsonbBuildObject = (select: Record) => { const query = sql.join( Object.entries(select).flatMap(([k, v]) => {