Fix: erstatt LATERAL join med separat reaksjons-query
LATERAL subquery med parameteriserte verdier fungerte ikke med postgres-biblioteket. Bruker nå en enklere to-stegs tilnærming: hent meldinger først, deretter reaksjoner i én batch-query. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5bc992272d
commit
e4b0eb77ea
1 changed files with 33 additions and 36 deletions
|
|
@ -19,29 +19,13 @@ export const GET: RequestHandler = async ({ params, url, locals }) => {
|
||||||
|
|
||||||
const currentUserId = locals.user.id;
|
const currentUserId = locals.user.id;
|
||||||
|
|
||||||
const messages = after
|
const rows = after
|
||||||
? await sql`
|
? await sql`
|
||||||
SELECT m.id, m.channel_id, m.body, m.message_type, m.title,
|
SELECT m.id, m.channel_id, m.body, m.message_type, m.title,
|
||||||
m.pinned, m.visibility, m.created_at, m.updated_at, m.reply_to,
|
m.pinned, m.visibility, m.created_at, m.updated_at, m.reply_to,
|
||||||
u.display_name as author_name, u.authentik_id as author_id,
|
u.display_name as author_name, u.authentik_id as author_id
|
||||||
COALESCE(r.reactions, '[]'::jsonb) as reactions
|
|
||||||
FROM messages m
|
FROM messages m
|
||||||
LEFT JOIN users u ON u.authentik_id = m.author_id
|
LEFT JOIN users u ON u.authentik_id = m.author_id
|
||||||
LEFT JOIN LATERAL (
|
|
||||||
SELECT jsonb_agg(jsonb_build_object(
|
|
||||||
'reaction', sub.reaction,
|
|
||||||
'count', sub.cnt,
|
|
||||||
'user_reacted', sub.user_reacted
|
|
||||||
)) as reactions
|
|
||||||
FROM (
|
|
||||||
SELECT mr.reaction,
|
|
||||||
count(*)::int as cnt,
|
|
||||||
bool_or(mr.user_id = ${currentUserId}) as user_reacted
|
|
||||||
FROM message_reactions mr
|
|
||||||
WHERE mr.message_id = m.id
|
|
||||||
GROUP BY mr.reaction
|
|
||||||
) sub
|
|
||||||
) r ON true
|
|
||||||
WHERE m.channel_id = ${channelId} AND m.created_at > ${after}
|
WHERE m.channel_id = ${channelId} AND m.created_at > ${after}
|
||||||
ORDER BY m.created_at ASC
|
ORDER BY m.created_at ASC
|
||||||
LIMIT ${limit}
|
LIMIT ${limit}
|
||||||
|
|
@ -49,29 +33,42 @@ export const GET: RequestHandler = async ({ params, url, locals }) => {
|
||||||
: await sql`
|
: await sql`
|
||||||
SELECT m.id, m.channel_id, m.body, m.message_type, m.title,
|
SELECT m.id, m.channel_id, m.body, m.message_type, m.title,
|
||||||
m.pinned, m.visibility, m.created_at, m.updated_at, m.reply_to,
|
m.pinned, m.visibility, m.created_at, m.updated_at, m.reply_to,
|
||||||
u.display_name as author_name, u.authentik_id as author_id,
|
u.display_name as author_name, u.authentik_id as author_id
|
||||||
COALESCE(r.reactions, '[]'::jsonb) as reactions
|
|
||||||
FROM messages m
|
FROM messages m
|
||||||
LEFT JOIN users u ON u.authentik_id = m.author_id
|
LEFT JOIN users u ON u.authentik_id = m.author_id
|
||||||
LEFT JOIN LATERAL (
|
|
||||||
SELECT jsonb_agg(jsonb_build_object(
|
|
||||||
'reaction', sub.reaction,
|
|
||||||
'count', sub.cnt,
|
|
||||||
'user_reacted', sub.user_reacted
|
|
||||||
)) as reactions
|
|
||||||
FROM (
|
|
||||||
SELECT mr.reaction,
|
|
||||||
count(*)::int as cnt,
|
|
||||||
bool_or(mr.user_id = ${currentUserId}) as user_reacted
|
|
||||||
FROM message_reactions mr
|
|
||||||
WHERE mr.message_id = m.id
|
|
||||||
GROUP BY mr.reaction
|
|
||||||
) sub
|
|
||||||
) r ON true
|
|
||||||
WHERE m.channel_id = ${channelId}
|
WHERE m.channel_id = ${channelId}
|
||||||
ORDER BY m.created_at DESC
|
ORDER BY m.created_at DESC
|
||||||
LIMIT ${limit}
|
LIMIT ${limit}
|
||||||
`.then((rows) => rows.reverse());
|
`.then((r) => r.reverse());
|
||||||
|
|
||||||
|
// Hent reaksjoner for alle meldinger i én query
|
||||||
|
const messageIds = rows.map((r) => r.id as string);
|
||||||
|
let reactionsMap: Record<string, { reaction: string; count: number; user_reacted: boolean }[]> = {};
|
||||||
|
|
||||||
|
if (messageIds.length > 0) {
|
||||||
|
const reactions = await sql`
|
||||||
|
SELECT mr.message_id, mr.reaction,
|
||||||
|
count(*)::int as count,
|
||||||
|
bool_or(mr.user_id = ${currentUserId}) as user_reacted
|
||||||
|
FROM message_reactions mr
|
||||||
|
WHERE mr.message_id = ANY(${messageIds})
|
||||||
|
GROUP BY mr.message_id, mr.reaction
|
||||||
|
`;
|
||||||
|
for (const r of reactions) {
|
||||||
|
const mid = r.message_id as string;
|
||||||
|
if (!reactionsMap[mid]) reactionsMap[mid] = [];
|
||||||
|
reactionsMap[mid].push({
|
||||||
|
reaction: r.reaction as string,
|
||||||
|
count: r.count as number,
|
||||||
|
user_reacted: r.user_reacted as boolean
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = rows.map((m) => ({
|
||||||
|
...m,
|
||||||
|
reactions: reactionsMap[m.id as string] ?? []
|
||||||
|
}));
|
||||||
|
|
||||||
return json(messages);
|
return json(messages);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue