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 messages = after
|
||||
const rows = after
|
||||
? await sql`
|
||||
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,
|
||||
u.display_name as author_name, u.authentik_id as author_id,
|
||||
COALESCE(r.reactions, '[]'::jsonb) as reactions
|
||||
u.display_name as author_name, u.authentik_id as author_id
|
||||
FROM messages m
|
||||
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}
|
||||
ORDER BY m.created_at ASC
|
||||
LIMIT ${limit}
|
||||
|
|
@ -49,29 +33,42 @@ export const GET: RequestHandler = async ({ params, url, locals }) => {
|
|||
: await sql`
|
||||
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,
|
||||
u.display_name as author_name, u.authentik_id as author_id,
|
||||
COALESCE(r.reactions, '[]'::jsonb) as reactions
|
||||
u.display_name as author_name, u.authentik_id as author_id
|
||||
FROM messages m
|
||||
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}
|
||||
ORDER BY m.created_at DESC
|
||||
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);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue