perf: reduce query

This commit is contained in:
syuilo 2021-03-18 17:35:47 +09:00
parent 0c7a4a493b
commit 3c48081be9

View file

@ -11,33 +11,40 @@ import { perUserReactionsChart } from '../../chart';
import { genId } from '../../../misc/gen-id'; import { genId } from '../../../misc/gen-id';
import { createNotification } from '../../create-notification'; import { createNotification } from '../../create-notification';
import deleteReaction from './delete'; import deleteReaction from './delete';
import { isDuplicateKeyValueError } from '../../../misc/is-duplicate-key-value-error';
export default async (user: User, note: Note, reaction?: string) => { export default async (user: User, note: Note, reaction?: string) => {
reaction = await toDbReaction(reaction, user.host); reaction = await toDbReaction(reaction, user.host);
const exist = await NoteReactions.findOne({ let record;
noteId: note.id,
userId: user.id,
});
if (exist) {
if (exist.reaction !== reaction) {
// 別のリアクションがすでにされていたら置き換える
await deleteReaction(user, note);
} else {
// 同じリアクションがすでにされていたら何もしない
return;
}
}
// Create reaction // Create reaction
const inserted = await NoteReactions.save({ try {
id: genId(), record = await NoteReactions.save({
createdAt: new Date(), id: genId(),
noteId: note.id, createdAt: new Date(),
userId: user.id, noteId: note.id,
reaction userId: user.id,
}); reaction
});
} catch (e) {
if (isDuplicateKeyValueError(e)) {
record = await NoteReactions.findOneOrFail({
noteId: note.id,
userId: user.id,
});
if (record.reaction !== reaction) {
// 別のリアクションがすでにされていたら置き換える
await deleteReaction(user, note);
} else {
// 同じリアクションがすでにされていたら何もしない
return;
}
} else {
throw e;
}
}
// Increment reactions count // Increment reactions count
const sql = `jsonb_set("reactions", '{${reaction}}', (COALESCE("reactions"->>'${reaction}', '0')::int + 1)::text::jsonb)`; const sql = `jsonb_set("reactions", '{${reaction}}', (COALESCE("reactions"->>'${reaction}', '0')::int + 1)::text::jsonb)`;
@ -101,7 +108,7 @@ export default async (user: User, note: Note, reaction?: string) => {
//#region 配信 //#region 配信
if (Users.isLocalUser(user) && !note.localOnly) { if (Users.isLocalUser(user) && !note.localOnly) {
const content = renderActivity(await renderLike(inserted, note)); const content = renderActivity(await renderLike(record, note));
const dm = new DeliverManager(user, content); const dm = new DeliverManager(user, content);
if (note.userHost !== null) { if (note.userHost !== null) {
const reactee = await Users.findOne(note.userId); const reactee = await Users.findOne(note.userId);