diff --git a/packages/backend/native-utils/scylla-migration/cql/1689400417034_timeline/down.cql b/packages/backend/native-utils/scylla-migration/cql/1689400417034_timeline/down.cql index 8157108527..3db9222563 100644 --- a/packages/backend/native-utils/scylla-migration/cql/1689400417034_timeline/down.cql +++ b/packages/backend/native-utils/scylla-migration/cql/1689400417034_timeline/down.cql @@ -2,13 +2,13 @@ DROP MATERIALIZED VIEW IF EXISTS reaction_by_id; DROP MATERIALIZED VIEW IF EXISTS reaction_by_userid; DROP INDEX IF EXISTS reaction_by_id; DROP TABLE IF EXISTS reaction; -DROP TABLE IF EXISTS deleted_note; +DROP INDEX IF EXISTS home_by_id; DROP TABLE IF EXISTS home_timeline; DROP MATERIALIZED VIEW IF EXISTS local_timeline; DROP MATERIALIZED VIEW IF EXISTS global_timeline; DROP MATERIALIZED VIEW IF EXISTS note_by_renote_id; DROP MATERIALIZED VIEW IF EXISTS note_by_userid; -DROP MATERIALIZED VIEW IF EXISTS note_by_id; +DROP INDEX IF EXISTS note_by_id; DROP INDEX IF EXISTS note_by_uri; DROP INDEX IF EXISTS note_by_url; DROP TABLE IF EXISTS note; diff --git a/packages/backend/native-utils/scylla-migration/cql/1689400417034_timeline/up.cql b/packages/backend/native-utils/scylla-migration/cql/1689400417034_timeline/up.cql index 2071a26ae8..2e76da4a79 100644 --- a/packages/backend/native-utils/scylla-migration/cql/1689400417034_timeline/up.cql +++ b/packages/backend/native-utils/scylla-migration/cql/1689400417034_timeline/up.cql @@ -74,17 +74,7 @@ CREATE TABLE IF NOT EXISTS note ( -- Store all posts CREATE INDEX IF NOT EXISTS note_by_uri ON note ("uri"); CREATE INDEX IF NOT EXISTS note_by_url ON note ("url"); - -CREATE MATERIALIZED VIEW IF NOT EXISTS note_by_id AS - SELECT * FROM note - WHERE "id" IS NOT NULL - AND "createdAt" IS NOT NULL - AND "createdAtDate" IS NOT NULL - AND "userId" IS NOT NULL - AND "userHost" IS NOT NULL - AND "visibility" IS NOT NULL - PRIMARY KEY ("id", "createdAt", "createdAtDate", "userId", "userHost", "visibility") - WITH CLUSTERING ORDER BY ("createdAt" DESC); +CREATE INDEX IF NOT EXISTS note_by_id ON note ("id"); CREATE MATERIALIZED VIEW IF NOT EXISTS note_by_user_id AS SELECT * FROM note @@ -171,11 +161,7 @@ CREATE TABLE IF NOT EXISTS home_timeline ( PRIMARY KEY (("feedUserId", "createdAtDate"), "createdAt", "userId") ) WITH CLUSTERING ORDER BY ("createdAt" DESC); -CREATE TABLE IF NOT EXISTS deleted_note ( - "noteId" ascii, - "deletedAt" timestamp, - PRIMARY KEY ("noteId", "deletedAt") -); +CREATE INDEX IF NOT EXISTS home_by_id ON home_timeline ("id"); CREATE TABLE IF NOT EXISTS reaction ( "id" text, diff --git a/packages/backend/src/db/cql.ts b/packages/backend/src/db/cql.ts index 4d33ed238d..9c270ce9ac 100644 --- a/packages/backend/src/db/cql.ts +++ b/packages/backend/src/db/cql.ts @@ -45,7 +45,7 @@ export const scyllaQueries = { byDate: `SELECT * FROM note WHERE "createdAtDate" = ?`, byUri: `SELECT * FROM note WHERE "uri" = ?`, byUrl: `SELECT * FROM note WHERE "url" = ?`, - byId: `SELECT * FROM note_by_id WHERE "id" IN ?`, + byId: `SELECT * FROM note WHERE "id" = ?`, byUserId: `SELECT * FROM note_by_user_id WHERE "userId" IN ?`, byRenoteId: `SELECT * FROM note_by_renote_id WHERE "renoteId" = ?`, }, @@ -110,7 +110,9 @@ export const scyllaQueries = { ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, select: { byUserAndDate: `SELECT * FROM home_timeline WHERE "feedUserId" = ? AND "createdAtDate" = ?`, + byId: `SELECT * FROM home_timeline WHERE "id" = ?`, }, + delete: `DELETE FROM home_timeline WHERE "feedUserId" = ? AND "createdAtDate" = ? AND "createdAt" = ? AND "userId" = ?`, }, localTimeline: { select: { @@ -122,10 +124,6 @@ export const scyllaQueries = { byDate: `SELECT * FROM global_timeline WHERE "createdAtDate" = ?`, }, }, - deletedNote: { - insert: `INSERT INTO deleted_note ("noteId", "deletedAt") VALUES (?, ?)`, - select: `SELECT "noteId" FROM deleted_note`, - }, reaction: { insert: `INSERT INTO reaction ("id", "noteId", "userId", "reaction", "emoji", "createdAt") diff --git a/packages/backend/src/db/scylla.ts b/packages/backend/src/db/scylla.ts index 3ee2b181da..49077fe824 100644 --- a/packages/backend/src/db/scylla.ts +++ b/packages/backend/src/db/scylla.ts @@ -155,15 +155,14 @@ export function parseScyllaNote(row: types.Row): ScyllaNote { }; } -export interface DeletedNote { - noteId: string; - deletedAt: string; -} +export function parseHomeTimeline( + row: types.Row, +): { feedUserId: string } & ScyllaNote { + const note = parseScyllaNote(row); -export function parseDeletedNote(row: types.Row): DeletedNote { return { - noteId: row.get("noteId"), - deletedAt: row.get("deletedAt"), + feedUserId: row.get("feedUserId"), + ...note, }; } @@ -301,18 +300,7 @@ export async function execNotePaginationQuery( if (result.rowLength > 0) { const notes = result.rows.map(parseScyllaNote); - 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)), - ); + foundNotes.push(...(filter ? await filter(notes) : notes)); untilDate = notes[notes.length - 1].createdAt; } diff --git a/packages/backend/src/models/repositories/note.ts b/packages/backend/src/models/repositories/note.ts index 0613e80794..1aef1cdef9 100644 --- a/packages/backend/src/models/repositories/note.ts +++ b/packages/backend/src/models/repositories/note.ts @@ -206,7 +206,7 @@ export const NoteRepository = db.getRepository(Note).extend({ if (scyllaClient) { const result = await scyllaClient.execute( prepared.note.select.byId, - [[noteId]], + [noteId], { prepare: true }, ); if (result.rowLength > 0) { diff --git a/packages/backend/src/server/api/common/getters.ts b/packages/backend/src/server/api/common/getters.ts index bf136d2970..2dcd6916a0 100644 --- a/packages/backend/src/server/api/common/getters.ts +++ b/packages/backend/src/server/api/common/getters.ts @@ -23,7 +23,7 @@ export async function getNote( if (scyllaClient) { const result = await scyllaClient.execute( prepared.note.select.byId, - [[noteId]], + [noteId], { prepare: true }, ); if (result.rowLength > 0) { diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 165f82de8b..f51ebdf50a 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -905,7 +905,7 @@ async function insertNote( if (scyllaClient) { const result = await scyllaClient.execute( prepared.note.select.byId, - [[insert.id]], + [insert.id], { prepare: true }, ); if (result.rowLength > 0) { diff --git a/packages/backend/src/services/note/delete.ts b/packages/backend/src/services/note/delete.ts index 543de13312..33b893720f 100644 --- a/packages/backend/src/services/note/delete.ts +++ b/packages/backend/src/services/note/delete.ts @@ -22,7 +22,7 @@ import { countSameRenotes } from "@/misc/count-same-renotes.js"; import { registerOrFetchInstanceDoc } from "../register-or-fetch-instance-doc.js"; import { deliverToRelays } from "../relay.js"; import meilisearch from "@/db/meilisearch.js"; -import { prepared, scyllaClient } from "@/db/scylla.js"; +import { parseHomeTimeline, prepared, scyllaClient } from "@/db/scylla.js"; /** * 投稿を削除します。 @@ -126,10 +126,19 @@ export default async function ( prepare: true, }, ); - await scyllaClient.execute(prepared.deletedNote.insert, [ - note.id, - new Date(), - ]); + + const homeTimelines = await scyllaClient + .execute(prepared.homeTimeline.select.byId, [note.id], { prepare: true }) + .then((result) => result.rows.map(parseHomeTimeline)); + for (const timeline of homeTimelines) { + // No need to wait + scyllaClient.execute(prepared.homeTimeline.delete, [ + timeline.feedUserId, + timeline.createdAtDate, + timeline.createdAt, + timeline.userId, + ]); + } } await Notes.delete({