diff options
| author | かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com> | 2025-11-24 20:59:25 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-24 20:59:25 +0900 |
| commit | f801d1cf0bdca97ae4d0cfea5ab06a5d4fc58749 (patch) | |
| tree | 0d6b49a7ce686bab7edbc441153f178134f59b9e /packages/backend/src | |
| parent | fix(frontend): PlayのAiScriptバージョン判定が正しく動作しな... (diff) | |
| download | misskey-f801d1cf0bdca97ae4d0cfea5ab06a5d4fc58749.tar.gz misskey-f801d1cf0bdca97ae4d0cfea5ab06a5d4fc58749.tar.bz2 misskey-f801d1cf0bdca97ae4d0cfea5ab06a5d4fc58749.zip | |
fix(backend): DBレプリケーションを利用する環境でクエリーが失敗する問題を修正 (#16842)
* fix: DBレプリケーションを利用する環境でクエリーが失敗する問題を修正 (MisskeyIO#1123)
* Update Changelog
---------
Co-authored-by: あわわわとーにゅ <17376330+u1-liquid@users.noreply.github.com>
Diffstat (limited to 'packages/backend/src')
| -rw-r--r-- | packages/backend/src/models/_.ts | 65 |
1 files changed, 1 insertions, 64 deletions
diff --git a/packages/backend/src/models/_.ts b/packages/backend/src/models/_.ts index 8c77a225c8..c4528e3a77 100644 --- a/packages/backend/src/models/_.ts +++ b/packages/backend/src/models/_.ts @@ -5,18 +5,9 @@ import { FindOneOptions, - InsertQueryBuilder, ObjectLiteral, - QueryRunner, Repository, - SelectQueryBuilder, } from 'typeorm'; -import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions.js'; -import { RelationCountLoader } from 'typeorm/query-builder/relation-count/RelationCountLoader.js'; -import { RelationIdLoader } from 'typeorm/query-builder/relation-id/RelationIdLoader.js'; -import { - RawSqlResultsToEntityTransformer, -} from 'typeorm/query-builder/transformer/RawSqlResultsToEntityTransformer.js'; import { MiAbuseReportNotificationRecipient } from '@/models/AbuseReportNotificationRecipient.js'; import { MiAbuseUserReport } from '@/models/AbuseUserReport.js'; import { MiAccessToken } from '@/models/AccessToken.js'; @@ -96,66 +87,12 @@ import { MiWebhook } from '@/models/Webhook.js'; import type { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity.js'; export interface MiRepository<T extends ObjectLiteral> { - createTableColumnNames(this: Repository<T> & MiRepository<T>): string[]; - insertOne(this: Repository<T> & MiRepository<T>, entity: QueryDeepPartialEntity<T>, findOptions?: Pick<FindOneOptions<T>, 'relations'>): Promise<T>; - - insertOneImpl(this: Repository<T> & MiRepository<T>, entity: QueryDeepPartialEntity<T>, findOptions?: Pick<FindOneOptions<T>, 'relations'>, queryRunner?: QueryRunner): Promise<T>; - - selectAliasColumnNames(this: Repository<T> & MiRepository<T>, queryBuilder: InsertQueryBuilder<T>, builder: SelectQueryBuilder<T>): void; } export const miRepository = { - createTableColumnNames() { - return this.metadata.columns.filter(column => column.isSelect && !column.isVirtual).map(column => column.databaseName); - }, async insertOne(entity, findOptions?) { - const opt = this.manager.connection.options as PostgresConnectionOptions; - if (opt.replication) { - const queryRunner = this.manager.connection.createQueryRunner('master'); - try { - return this.insertOneImpl(entity, findOptions, queryRunner); - } finally { - await queryRunner.release(); - } - } else { - return this.insertOneImpl(entity, findOptions); - } - }, - async insertOneImpl(entity, findOptions?, queryRunner?) { - // ---- insert + returningの結果を共通テーブル式(CTE)に保持するクエリを生成 ---- - - const queryBuilder = this.createQueryBuilder().insert().values(entity); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const mainAlias = queryBuilder.expressionMap.mainAlias!; - const name = mainAlias.name; - mainAlias.name = 't'; - const columnNames = this.createTableColumnNames(); - queryBuilder.returning(columnNames.reduce((a, c) => `${a}, ${queryBuilder.escape(c)}`, '').slice(2)); - - // ---- 共通テーブル式(CTE)から結果を取得 ---- - const builder = this.createQueryBuilder(undefined, queryRunner).addCommonTableExpression(queryBuilder, 'cte', { columnNames }); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - builder.expressionMap.mainAlias!.tablePath = 'cte'; - this.selectAliasColumnNames(queryBuilder, builder); - if (findOptions) { - builder.setFindOptions(findOptions); - } - const raw = await builder.execute(); - mainAlias.name = name; - const relationId = await new RelationIdLoader(builder.connection, this.queryRunner, builder.expressionMap.relationIdAttributes).load(raw); - const relationCount = await new RelationCountLoader(builder.connection, this.queryRunner, builder.expressionMap.relationCountAttributes).load(raw); - const result = new RawSqlResultsToEntityTransformer(builder.expressionMap, builder.connection.driver, relationId, relationCount, this.queryRunner).transform(raw, mainAlias); - return result[0]; - }, - selectAliasColumnNames(queryBuilder, builder) { - let selectOrAddSelect = (selection: string, selectionAliasName?: string) => { - selectOrAddSelect = (selection, selectionAliasName) => builder.addSelect(selection, selectionAliasName); - return builder.select(selection, selectionAliasName); - }; - for (const columnName of this.createTableColumnNames()) { - selectOrAddSelect(`${builder.alias}.${columnName}`, `${builder.alias}_${columnName}`); - } + return await this.insert(entity).then(x => this.findOneOrFail({ where: x.identifiers[0], ...findOptions })); }, } satisfies MiRepository<ObjectLiteral>; |