Use the same subquery (videos/progress) for entries & firstEntry

This commit is contained in:
Zoe Roux 2025-03-12 09:49:58 +01:00
parent be35a4f0d9
commit 1943eca52b
No known key found for this signature in database
2 changed files with 40 additions and 66 deletions

View File

@ -106,6 +106,37 @@ const newsSort: Sort = {
}, },
], ],
}; };
const { guess, createdAt, updatedAt, ...videosCol } = getColumns(videos);
export const entryVideosQ = db
.select({
videos: coalesce(
jsonbAgg(
jsonbBuildObject<EmbeddedVideo>({
slug: entryVideoJoin.slug,
...videosCol,
}),
),
sql`'[]'::jsonb`,
).as("videos"),
})
.from(entryVideoJoin)
.where(eq(entryVideoJoin.entryPk, entries.pk))
.leftJoin(videos, eq(videos.pk, entryVideoJoin.videoPk))
.as("videos");
export const getEntryProgressQ = (userId: number) =>
db
.selectDistinctOn([history.entryPk], {
percent: history.percent,
time: history.time,
entryPk: history.entryPk,
videoId: videos.id,
})
.from(history)
.where(eq(history.profilePk, userId))
.leftJoin(videos, eq(history.videoPk, videos.pk))
.orderBy(history.entryPk, desc(history.playedDate))
.as("progress");
async function getEntries({ async function getEntries({
after, after,
@ -134,36 +165,7 @@ async function getEntries({
.as("t"); .as("t");
const { pk, name, ...transCol } = getColumns(transQ); const { pk, name, ...transCol } = getColumns(transQ);
const { guess, createdAt, updatedAt, ...videosCol } = getColumns(videos); const entryProgressQ = getEntryProgressQ(userId);
const videosQ = db
.select({
videos: coalesce(
jsonbAgg(
jsonbBuildObject<EmbeddedVideo>({
slug: entryVideoJoin.slug,
...videosCol,
}),
),
sql`'[]'::jsonb`,
).as("videos"),
})
.from(entryVideoJoin)
.where(eq(entryVideoJoin.entryPk, entries.pk))
.leftJoin(videos, eq(videos.pk, entryVideoJoin.videoPk))
.as("videos");
const progressQ = db
.selectDistinctOn([history.entryPk], {
percent: history.percent,
time: history.time,
entryPk: history.entryPk,
videoId: videos.id,
})
.from(history)
.where(eq(history.profilePk, userId))
.leftJoin(videos, eq(history.videoPk, videos.pk))
.orderBy(history.entryPk, desc(history.playedDate))
.as("progress");
const { const {
kind, kind,
@ -178,8 +180,8 @@ async function getEntries({
.select({ .select({
...entryCol, ...entryCol,
...transCol, ...transCol,
videos: videosQ.videos, videos: entryVideosQ.videos,
progress: getColumns(progressQ), progress: getColumns(entryProgressQ),
// specials don't have an `episodeNumber` but a `number` field. // specials don't have an `episodeNumber` but a `number` field.
number: episodeNumber, number: episodeNumber,
@ -197,8 +199,8 @@ async function getEntries({
}) })
.from(entries) .from(entries)
.innerJoin(transQ, eq(entries.pk, transQ.pk)) .innerJoin(transQ, eq(entries.pk, transQ.pk))
.leftJoinLateral(videosQ, sql`true`) .leftJoinLateral(entryVideosQ, sql`true`)
.leftJoin(progressQ, eq(entries.pk, progressQ.entryPk)) .leftJoin(entryProgressQ, eq(entries.pk, entryProgressQ.entryPk))
.where( .where(
and( and(
filter, filter,

View File

@ -35,6 +35,7 @@ import {
sortToSql, sortToSql,
} from "~/models/utils"; } from "~/models/utils";
import type { EmbeddedVideo } from "~/models/video"; import type { EmbeddedVideo } from "~/models/video";
import { entryVideosQ, getEntryProgressQ } from "../entries";
export const showFilters: FilterDef = { export const showFilters: FilterDef = {
genres: { genres: {
@ -160,36 +161,7 @@ const showRelations = {
.as("t"); .as("t");
const { pk, ...transCol } = getColumns(transQ); const { pk, ...transCol } = getColumns(transQ);
const { guess, createdAt, updatedAt, ...videosCol } = getColumns(videos); const progressQ = getEntryProgressQ(userId);
const videosQ = db
.select({
videos: coalesce(
jsonbAgg(
jsonbBuildObject<EmbeddedVideo>({
slug: entryVideoJoin.slug,
...videosCol,
}),
),
sql`'[]'::jsonb`,
).as("videos"),
})
.from(entryVideoJoin)
.where(eq(entryVideoJoin.entryPk, entries.pk))
.leftJoin(videos, eq(videos.pk, entryVideoJoin.videoPk))
.as("videos");
const progressQ = db
.selectDistinctOn([history.entryPk], {
percent: history.percent,
time: history.time,
entryPk: history.entryPk,
videoId: videos.id,
})
.from(history)
.where(eq(history.profilePk, userId))
.leftJoin(videos, eq(history.videoPk, videos.pk))
.orderBy(history.entryPk, desc(history.playedDate))
.as("progress");
return db return db
.select({ .select({
@ -197,14 +169,14 @@ const showRelations = {
...getColumns(entries), ...getColumns(entries),
...transCol, ...transCol,
number: entries.episodeNumber, number: entries.episodeNumber,
videos: videosQ.videos, videos: entryVideosQ.videos,
progress: getColumns(progressQ), progress: getColumns(progressQ),
}).as("firstEntry"), }).as("firstEntry"),
}) })
.from(entries) .from(entries)
.innerJoin(transQ, eq(entries.pk, transQ.pk)) .innerJoin(transQ, eq(entries.pk, transQ.pk))
.leftJoin(progressQ, eq(entries.pk, progressQ.entryPk)) .leftJoin(progressQ, eq(entries.pk, progressQ.entryPk))
.leftJoinLateral(videosQ, sql`true`) .leftJoinLateral(entryVideosQ, sql`true`)
.where(and(eq(entries.showPk, shows.pk), ne(entries.kind, "extra"))) .where(and(eq(entries.showPk, shows.pk), ne(entries.kind, "extra")))
.orderBy(entries.order) .orderBy(entries.order)
.limit(1) .limit(1)