From bc8b1b8035a078ce34de8dfadfeee33f5fc4edfa Mon Sep 17 00:00:00 2001 From: Mel-906 Date: Fri, 27 Mar 2026 00:06:45 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20AsyncLocalStorage=E3=82=92=E7=94=A8?= =?UTF-8?q?=E3=81=84=E3=81=9FUnit=20of=20Work=E5=9F=BA=E7=9B=A4=E3=82=92?= =?UTF-8?q?=E5=B0=8E=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 複数の集約をまたぐDB操作をトランザクションで安全にまとめるための仕組みを追加。 AsyncLocalStorageによりRepository側のコード変更なしでトランザクションを共有できる。 Co-Authored-By: Claude Opus 4.6 (1M context) --- .codex | 0 src/application/UnitOfWork.ts | 7 +++ src/application/index.ts | 1 + src/application/usecase/base.ts | 24 ++++++++++ .../drizzle/DrizzleUnitOfWork.ts | 12 +++++ src/infrastructure/drizzle/client.ts | 46 +++++++++++++++---- src/infrastructure/drizzle/index.ts | 1 + 7 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 .codex create mode 100644 src/application/UnitOfWork.ts create mode 100644 src/infrastructure/drizzle/DrizzleUnitOfWork.ts diff --git a/.codex b/.codex new file mode 100644 index 0000000..e69de29 diff --git a/src/application/UnitOfWork.ts b/src/application/UnitOfWork.ts new file mode 100644 index 0000000..2987d89 --- /dev/null +++ b/src/application/UnitOfWork.ts @@ -0,0 +1,7 @@ +/** + * 一連の操作をまとめて扱うためのインターフェース + * 具体的な実装(DBトランザクション等)はInfrastructure層が担当する + */ +export interface UnitOfWork { + run(fn: () => Promise): Promise; +} diff --git a/src/application/index.ts b/src/application/index.ts index 4008668..d86cc99 100644 --- a/src/application/index.ts +++ b/src/application/index.ts @@ -1,4 +1,5 @@ export * from "./dto"; +export * from "./UnitOfWork"; export * from "./usecase/member"; export * from "./usecase/event"; export * from "./usecase/eventParticipation"; diff --git a/src/application/usecase/base.ts b/src/application/usecase/base.ts index 9704b84..c6f3eac 100644 --- a/src/application/usecase/base.ts +++ b/src/application/usecase/base.ts @@ -1,8 +1,32 @@ +import type { UnitOfWork } from "../UnitOfWork"; + /** * ユースケースの基底抽象クラス * TInputはユースケースへの入力型 * TOutputはユースケースからの出力型 */ export abstract class IUseCase { + /** + * ユースケースのビジネスロジックを実行する + * トランザクションなしで実行されるため、読み取り専用のUseCaseはこちらを使う + * 複数のDB書き込みを安全にまとめたい場合は run() を使うこと + */ abstract execute(input: Input): Promise; + + /** + * UnitOfWorkで囲んでexecuteを実行する + * トランザクション内で全てのDB操作がまとめて成功/失敗する + * 複数の集約をまたぐ書き込み操作がある場合に使用する + * + * 注意: + * - execute()内で外部API呼び出し(Discord API等)を行うと、 + * その応答待ちの間トランザクションが開きっぱなしになる + * 外部連携はトランザクション完了後に行うこと + * - トランザクションがロールバックされてもメモリ上のドメインオブジェクトは + * 元に戻らない。execute()内で取得・変更したドメインオブジェクトを + * ロールバック後に再利用しないこと + */ + async run(input: Input, unitOfWork: UnitOfWork): Promise { + return unitOfWork.run(() => this.execute(input)); + } } diff --git a/src/infrastructure/drizzle/DrizzleUnitOfWork.ts b/src/infrastructure/drizzle/DrizzleUnitOfWork.ts new file mode 100644 index 0000000..0c3bd27 --- /dev/null +++ b/src/infrastructure/drizzle/DrizzleUnitOfWork.ts @@ -0,0 +1,12 @@ +import type { UnitOfWork } from "#application/UnitOfWork"; +import { runInTransaction } from "./client"; + +/** + * UnitOfWorkのDrizzle実装 + * AsyncLocalStorageを利用して、トランザクションを処理の流れ全体で共有する + */ +export class DrizzleUnitOfWork implements UnitOfWork { + async run(fn: () => Promise): Promise { + return runInTransaction(fn); + } +} diff --git a/src/infrastructure/drizzle/client.ts b/src/infrastructure/drizzle/client.ts index 14fa1e5..025e627 100644 --- a/src/infrastructure/drizzle/client.ts +++ b/src/infrastructure/drizzle/client.ts @@ -1,24 +1,54 @@ /// +import { AsyncLocalStorage } from "node:async_hooks"; +import type { PgDatabase } from "drizzle-orm/pg-core"; import { drizzle } from "drizzle-orm/postgres-js"; +import type { PostgresJsQueryResultHKT } from "drizzle-orm/postgres-js/session"; import postgres, { type Sql } from "postgres"; import * as schema from "./schema"; -let client: Sql | null = null; +export type DrizzleDb = PgDatabase; -function getClient(): Sql { - if (!client) { +let sqlClient: Sql | null = null; + +function getSqlClient(): Sql { + if (!sqlClient) { const connectionString = process.env.DATABASE_URL; if (!connectionString) { throw new Error("DATABASE_URL environment variable is not set"); } // Supabase の Transaction pool mode は prepared statement をサポートしないため無効化 - client = postgres(connectionString, { prepare: false }); + sqlClient = postgres(connectionString, { prepare: false }); } - return client; + return sqlClient; +} + +function createDb() { + return drizzle(getSqlClient(), { schema }); } -export function getDb() { - return drizzle(getClient(), { schema }); +const transactionContext = new AsyncLocalStorage(); + +/** + * DB接続を取得する + * トランザクション中であればそのトランザクションを返し、 + * そうでなければ新しいDB接続を返す + */ +export function getDb(): DrizzleDb { + const tx = transactionContext.getStore(); + if (tx) return tx; + return createDb(); } -export type DrizzleDb = ReturnType; +/** + * トランザクション内で処理を実行する + * すでにトランザクション中であればそのまま実行する(ネストしない) + */ +export function runInTransaction(fn: () => Promise): Promise { + if (transactionContext.getStore()) { + return fn(); + } + const db = createDb(); + return db.transaction(async (tx) => { + return transactionContext.run(tx, fn); + }); +} diff --git a/src/infrastructure/drizzle/index.ts b/src/infrastructure/drizzle/index.ts index a84e17e..8c90ff3 100644 --- a/src/infrastructure/drizzle/index.ts +++ b/src/infrastructure/drizzle/index.ts @@ -2,3 +2,4 @@ export { DrizzleDiscordAccountRepository } from "./DrizzleDiscordAccountReposito export { DrizzleEventRepository } from "./DrizzleEventRepository"; export { DrizzleKarteRepository } from "./DrizzleKarteRepository"; export { DrizzleMemberRepository } from "./DrizzleMemberRepository"; +export { DrizzleUnitOfWork } from "./DrizzleUnitOfWork"; From ba137b9a67f545c4d0fb518761bd75a8c98d04a3 Mon Sep 17 00:00:00 2001 From: Mel-906 Date: Sat, 28 Mar 2026 23:15:00 +0900 Subject: [PATCH 2/4] =?UTF-8?q?refactor:=20getDb/createDb/DrizzleDb=20?= =?UTF-8?q?=E3=82=92=20getClient/createClient/DrizzleClient=20=E3=81=AB?= =?UTF-8?q?=E3=83=AA=E3=83=8D=E3=83=BC=E3=83=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 生成・取得しているのはDBそのものではなくDrizzleクライアントであるため、 実態に合った命名に修正。 Co-Authored-By: Claude Opus 4.6 (1M context) --- .codex | 0 .../DrizzleDiscordAccountRepository.ts | 10 ++++---- .../drizzle/DrizzleEventRepository.ts | 22 ++++++++--------- .../drizzle/DrizzleKarteRepository.ts | 8 +++---- .../drizzle/DrizzleMemberRepository.ts | 10 ++++---- src/infrastructure/drizzle/client.ts | 24 +++++++++++++++---- 6 files changed, 44 insertions(+), 30 deletions(-) delete mode 100644 .codex diff --git a/.codex b/.codex deleted file mode 100644 index e69de29..0000000 diff --git a/src/infrastructure/drizzle/DrizzleDiscordAccountRepository.ts b/src/infrastructure/drizzle/DrizzleDiscordAccountRepository.ts index 8fe843c..df80da4 100644 --- a/src/infrastructure/drizzle/DrizzleDiscordAccountRepository.ts +++ b/src/infrastructure/drizzle/DrizzleDiscordAccountRepository.ts @@ -8,7 +8,7 @@ import { discordId, memberId, } from "#domain"; -import { getDb } from "./client"; +import { getClient } from "./client"; import { discordAccountDomainEvents, discordAccounts } from "./schema"; import { serializeDiscordAccountEventPayload } from "./serializeDiscordAccountEvent"; @@ -20,7 +20,7 @@ function toDomain(row: DiscordAccountRow): DiscordAccount { export class DrizzleDiscordAccountRepository implements DiscordAccountRepository { async findByDiscordId(id: DiscordId): Promise { - const db = getDb(); + const db = getClient(); const row = await db.query.discordAccounts.findFirst({ where: eq(discordAccounts.discordId, id as string), }); @@ -29,7 +29,7 @@ export class DrizzleDiscordAccountRepository implements DiscordAccountRepository } async findByMemberId(id: MemberId): Promise { - const db = getDb(); + const db = getClient(); const rows = await db.query.discordAccounts.findMany({ where: eq(discordAccounts.memberId, id as string), }); @@ -43,7 +43,7 @@ export class DrizzleDiscordAccountRepository implements DiscordAccountRepository } async save(account: DiscordAccount): Promise { - const db = getDb(); + const db = getClient(); const now = new Date().toISOString(); const events = account.getDomainEvents(); @@ -80,7 +80,7 @@ export class DrizzleDiscordAccountRepository implements DiscordAccountRepository } async delete(id: DiscordId): Promise { - const db = getDb(); + const db = getClient(); await db.delete(discordAccounts).where(eq(discordAccounts.discordId, id as string)); } } diff --git a/src/infrastructure/drizzle/DrizzleEventRepository.ts b/src/infrastructure/drizzle/DrizzleEventRepository.ts index 9451f0d..432c098 100644 --- a/src/infrastructure/drizzle/DrizzleEventRepository.ts +++ b/src/infrastructure/drizzle/DrizzleEventRepository.ts @@ -14,7 +14,7 @@ import { exhibitId, memberId, } from "#domain"; -import { type DrizzleDb, getDb } from "./client"; +import { type DrizzleClient, getClient } from "./client"; import { events, exhibits, lightningTalks, memberEvents, memberExhibits } from "./schema"; // ============================================================================ @@ -101,7 +101,7 @@ export class DrizzleEventRepository implements EventRepository { // ========================================================================== private async persistEvent(event: Event): Promise { - const db = getDb(); + const db = getClient(); const snapshot = event.toSnapshot(); const now = new Date().toISOString(); const dateStr = snapshot.date instanceof Date ? snapshot.date.toISOString() : snapshot.date; @@ -143,7 +143,7 @@ export class DrizzleEventRepository implements EventRepository { } private async deleteObsoleteExhibits( - db: DrizzleDb, + db: DrizzleClient, eventId: EventId, keptExhibitIds: ExhibitId[], ): Promise { @@ -164,7 +164,7 @@ export class DrizzleEventRepository implements EventRepository { } private async upsertExhibit( - db: DrizzleDb, + db: DrizzleClient, eventId: EventId, ex: ReturnType["exhibits"][number], ): Promise { @@ -220,7 +220,7 @@ export class DrizzleEventRepository implements EventRepository { } private async syncMemberEvents( - db: DrizzleDb, + db: DrizzleClient, eventId: EventId, memberIds: MemberId[], ): Promise { @@ -241,7 +241,7 @@ export class DrizzleEventRepository implements EventRepository { } private async syncMemberExhibits( - db: DrizzleDb, + db: DrizzleClient, exhibitId: ExhibitId, memberIds: MemberId[], ): Promise { @@ -266,7 +266,7 @@ export class DrizzleEventRepository implements EventRepository { // ========================================================================== async findById(id: EventId): Promise { - const db = getDb(); + const db = getClient(); const record = await db.query.events.findFirst({ where: eq(events.id, id), with: { @@ -285,7 +285,7 @@ export class DrizzleEventRepository implements EventRepository { } async findByParticipantMemberId(memberId: MemberId): Promise { - const db = getDb(); + const db = getClient(); const participations = await db .select({ eventId: memberEvents.eventId }) @@ -312,7 +312,7 @@ export class DrizzleEventRepository implements EventRepository { } async findByExhibitId(exhibitId: ExhibitId): Promise { - const db = getDb(); + const db = getClient(); const exhibit = await db .select({ eventId: exhibits.eventId }) @@ -325,7 +325,7 @@ export class DrizzleEventRepository implements EventRepository { } async findAll(): Promise { - const db = getDb(); + const db = getClient(); const records = await db.query.events.findMany({ with: { memberEvents: true, @@ -346,7 +346,7 @@ export class DrizzleEventRepository implements EventRepository { } async delete(eventId: EventId): Promise { - const db = getDb(); + const db = getClient(); const exhibitRecords = await db .select({ id: exhibits.id }) diff --git a/src/infrastructure/drizzle/DrizzleKarteRepository.ts b/src/infrastructure/drizzle/DrizzleKarteRepository.ts index 86fc967..0366285 100644 --- a/src/infrastructure/drizzle/DrizzleKarteRepository.ts +++ b/src/infrastructure/drizzle/DrizzleKarteRepository.ts @@ -21,7 +21,7 @@ import { type Resolution, type SupportRecord, } from "#domain"; -import { getDb } from "./client"; +import { getClient } from "./client"; import { karteAssignees, kartes } from "./schema"; // ============================================================================ @@ -250,7 +250,7 @@ function consultedAtToPrecision(r: Recorded): ConsultedAt["precisio export class DrizzleKarteRepository implements KarteRepository { async findById(id: KarteId): Promise { - const db = getDb(); + const db = getClient(); const row = await db.query.kartes.findFirst({ where: eq(kartes.id, id as string), with: { @@ -263,7 +263,7 @@ export class DrizzleKarteRepository implements KarteRepository { } async findAll(): Promise { - const db = getDb(); + const db = getClient(); const rows = await db.query.kartes.findMany({ with: { karteAssignees: true, @@ -274,7 +274,7 @@ export class DrizzleKarteRepository implements KarteRepository { } async save(karte: Karte): Promise { - const db = getDb(); + const db = getClient(); const clientCols = clientToColumns(karte.client); const resCols = resolutionToColumns(karte.supportRecord.resolution); diff --git a/src/infrastructure/drizzle/DrizzleMemberRepository.ts b/src/infrastructure/drizzle/DrizzleMemberRepository.ts index 7f77ec7..144c8d1 100644 --- a/src/infrastructure/drizzle/DrizzleMemberRepository.ts +++ b/src/infrastructure/drizzle/DrizzleMemberRepository.ts @@ -16,7 +16,7 @@ import { type MemberRepository, type Recorded, } from "#domain"; -import { getDb } from "./client"; +import { getClient } from "./client"; import { memberDomainEvents, members } from "./schema"; import { serializeMemberEventPayload } from "./serializeMemberEvent"; @@ -100,7 +100,7 @@ function toInsertValues(member: Member): MemberInsert { export class DrizzleMemberRepository implements MemberRepository { async findById(id: MemberId): Promise { - const db = getDb(); + const db = getClient(); const row = await db.query.members.findFirst({ where: eq(members.id, id as string), }); @@ -109,7 +109,7 @@ export class DrizzleMemberRepository implements MemberRepository { } async findByEmail(email: UniversityEmail): Promise { - const db = getDb(); + const db = getClient(); const row = await db.query.members.findFirst({ where: eq(members.email, email.getValue()), }); @@ -118,13 +118,13 @@ export class DrizzleMemberRepository implements MemberRepository { } async findAll(): Promise { - const db = getDb(); + const db = getClient(); const rows = await db.query.members.findMany(); return rows.map(toDomain); } async save(member: Member): Promise { - const db = getDb(); + const db = getClient(); const values = toInsertValues(member); const events = member.getDomainEvents(); diff --git a/src/infrastructure/drizzle/client.ts b/src/infrastructure/drizzle/client.ts index 025e627..187b642 100644 --- a/src/infrastructure/drizzle/client.ts +++ b/src/infrastructure/drizzle/client.ts @@ -22,21 +22,31 @@ function getSqlClient(): Sql { return sqlClient; } +<<<<<<< HEAD function createDb() { return drizzle(getSqlClient(), { schema }); } const transactionContext = new AsyncLocalStorage(); +======= +function createClient() { + return drizzle(getPool(), { schema }); +} + +export type DrizzleClient = ReturnType; + +const transactionContext = new AsyncLocalStorage(); +>>>>>>> 91008a2 (refactor: getDb/createDb/DrizzleDb を getClient/createClient/DrizzleClient にリネーム) /** - * DB接続を取得する + * Drizzleクライアントを取得する * トランザクション中であればそのトランザクションを返し、 - * そうでなければ新しいDB接続を返す + * そうでなければ新しいクライアントを返す */ -export function getDb(): DrizzleDb { +export function getClient(): DrizzleClient { const tx = transactionContext.getStore(); if (tx) return tx; - return createDb(); + return createClient(); } /** @@ -47,8 +57,12 @@ export function runInTransaction(fn: () => Promise): Promise { if (transactionContext.getStore()) { return fn(); } - const db = createDb(); + const db = createClient(); return db.transaction(async (tx) => { +<<<<<<< HEAD return transactionContext.run(tx, fn); +======= + return transactionContext.run(tx as unknown as DrizzleClient, fn); +>>>>>>> 91008a2 (refactor: getDb/createDb/DrizzleDb を getClient/createClient/DrizzleClient にリネーム) }); } From a90e5395889636072519cebfdf77077d34906eff Mon Sep 17 00:00:00 2001 From: Mel-906 Date: Sat, 28 Mar 2026 23:32:34 +0900 Subject: [PATCH 3/4] =?UTF-8?q?refactor:=20DrizzleClient=E3=82=92PgDatabas?= =?UTF-8?q?e=E5=9E=8B=E3=81=A7=E5=AE=9A=E7=BE=A9=E3=81=97=E3=83=88?= =?UTF-8?q?=E3=83=A9=E3=83=B3=E3=82=B6=E3=82=AF=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E3=81=AE=E5=BC=B7=E5=88=B6=E3=82=AD=E3=83=A3=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=92=E9=99=A4=E5=8E=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PgTransactionはPgDatabaseを継承しているため、DrizzleClientを PgDatabaseで定義することで DB接続とトランザクションを同じ型として扱えるようになった。 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/infrastructure/drizzle/client.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/infrastructure/drizzle/client.ts b/src/infrastructure/drizzle/client.ts index 187b642..d37edc2 100644 --- a/src/infrastructure/drizzle/client.ts +++ b/src/infrastructure/drizzle/client.ts @@ -1,5 +1,6 @@ /// import { AsyncLocalStorage } from "node:async_hooks"; +<<<<<<< HEAD import type { PgDatabase } from "drizzle-orm/pg-core"; import { drizzle } from "drizzle-orm/postgres-js"; import type { PostgresJsQueryResultHKT } from "drizzle-orm/postgres-js/session"; @@ -7,6 +8,17 @@ import postgres, { type Sql } from "postgres"; import * as schema from "./schema"; export type DrizzleDb = PgDatabase; +======= +import type { NodePgQueryResultHKT } from "drizzle-orm/node-postgres"; +import { drizzle } from "drizzle-orm/node-postgres"; +import type { PgDatabase } from "drizzle-orm/pg-core"; +import { Pool } from "pg"; +import * as schema from "./schema"; + +export type DrizzleClient = PgDatabase; + +let pool: Pool | null = null; +>>>>>>> 6d5f1a6 (refactor: DrizzleClientをPgDatabase型で定義しトランザクションの強制キャストを除去) let sqlClient: Sql | null = null; @@ -22,6 +34,7 @@ function getSqlClient(): Sql { return sqlClient; } +<<<<<<< HEAD <<<<<<< HEAD function createDb() { return drizzle(getSqlClient(), { schema }); @@ -30,11 +43,12 @@ function createDb() { const transactionContext = new AsyncLocalStorage(); ======= function createClient() { +======= +function createClient(): DrizzleClient { +>>>>>>> 6d5f1a6 (refactor: DrizzleClientをPgDatabase型で定義しトランザクションの強制キャストを除去) return drizzle(getPool(), { schema }); } -export type DrizzleClient = ReturnType; - const transactionContext = new AsyncLocalStorage(); >>>>>>> 91008a2 (refactor: getDb/createDb/DrizzleDb を getClient/createClient/DrizzleClient にリネーム) @@ -59,10 +73,14 @@ export function runInTransaction(fn: () => Promise): Promise { } const db = createClient(); return db.transaction(async (tx) => { +<<<<<<< HEAD <<<<<<< HEAD return transactionContext.run(tx, fn); ======= return transactionContext.run(tx as unknown as DrizzleClient, fn); >>>>>>> 91008a2 (refactor: getDb/createDb/DrizzleDb を getClient/createClient/DrizzleClient にリネーム) +======= + return transactionContext.run(tx, fn); +>>>>>>> 6d5f1a6 (refactor: DrizzleClientをPgDatabase型で定義しトランザクションの強制キャストを除去) }); } From 21d05431758f38746e149b33f39fc58fb61f3a9a Mon Sep 17 00:00:00 2001 From: Mel-906 Date: Sat, 25 Apr 2026 03:48:34 +0900 Subject: [PATCH 4/4] fix: resolve drizzle client merge conflict --- .../DrizzleDiscordAccountRepository.ts | 2 +- src/infrastructure/drizzle/client.ts | 36 ++----------------- 2 files changed, 3 insertions(+), 35 deletions(-) diff --git a/src/infrastructure/drizzle/DrizzleDiscordAccountRepository.ts b/src/infrastructure/drizzle/DrizzleDiscordAccountRepository.ts index df80da4..d71c4f2 100644 --- a/src/infrastructure/drizzle/DrizzleDiscordAccountRepository.ts +++ b/src/infrastructure/drizzle/DrizzleDiscordAccountRepository.ts @@ -37,7 +37,7 @@ export class DrizzleDiscordAccountRepository implements DiscordAccountRepository } async findAll(): Promise { - const db = getDb(); + const db = getClient(); const rows = await db.query.discordAccounts.findMany(); return rows.map(toDomain); } diff --git a/src/infrastructure/drizzle/client.ts b/src/infrastructure/drizzle/client.ts index d37edc2..af83232 100644 --- a/src/infrastructure/drizzle/client.ts +++ b/src/infrastructure/drizzle/client.ts @@ -1,24 +1,12 @@ /// import { AsyncLocalStorage } from "node:async_hooks"; -<<<<<<< HEAD import type { PgDatabase } from "drizzle-orm/pg-core"; import { drizzle } from "drizzle-orm/postgres-js"; import type { PostgresJsQueryResultHKT } from "drizzle-orm/postgres-js/session"; import postgres, { type Sql } from "postgres"; import * as schema from "./schema"; -export type DrizzleDb = PgDatabase; -======= -import type { NodePgQueryResultHKT } from "drizzle-orm/node-postgres"; -import { drizzle } from "drizzle-orm/node-postgres"; -import type { PgDatabase } from "drizzle-orm/pg-core"; -import { Pool } from "pg"; -import * as schema from "./schema"; - -export type DrizzleClient = PgDatabase; - -let pool: Pool | null = null; ->>>>>>> 6d5f1a6 (refactor: DrizzleClientをPgDatabase型で定義しトランザクションの強制キャストを除去) +export type DrizzleClient = PgDatabase; let sqlClient: Sql | null = null; @@ -34,23 +22,11 @@ function getSqlClient(): Sql { return sqlClient; } -<<<<<<< HEAD -<<<<<<< HEAD -function createDb() { - return drizzle(getSqlClient(), { schema }); -} - -const transactionContext = new AsyncLocalStorage(); -======= -function createClient() { -======= function createClient(): DrizzleClient { ->>>>>>> 6d5f1a6 (refactor: DrizzleClientをPgDatabase型で定義しトランザクションの強制キャストを除去) - return drizzle(getPool(), { schema }); + return drizzle(getSqlClient(), { schema }); } const transactionContext = new AsyncLocalStorage(); ->>>>>>> 91008a2 (refactor: getDb/createDb/DrizzleDb を getClient/createClient/DrizzleClient にリネーム) /** * Drizzleクライアントを取得する @@ -73,14 +49,6 @@ export function runInTransaction(fn: () => Promise): Promise { } const db = createClient(); return db.transaction(async (tx) => { -<<<<<<< HEAD -<<<<<<< HEAD - return transactionContext.run(tx, fn); -======= - return transactionContext.run(tx as unknown as DrizzleClient, fn); ->>>>>>> 91008a2 (refactor: getDb/createDb/DrizzleDb を getClient/createClient/DrizzleClient にリネーム) -======= return transactionContext.run(tx, fn); ->>>>>>> 6d5f1a6 (refactor: DrizzleClientをPgDatabase型で定義しトランザクションの強制キャストを除去) }); }