summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2021-03-20 11:05:33 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2021-03-20 11:05:33 +0900
commite523e54881834a50b7b5e1f0efebcc98cfc34dd7 (patch)
treed1205c11c3b88acb303b459586062b423f69dc0b /src
parentfix: suppress disk stats error (diff)
downloadsharkey-e523e54881834a50b7b5e1f0efebcc98cfc34dd7.tar.gz
sharkey-e523e54881834a50b7b5e1f0efebcc98cfc34dd7.tar.bz2
sharkey-e523e54881834a50b7b5e1f0efebcc98cfc34dd7.zip
perf(server): Reduce database query
Diffstat (limited to 'src')
-rw-r--r--src/models/repositories/notification.ts67
-rw-r--r--src/server/api/endpoints/i/notifications.ts2
2 files changed, 58 insertions, 11 deletions
diff --git a/src/models/repositories/notification.ts b/src/models/repositories/notification.ts
index d593dc22a9..a9fe5e7b4e 100644
--- a/src/models/repositories/notification.ts
+++ b/src/models/repositories/notification.ts
@@ -1,8 +1,11 @@
-import { EntityRepository, Repository } from 'typeorm';
-import { Users, Notes, UserGroupInvitations, AccessTokens } from '..';
+import { EntityRepository, In, Repository } from 'typeorm';
+import { Users, Notes, UserGroupInvitations, AccessTokens, NoteReactions } from '..';
import { Notification } from '../entities/notification';
import { awaitAll } from '../../prelude/await-all';
import { SchemaType } from '../../misc/schema';
+import { Note } from '../entities/note';
+import { NoteReaction } from '../entities/note-reaction';
+import { User } from '../entities/user';
export type PackedNotification = SchemaType<typeof packedNotificationSchema>;
@@ -10,6 +13,11 @@ export type PackedNotification = SchemaType<typeof packedNotificationSchema>;
export class NotificationRepository extends Repository<Notification> {
public async pack(
src: Notification['id'] | Notification,
+ options: {
+ _hintForEachNotes_: {
+ myReactions: Map<Note['id'], NoteReaction | null>;
+ };
+ }
): Promise<PackedNotification> {
const notification = typeof src === 'object' ? src : await this.findOneOrFail(src);
const token = notification.appAccessTokenId ? await AccessTokens.findOneOrFail(notification.appAccessTokenId) : null;
@@ -22,23 +30,41 @@ export class NotificationRepository extends Repository<Notification> {
userId: notification.notifierId,
user: notification.notifierId ? Users.pack(notification.notifier || notification.notifierId) : null,
...(notification.type === 'mention' ? {
- note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId),
+ note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, {
+ detail: true,
+ _hint_: options._hintForEachNotes_
+ }),
} : {}),
...(notification.type === 'reply' ? {
- note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId),
+ note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, {
+ detail: true,
+ _hint_: options._hintForEachNotes_
+ }),
} : {}),
...(notification.type === 'renote' ? {
- note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId),
+ note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, {
+ detail: true,
+ _hint_: options._hintForEachNotes_
+ }),
} : {}),
...(notification.type === 'quote' ? {
- note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId),
+ note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, {
+ detail: true,
+ _hint_: options._hintForEachNotes_
+ }),
} : {}),
...(notification.type === 'reaction' ? {
- note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId),
+ note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, {
+ detail: true,
+ _hint_: options._hintForEachNotes_
+ }),
reaction: notification.reaction
} : {}),
...(notification.type === 'pollVote' ? {
- note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId),
+ note: Notes.pack(notification.note || notification.noteId!, notification.notifieeId, {
+ detail: true,
+ _hint_: options._hintForEachNotes_
+ }),
choice: notification.choice
} : {}),
...(notification.type === 'groupInvited' ? {
@@ -52,10 +78,31 @@ export class NotificationRepository extends Repository<Notification> {
});
}
- public packMany(
+ public async packMany(
notifications: Notification[],
+ meId: User['id']
) {
- return Promise.all(notifications.map(x => this.pack(x)));
+ if (notifications.length === 0) return [];
+
+ const notes = notifications.filter(x => x.note != null).map(x => x.note!);
+ const noteIds = notes.map(n => n.id);
+ const myReactionsMap = new Map<Note['id'], NoteReaction | null>();
+ const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!);
+ const targets = [...noteIds, ...renoteIds];
+ const myReactions = await NoteReactions.find({
+ userId: meId,
+ noteId: In(targets),
+ });
+
+ for (const target of targets) {
+ myReactionsMap.set(target, myReactions.find(reaction => reaction.noteId === target) || null);
+ }
+
+ return await Promise.all(notifications.map(x => this.pack(x, {
+ _hintForEachNotes_: {
+ myReactions: myReactionsMap
+ }
+ })));
}
}
diff --git a/src/server/api/endpoints/i/notifications.ts b/src/server/api/endpoints/i/notifications.ts
index 7a423edb8d..af49549d37 100644
--- a/src/server/api/endpoints/i/notifications.ts
+++ b/src/server/api/endpoints/i/notifications.ts
@@ -112,5 +112,5 @@ export default define(meta, async (ps, user) => {
readNotification(user.id, notifications.map(x => x.id));
}
- return await Notifications.packMany(notifications);
+ return await Notifications.packMany(notifications, user.id);
});