diff --git a/neko/index.js b/neko/index.js index 408bd0ca..c547c458 100644 --- a/neko/index.js +++ b/neko/index.js @@ -295,7 +295,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { EnvConfig, readEnvironmentConfig, readServerConfig, JsDbConn, initDatabase, AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, stringToAcct, acctToString, getFullApAccount, isSelfHost, extractHost, toPuny, toPunyOptional, convertToHiddenPost, sqlLikeEscape, safeForSql, formatMilliseconds, nativeInitIdGenerator, nativeCreateId, nativeGetTimestamp, fetchMeta, metaToPugArgs, genString, IdConvertType, convertId } = nativeBinding +const { EnvConfig, readEnvironmentConfig, readServerConfig, JsDbConn, initDatabase, AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, stringToAcct, acctToString, getFullApAccount, isSelfHost, extractHost, toPuny, toPunyOptional, convertToHiddenPost, countSameRenotes, sqlLikeEscape, safeForSql, formatMilliseconds, nativeInitIdGenerator, nativeCreateId, nativeGetTimestamp, fetchMeta, metaToPugArgs, genString, IdConvertType, convertId } = nativeBinding module.exports.EnvConfig = EnvConfig module.exports.readEnvironmentConfig = readEnvironmentConfig @@ -320,6 +320,7 @@ module.exports.extractHost = extractHost module.exports.toPuny = toPuny module.exports.toPunyOptional = toPunyOptional module.exports.convertToHiddenPost = convertToHiddenPost +module.exports.countSameRenotes = countSameRenotes module.exports.sqlLikeEscape = sqlLikeEscape module.exports.safeForSql = safeForSql module.exports.formatMilliseconds = formatMilliseconds diff --git a/packages/backend-rs/src/util/count_same_renotes.rs b/packages/backend-rs/src/util/count_same_renotes.rs new file mode 100644 index 00000000..a756484d --- /dev/null +++ b/packages/backend-rs/src/util/count_same_renotes.rs @@ -0,0 +1,19 @@ +use crate::database::{JsDbConn, NapiDbErrExt}; +use crate::model::entity::note; +use sea_orm::prelude::*; + +#[napi_derive::napi] +pub async fn count_same_renotes( + conn: &JsDbConn, + user_id: String, + renote_id: String, + exclude_note_id: Option, +) -> napi::Result { + let mut query = note::Entity::find() + .filter(note::Column::UserId.eq(user_id)) + .filter(note::Column::RenoteId.eq(renote_id)); + if let Some(exclude_note_id) = exclude_note_id { + query = query.filter(note::Column::Id.ne(exclude_note_id)); + } + query.count(conn.inner()).await.map_err(NapiDbErrExt::into) +} diff --git a/packages/backend-rs/src/util/mod.rs b/packages/backend-rs/src/util/mod.rs index bdbd2e45..50c47eb6 100644 --- a/packages/backend-rs/src/util/mod.rs +++ b/packages/backend-rs/src/util/mod.rs @@ -1,6 +1,7 @@ pub mod acct; pub mod convert_host; pub mod convert_to_hidden_post; +pub mod count_same_renotes; pub mod escape_sql; pub mod format_milliseconds; pub mod id; diff --git a/packages/backend/src/misc/backend-rs.ts b/packages/backend/src/misc/backend-rs.ts index bee18e12..a4ac8bc2 100644 --- a/packages/backend/src/misc/backend-rs.ts +++ b/packages/backend/src/misc/backend-rs.ts @@ -2,6 +2,7 @@ import { readServerConfig, readEnvironmentConfig, initDatabase, + countSameRenotes as countSameRenotesImpl, fetchMeta as fetchMetaImpl, getFullApAccount as getFullApAccountImpl, isSelfHost as isSelfHostImpl, @@ -13,6 +14,14 @@ const dbPromise = initDatabase(serverConfig.db); type Option = T | null | undefined; +type WithoutState = F extends (state: any, ...args: infer P) => infer R + ? (...args: P) => R + : never; + +export const countSameRenotes: WithoutState = ( + ...args +) => dbPromise.then((db) => countSameRenotesImpl(db, ...args)); + export const fetchMeta = (invalidateCache = false) => dbPromise.then((db) => fetchMetaImpl(db, invalidateCache)); diff --git a/packages/backend/src/misc/count-same-renotes.ts b/packages/backend/src/misc/count-same-renotes.ts deleted file mode 100644 index 45a6c1d3..00000000 --- a/packages/backend/src/misc/count-same-renotes.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Notes } from "@/models/index.js"; - -export async function countSameRenotes( - userId: string, - renoteId: string, - excludeNoteId: string | undefined, -): Promise { - // 指定したユーザーの指定したノートのリノートがいくつあるか数える - const query = Notes.createQueryBuilder("note") - .where("note.userId = :userId", { userId }) - .andWhere("note.renoteId = :renoteId", { renoteId }); - - // 指定した投稿を除く - if (excludeNoteId) { - query.andWhere("note.id != :excludeNoteId", { excludeNoteId }); - } - - return await query.getCount(); -} diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index e06b8562..bce1b65b 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -47,7 +47,7 @@ import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js import { checkHitAntenna } from "@/misc/check-hit-antenna.js"; import { getWordHardMute } from "@/misc/check-word-mute.js"; import { addNoteToAntenna } from "@/services/add-note-to-antenna.js"; -import { countSameRenotes } from "@/misc/count-same-renotes.js"; +import { countSameRenotes } from "@/misc/backend-rs.js"; import { deliverToRelays, getCachedRelays } from "../relay.js"; import type { Channel } from "@/models/entities/channel.js"; import { normalizeForSearch } from "@/misc/normalize-for-search.js"; @@ -412,7 +412,7 @@ export default async ( if ( data.renote && !user.isBot && - (await countSameRenotes(user.id, data.renote.id, note.id)) === 0 + (await countSameRenotes(user.id, data.renote.id, note.id)) === 0n ) { incRenoteCount(data.renote); } diff --git a/packages/backend/src/services/note/delete.ts b/packages/backend/src/services/note/delete.ts index f427da1f..dceb4c1d 100644 --- a/packages/backend/src/services/note/delete.ts +++ b/packages/backend/src/services/note/delete.ts @@ -13,7 +13,7 @@ import { deliverToFollowers, deliverToUser, } from "@/remote/activitypub/deliver-manager.js"; -import { countSameRenotes } from "@/misc/count-same-renotes.js"; +import { countSameRenotes } from "@/misc/backend-rs.js"; import { registerOrFetchInstanceDoc } from "@/services/register-or-fetch-instance-doc.js"; import { deliverToRelays } from "@/services/relay.js"; // import meilisearch from "@/db/meilisearch.js"; @@ -34,7 +34,7 @@ export default async function ( // この投稿を除く指定したユーザーによる指定したノートのリノートが存在しないとき if ( note.renoteId && - (await countSameRenotes(user.id, note.renoteId, note.id)) === 0 && + (await countSameRenotes(user.id, note.renoteId, note.id)) === 0n && deleteFromDb ) { Notes.decrement({ id: note.renoteId }, "renoteCount", 1);