refactor: parameterize duplicated getAffected*Ids query helpers

Four structurally identical functions collapsed into two parameterized
helpers while preserving the existing public API.
This commit is contained in:
2026-03-28 10:31:06 -07:00
parent 17e715b2bf
commit c6d349886e

View File

@@ -89,72 +89,61 @@ export function findSharedCoverBlobHash(
return null; return null;
} }
export function getAffectedWordIdsForSessions(db: DatabaseSync, sessionIds: number[]): number[] { type LexicalEntity = 'word' | 'kanji';
if (sessionIds.length === 0) {
return [];
}
function getAffectedIdsForSessions(
db: DatabaseSync,
entity: LexicalEntity,
sessionIds: number[],
): number[] {
if (sessionIds.length === 0) return [];
const table = entity === 'word' ? 'imm_word_line_occurrences' : 'imm_kanji_line_occurrences';
const col = `${entity}_id`;
return ( return (
db db
.prepare( .prepare(
` `SELECT DISTINCT o.${col} AS id
SELECT DISTINCT o.word_id AS wordId FROM ${table} o
FROM imm_word_line_occurrences o
JOIN imm_subtitle_lines sl ON sl.line_id = o.line_id JOIN imm_subtitle_lines sl ON sl.line_id = o.line_id
WHERE sl.session_id IN (${makePlaceholders(sessionIds)}) WHERE sl.session_id IN (${makePlaceholders(sessionIds)})`,
`,
) )
.all(...sessionIds) as Array<{ wordId: number }> .all(...sessionIds) as Array<{ id: number }>
).map((row) => row.wordId); ).map((row) => row.id);
}
function getAffectedIdsForVideo(
db: DatabaseSync,
entity: LexicalEntity,
videoId: number,
): number[] {
const table = entity === 'word' ? 'imm_word_line_occurrences' : 'imm_kanji_line_occurrences';
const col = `${entity}_id`;
return (
db
.prepare(
`SELECT DISTINCT o.${col} AS id
FROM ${table} o
JOIN imm_subtitle_lines sl ON sl.line_id = o.line_id
WHERE sl.video_id = ?`,
)
.all(videoId) as Array<{ id: number }>
).map((row) => row.id);
}
export function getAffectedWordIdsForSessions(db: DatabaseSync, sessionIds: number[]): number[] {
return getAffectedIdsForSessions(db, 'word', sessionIds);
} }
export function getAffectedKanjiIdsForSessions(db: DatabaseSync, sessionIds: number[]): number[] { export function getAffectedKanjiIdsForSessions(db: DatabaseSync, sessionIds: number[]): number[] {
if (sessionIds.length === 0) { return getAffectedIdsForSessions(db, 'kanji', sessionIds);
return [];
}
return (
db
.prepare(
`
SELECT DISTINCT o.kanji_id AS kanjiId
FROM imm_kanji_line_occurrences o
JOIN imm_subtitle_lines sl ON sl.line_id = o.line_id
WHERE sl.session_id IN (${makePlaceholders(sessionIds)})
`,
)
.all(...sessionIds) as Array<{ kanjiId: number }>
).map((row) => row.kanjiId);
} }
export function getAffectedWordIdsForVideo(db: DatabaseSync, videoId: number): number[] { export function getAffectedWordIdsForVideo(db: DatabaseSync, videoId: number): number[] {
return ( return getAffectedIdsForVideo(db, 'word', videoId);
db
.prepare(
`
SELECT DISTINCT o.word_id AS wordId
FROM imm_word_line_occurrences o
JOIN imm_subtitle_lines sl ON sl.line_id = o.line_id
WHERE sl.video_id = ?
`,
)
.all(videoId) as Array<{ wordId: number }>
).map((row) => row.wordId);
} }
export function getAffectedKanjiIdsForVideo(db: DatabaseSync, videoId: number): number[] { export function getAffectedKanjiIdsForVideo(db: DatabaseSync, videoId: number): number[] {
return ( return getAffectedIdsForVideo(db, 'kanji', videoId);
db
.prepare(
`
SELECT DISTINCT o.kanji_id AS kanjiId
FROM imm_kanji_line_occurrences o
JOIN imm_subtitle_lines sl ON sl.line_id = o.line_id
WHERE sl.video_id = ?
`,
)
.all(videoId) as Array<{ kanjiId: number }>
).map((row) => row.kanjiId);
} }
function refreshWordAggregates(db: DatabaseSync, wordIds: number[]): void { function refreshWordAggregates(db: DatabaseSync, wordIds: number[]): void {