From 07526ada453b10b329611393329780c1804b82d1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=82=B7=E3=82=A2=E3=83=8E=E3=83=B3?=
 <xianon@hotmail.co.jp>
Date: Sat, 6 Nov 2021 18:57:49 +0900
Subject: [PATCH] =?UTF-8?q?perf:=20delete-account=E5=87=A6=E7=90=86?=
 =?UTF-8?q?=E3=82=92=E8=BB=BD=E3=81=8F=E3=81=99=E3=82=8B=20(#7958)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Revert "#7892"

This reverts commit 71d9c2a53d116a61f4c9b21ff98712a0000412b8.

* アカウント削除処理でノート削除を重複して行なわないようにする

* ドライブファイル削除時に参照しているノートを削除しないようにする

* 不要となったコードを削除する
---
 src/remote/activitypub/kernel/delete/actor.ts |  5 +-
 src/services/drive/delete-file.ts             | 65 +------------------
 2 files changed, 2 insertions(+), 68 deletions(-)

diff --git a/src/remote/activitypub/kernel/delete/actor.ts b/src/remote/activitypub/kernel/delete/actor.ts
index a0eb904565..502f8d5ab5 100644
--- a/src/remote/activitypub/kernel/delete/actor.ts
+++ b/src/remote/activitypub/kernel/delete/actor.ts
@@ -15,7 +15,7 @@ export async function deleteActor(actor: IRemoteUser, uri: string): Promise<stri
 	if (actor.isDeleted) {
 		logger.info(`skip: already deleted`);
 	}
-/*
+
 	const job = await createDeleteAccountJob(actor);
 
 	await Users.update(actor.id, {
@@ -23,7 +23,4 @@ export async function deleteActor(actor: IRemoteUser, uri: string): Promise<stri
 	});
 
 	return `ok: queued ${job.name} ${job.id}`;
-*/
-
-	return `skip: account deletion temporaly disabled`;
 }
diff --git a/src/services/drive/delete-file.ts b/src/services/drive/delete-file.ts
index 2eab17ac1c..2ac11b8295 100644
--- a/src/services/drive/delete-file.ts
+++ b/src/services/drive/delete-file.ts
@@ -1,19 +1,11 @@
 import { DriveFile } from '@/models/entities/drive-file';
 import { InternalStorage } from './internal-storage';
-import { DriveFiles, Instances, Notes, Users } from '@/models/index';
+import { DriveFiles, Instances } from '@/models/index';
 import { driveChart, perUserDriveChart, instanceChart } from '@/services/chart/index';
 import { createDeleteObjectStorageFileJob } from '@/queue/index';
 import { fetchMeta } from '@/misc/fetch-meta';
 import { getS3 } from './s3';
 import { v4 as uuid } from 'uuid';
-import { Note } from '@/models/entities/note';
-import { renderActivity } from '@/remote/activitypub/renderer/index';
-import renderDelete from '@/remote/activitypub/renderer/delete';
-import renderTombstone from '@/remote/activitypub/renderer/tombstone';
-import config from '@/config/index';
-import { deliverToFollowers } from '@/remote/activitypub/deliver-manager';
-import { Brackets } from 'typeorm';
-import { deliverToRelays } from '../relay';
 
 export async function deleteFile(file: DriveFile, isExpired = false) {
 	if (file.storedInternal) {
@@ -87,28 +79,6 @@ async function postProcess(file: DriveFile, isExpired = false) {
 		});
 	} else {
 		DriveFiles.delete(file.id);
-
-		// TODO: トランザクション
-		const relatedNotes = await findRelatedNotes(file.id);
-		for (const relatedNote of relatedNotes) { // for each note with deleted driveFile
-			const cascadingNotes = (await findCascadingNotes(relatedNote)).filter(note => !note.localOnly);
-			for (const cascadingNote of cascadingNotes) { // for each notes subject to cascade deletion
-				if (!cascadingNote.user) continue;
-				if (!Users.isLocalUser(cascadingNote.user)) continue;
-				const content = renderActivity(renderDelete(renderTombstone(`${config.url}/notes/${cascadingNote.id}`), cascadingNote.user));
-				deliverToFollowers(cascadingNote.user, content); // federate delete msg
-				deliverToRelays(cascadingNote.user, content);
-			}
-			if (!relatedNote.user) continue;
-			if (Users.isLocalUser(relatedNote.user)) {
-				const content = renderActivity(renderDelete(renderTombstone(`${config.url}/notes/${relatedNote.id}`), relatedNote.user));
-				deliverToFollowers(relatedNote.user, content);
-				deliverToRelays(relatedNote.user, content);
-			}
-		}
-		Notes.createQueryBuilder().delete()
-			.where(':id = ANY("fileIds")', { id: file.id })
-			.execute();
 	}
 
 	// 統計を更新
@@ -131,36 +101,3 @@ export async function deleteObjectStorageFile(key: string) {
 		Key: key
 	}).promise();
 }
-
-async function findRelatedNotes(fileId: string) {
-	// NOTE: When running raw query, TypeORM converts field name to lowercase. Wrap in quotes to prevent conversion.
-	const relatedNotes = await Notes.createQueryBuilder('note').where(':id = ANY("fileIds")', { id: fileId }).getMany();
-	for (const relatedNote of relatedNotes) {
-		const user = await Users.findOne({ id: relatedNote.userId });
-		if (user)
-			relatedNote.user = user;
-	}
-	return relatedNotes;
-}
-
-async function findCascadingNotes(note: Note) {
-	const cascadingNotes: Note[] = [];
-
-	const recursive = async (noteId: string) => {
-		const query = Notes.createQueryBuilder('note')
-			.where('note.replyId = :noteId', { noteId })
-			.orWhere(new Brackets(q => {
-				q.where('note.renoteId = :noteId', { noteId })
-				.andWhere('note.text IS NOT NULL');
-			}))
-			.leftJoinAndSelect('note.user', 'user');
-		const replies = await query.getMany();
-		for (const reply of replies) {
-			cascadingNotes.push(reply);
-			await recursive(reply.id);
-		}
-	};
-	await recursive(note.id);
-
-	return cascadingNotes.filter(note => note.userHost === null); // filter out non-local users
-}