Simplify getUnreadReactionsAndMarkRead query

This commit is contained in:
trevor-signal
2025-12-05 12:27:07 -05:00
committed by GitHub
parent 465cf7af41
commit c254eab90c
4 changed files with 36 additions and 64 deletions

View File

@@ -488,7 +488,7 @@ export type StoryReadType = Readonly<{
export type ReactionResultType = Pick<
ReactionType,
'targetAuthorAci' | 'targetTimestamp' | 'messageId'
> & { rowid: number };
>;
export type PollVoteReadResultType = {
id: string;

View File

@@ -3504,20 +3504,23 @@ function getUnreadReactionsAndMarkRead(
storyId?: string;
}
): Array<ReactionResultType> {
return db.transaction(() => {
const unreadMessages: Array<ReactionResultType> = db
return db
.prepare(
`
SELECT reactions.rowid, targetAuthorAci, targetTimestamp, messageId
FROM reactions
UPDATE reactions
INDEXED BY reactions_unread
JOIN messages on messages.id IS reactions.messageId
SET unread = 0
WHERE
reactions.conversationId IS $conversationId AND
reactions.unread > 0 AND
messages.received_at <= $readMessageReceivedAt AND
messages.storyId IS $storyId
ORDER BY messageReceivedAt DESC;
conversationId = $conversationId AND
unread >= 1 AND
EXISTS (
SELECT 1
FROM messages
WHERE messages.id = reactions.messageId
AND messages.received_at <= $readMessageReceivedAt
AND messages.storyId IS $storyId
)
RETURNING targetAuthorAci, targetTimestamp, messageId;
`
)
.all({
@@ -3525,25 +3528,6 @@ function getUnreadReactionsAndMarkRead(
readMessageReceivedAt,
storyId: storyId || null,
});
const idsToUpdate = unreadMessages.map(item => item.rowid);
batchMultiVarQuery(
db,
idsToUpdate,
(ids: ReadonlyArray<number>, persistent: boolean): void => {
db.prepare(
`
UPDATE reactions
SET unread = 0
WHERE rowid IN ( ${ids.map(() => '?').join(', ')} );
`,
{ persistent }
).run(ids);
}
);
return unreadMessages;
})();
}
function markReactionAsRead(

View File

@@ -133,7 +133,7 @@ export class MainSQL {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
#onResponse = new Map<number, ResponseEntry<any>>();
#shouldTimeQueries = false;
#shouldLogQueryTime: (queryName: string) => boolean;
#shouldTrackQueryStats = false;
#queryStats?: {
@@ -150,6 +150,11 @@ export class MainSQL {
exitPromises.push(onExit);
}
this.#onExit = Promise.all(exitPromises);
const timeQueryEnvVar = process.env.TIME_QUERIES;
this.#shouldLogQueryTime = (queryName: string) => {
return timeQueryEnvVar === queryName || timeQueryEnvVar === '1';
};
}
public async initialize({
@@ -162,8 +167,6 @@ export class MainSQL {
throw new Error('Already initialized');
}
this.#shouldTimeQueries = Boolean(process.env.TIME_QUERIES);
this.#logger = logger;
this.#onReady = (async () => {
@@ -461,7 +464,7 @@ export class MainSQL {
currentStats.max = Math.max(currentStats.max, duration);
}
if (this.#shouldTimeQueries && !app.isPackaged) {
if (this.#shouldLogQueryTime(method) && !app.isPackaged) {
const twoDecimals = this.#roundDuration(duration);
this.#logger?.info(`MainSQL query: ${method}, duration=${twoDecimals}ms`);
}

View File

@@ -598,17 +598,9 @@ describe('sql/markRead', () => {
});
assert.lengthOf(markedRead, 2, 'two reactions marked read');
// Sorted in descending order
assert.strictEqual(
markedRead[0].messageId,
reaction4.messageId,
'first should be reaction4'
);
assert.strictEqual(
markedRead[1].messageId,
reaction1.messageId,
'second should be reaction1'
assert.sameMembers(
markedRead.map(read => read.messageId),
[reaction4.messageId, reaction1.messageId]
);
const markedRead2 = await getUnreadReactionsAndMarkRead({
@@ -755,16 +747,9 @@ describe('sql/markRead', () => {
assert.lengthOf(markedRead, 2, 'two reactions marked read');
// Sorted in descending order
assert.strictEqual(
markedRead[0].messageId,
reaction4.messageId,
'first should be reaction4'
);
assert.strictEqual(
markedRead[1].messageId,
reaction1.messageId,
'second should be reaction1'
assert.sameMembers(
markedRead.map(read => read.messageId),
[reaction4.messageId, reaction1.messageId]
);
const markedRead2 = await getUnreadReactionsAndMarkRead({