From 2d1a6d8ab02016f644e3029be10b3036a6edfb03 Mon Sep 17 00:00:00 2001 From: Namekuji Date: Mon, 14 Aug 2023 03:46:21 -0400 Subject: [PATCH] fix: proper cql --- packages/backend/src/db/cql.ts | 8 +-- packages/backend/src/services/note/delete.ts | 67 ++++++++++++-------- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/packages/backend/src/db/cql.ts b/packages/backend/src/db/cql.ts index c2c7207f63..62772c6ea5 100644 --- a/packages/backend/src/db/cql.ts +++ b/packages/backend/src/db/cql.ts @@ -49,9 +49,9 @@ export const scyllaQueries = { byIds: `SELECT * FROM note_by_id WHERE "id" IN ?`, byUserId: `SELECT * FROM note_by_user_id WHERE "userId" = ?`, byRenoteId: `SELECT * FROM note_by_renote_id WHERE "renoteId" = ?`, - byReplyId: `SELECT * FROM note WHERE "replyId" = ?` + byReplyId: `SELECT * FROM note WHERE "replyId" = ?`, }, - delete: `DELETE FROM note WHERE ("createdAtDate", "createdAt", "userId", "userHost", "visibility") IN ?`, + delete: `DELETE FROM note WHERE "createdAtDate" = ? AND "createdAt" = ? AND "userId" = ? AND "userHost" = ? AND "visibility" = ?`, update: { renoteCount: `UPDATE note SET "renoteCount" = ?, @@ -114,7 +114,7 @@ export const scyllaQueries = { byUserAndDate: `SELECT * FROM home_timeline WHERE "feedUserId" = ? AND "createdAtDate" = ?`, byId: `SELECT * FROM home_timeline WHERE "id" = ?`, }, - delete: `DELETE FROM home_timeline WHERE ("feedUserId", "createdAtDate", "createdAt", "userId") IN ?`, + delete: `DELETE FROM home_timeline WHERE "feedUserId" = ? AND "createdAtDate" = ? AND "createdAt" = ? AND "userId" = ?`, update: { renoteCount: `UPDATE home_timeline SET "renoteCount" = ?, @@ -128,7 +128,7 @@ export const scyllaQueries = { "reactions" = ?, "score" = ? WHERE "feedUserId" = ? AND "createdAtDate" = ? AND "createdAt" = ? AND "userId" = ? IF EXISTS`, - } + }, }, localTimeline: { select: { diff --git a/packages/backend/src/services/note/delete.ts b/packages/backend/src/services/note/delete.ts index d0c6955ff4..536da423f2 100644 --- a/packages/backend/src/services/note/delete.ts +++ b/packages/backend/src/services/note/delete.ts @@ -1,4 +1,4 @@ -import { Brackets, In } from "typeorm"; +import { Brackets, In, IsNull } from "typeorm"; import { publishNoteStream } from "@/services/stream.js"; import renderDelete from "@/remote/activitypub/renderer/delete.js"; import renderAnnounce from "@/remote/activitypub/renderer/announce.js"; @@ -227,33 +227,46 @@ export default async function ( if (scyllaClient) { const notesToDelete = [note, ...cascadingNotes]; - const noteDeleteParams = notesToDelete.map((n) => { - const date = new Date(n.createdAt.getTime()); - return [date, date, n.userId, n.userHost ?? "local", n.visibility]; - }); - await scyllaClient.execute(prepared.note.delete, noteDeleteParams, { - prepare: true, - }); - - const noteUserIds = new Set(notesToDelete.map((n) => n.userId)); - const meAndFollowers: string[] = [note.userId]; - for (const id of noteUserIds) { - const list = await LocalFollowersCache.init(id).then((cache) => - cache.getAll(), - ); - meAndFollowers.push(...list); + // Delete from note table + const noteDeleteParams = notesToDelete.map( + (n) => + [ + n.createdAt, + n.createdAt, + n.userId, + n.userHost ?? "local", + n.visibility, + ] as [Date, Date, string, string, string], + ); + for (const param of noteDeleteParams) { + scyllaClient.execute(prepared.note.delete, param, { + prepare: true, + }); + } + + // Delete from home timelines + const localUserIds = await Users.find({ + select: ["id"], + where: { + host: IsNull(), + }, + }).then((users) => users.map(({ id }) => id)); // TODO: cache? + const homeDeleteParams = localUserIds.flatMap((feedUserId) => + notesToDelete.map( + (n) => + [feedUserId, n.createdAt, n.createdAt, n.userId] as [ + string, + Date, + Date, + string, + ], + ), + ); + for (const param of homeDeleteParams) { + scyllaClient.execute(prepared.homeTimeline.delete, param, { + prepare: true, + }); } - const feedUserIds = new Set(meAndFollowers); - const homeDeleteParams = notesToDelete.map((n) => { - const tuples: [string, Date, Date, string][] = []; - for (const feedUserId of feedUserIds) { - tuples.push([feedUserId, n.createdAt, n.createdAt, n.userId]); - } - return tuples; - }); - await scyllaClient.execute(prepared.homeTimeline.delete, homeDeleteParams, { - prepare: true, - }); } else { await Notes.delete({ id: note.id,