fix filter delete notes out from timeliens

This commit is contained in:
Namekuji 2023-08-12 04:41:59 -04:00
parent 86ccb51fd0
commit 2a05d8ce12
No known key found for this signature in database
GPG key ID: 1D62332C07FBA532
5 changed files with 61 additions and 13 deletions

View file

@ -2,6 +2,7 @@ DROP MATERIALIZED VIEW IF EXISTS reaction_by_id;
DROP MATERIALIZED VIEW IF EXISTS reaction_by_userid; DROP MATERIALIZED VIEW IF EXISTS reaction_by_userid;
DROP INDEX IF EXISTS reaction_by_id; DROP INDEX IF EXISTS reaction_by_id;
DROP TABLE IF EXISTS reaction; DROP TABLE IF EXISTS reaction;
DROP TABLE IF EXISTS deleted_note;
DROP TABLE IF EXISTS home_timeline; DROP TABLE IF EXISTS home_timeline;
DROP MATERIALIZED VIEW IF EXISTS local_timeline; DROP MATERIALIZED VIEW IF EXISTS local_timeline;
DROP MATERIALIZED VIEW IF EXISTS global_timeline; DROP MATERIALIZED VIEW IF EXISTS global_timeline;

View file

@ -168,9 +168,15 @@ CREATE TABLE IF NOT EXISTS home_timeline (
"reactions" map<text, int>, -- Reactions "reactions" map<text, int>, -- Reactions
"noteEdit" set<frozen<note_edit_history>>, -- Edit History "noteEdit" set<frozen<note_edit_history>>, -- Edit History
"updatedAt" timestamp, "updatedAt" timestamp,
PRIMARY KEY (("feedUserId", "createdAtDate"), "createdAt") PRIMARY KEY (("feedUserId", "createdAtDate"), "createdAt", "userId")
) WITH CLUSTERING ORDER BY ("createdAt" DESC); ) WITH CLUSTERING ORDER BY ("createdAt" DESC);
CREATE TABLE IF NOT EXISTS deleted_note (
"noteId" ascii,
"deletedAt" timestamp,
PRIMARY KEY ("noteId", "deletedAt")
);
CREATE TABLE IF NOT EXISTS reaction ( CREATE TABLE IF NOT EXISTS reaction (
"id" text, "id" text,
"noteId" ascii, "noteId" ascii,

View file

@ -49,7 +49,7 @@ export const scyllaQueries = {
byUserId: `SELECT * FROM note_by_user_id WHERE "userId" IN ?`, byUserId: `SELECT * FROM note_by_user_id WHERE "userId" IN ?`,
byRenoteId: `SELECT * FROM note_by_renote_id WHERE "renoteId" = ?`, byRenoteId: `SELECT * FROM note_by_renote_id WHERE "renoteId" = ?`,
}, },
delete: `DELETE FROM note WHERE "createdAtDate" = ? AND "createdAt" = ? AND "userId" = ?`, delete: `DELETE FROM note WHERE "createdAtDate" = ? AND "createdAt" = ? AND "userId" = ? AND "userHost" = ? AND "visibility" = ?`,
update: { update: {
renoteCount: `UPDATE note SET renoteCount: `UPDATE note SET
"renoteCount" = ?, "renoteCount" = ?,
@ -122,6 +122,10 @@ export const scyllaQueries = {
byDate: `SELECT * FROM global_timeline WHERE "createdAtDate" = ?`, byDate: `SELECT * FROM global_timeline WHERE "createdAtDate" = ?`,
}, },
}, },
deletedNote: {
insert: `INSERT INTO deleted_note ("noteId", "deletedAt") VALUES (?, ?)`,
select: `SELECT "noteId" FROM deleted_note`,
},
reaction: { reaction: {
insert: `INSERT INTO reaction insert: `INSERT INTO reaction
("id", "noteId", "userId", "reaction", "emoji", "createdAt") ("id", "noteId", "userId", "reaction", "emoji", "createdAt")

View file

@ -155,13 +155,30 @@ export function parseScyllaNote(row: types.Row): ScyllaNote {
}; };
} }
export interface DeletedNote {
noteId: string;
deletedAt: string;
}
export function parseDeletedNote(row: types.Row): DeletedNote {
return {
noteId: row.get("noteId"),
deletedAt: row.get("deletedAt"),
};
}
export interface ScyllaNoteReaction extends NoteReaction { export interface ScyllaNoteReaction extends NoteReaction {
emoji: PopulatedEmoji; emoji: PopulatedEmoji;
} }
const QUERY_LIMIT = 1000; // TODO: should this be configurable? const QUERY_LIMIT = 1000; // TODO: should this be configurable?
export type TimelineKind = "home" | "local" | "recommended" | "global" | "renotes"; export type TimelineKind =
| "home"
| "local"
| "recommended"
| "global"
| "renotes";
export function parseScyllaReaction(row: types.Row): ScyllaNoteReaction { export function parseScyllaReaction(row: types.Row): ScyllaNoteReaction {
return { return {
@ -177,16 +194,17 @@ export function parseScyllaReaction(row: types.Row): ScyllaNoteReaction {
export function prepareNoteQuery( export function prepareNoteQuery(
kind: TimelineKind, kind: TimelineKind,
ps: { ps: {
untilId?: string; untilId?: string;
untilDate?: number; untilDate?: number;
sinceId?: string; sinceId?: string;
sinceDate?: number; sinceDate?: number;
}): { query: string; untilDate: Date; sinceDate: Date | null } { },
): { query: string; untilDate: Date; sinceDate: Date | null } {
const queryParts: string[] = []; const queryParts: string[] = [];
switch (kind) { switch (kind) {
case "home": case "home":
queryParts.push(prepared.homeTimeline.select.byUserAndDate) queryParts.push(prepared.homeTimeline.select.byUserAndDate);
break; break;
case "local": case "local":
queryParts.push(prepared.localTimeline.select.byDate); queryParts.push(prepared.localTimeline.select.byDate);
@ -283,7 +301,18 @@ export async function execNotePaginationQuery(
if (result.rowLength > 0) { if (result.rowLength > 0) {
const notes = result.rows.map(parseScyllaNote); const notes = result.rows.map(parseScyllaNote);
foundNotes.push(...(filter ? await filter(notes) : notes)); const candidates = filter ? await filter(notes) : notes;
// foundNotes.push(...(filter ? await filter(notes) : notes));
const deletedNotes = await scyllaClient
.execute(`${prepared.deletedNote.select} WHERE "noteId" IN ?`, [
candidates.map(({ id }) => id),
])
.then((result) =>
result.rows.map((row) => parseDeletedNote(row).noteId),
);
foundNotes.push(
...candidates.filter((note) => !deletedNotes.includes(note.id)),
);
untilDate = notes[notes.length - 1].createdAt; untilDate = notes[notes.length - 1].createdAt;
} }

View file

@ -119,9 +119,17 @@ export default async function (
if (scyllaClient) { if (scyllaClient) {
const date = new Date(note.createdAt.getTime()); const date = new Date(note.createdAt.getTime());
await scyllaClient.execute(prepared.note.delete, [date, date, note.userId], { await scyllaClient.execute(
prepare: true, prepared.note.delete,
}); [date, date, note.userId, note.userHost ?? "local", note.visibility],
{
prepare: true,
},
);
await scyllaClient.execute(prepared.deletedNote.insert, [
note.id,
new Date(),
]);
} }
await Notes.delete({ await Notes.delete({