// server/utils/prisma.ts - Prisma 客户端初始化:使用 MariaDB adapter 并在开发热更新中复用连接池。 import { PrismaMariaDb } from "@prisma/adapter-mariadb"; import { PrismaClient } from "~~/app/generated/prisma/client"; const globalForPrisma = globalThis as unknown as { prisma?: PrismaClient; }; const databaseUrl = process.env.DATABASE_URL; if (!databaseUrl) { throw new Error("DATABASE_URL is required to initialize PrismaClient"); } type MariaDbPoolConfig = Exclude< ConstructorParameters[0], string >; /** 从 DATABASE_URL 查询参数读取连接池配置,非法值回退到默认值 */ function getNumberParam(url: URL, name: string, fallback: number) { const value = url.searchParams.get(name); if (!value) { return fallback; } const parsed = Number(value); return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback; } /** 将 DATABASE_URL 拆成 Prisma MariaDB adapter 需要的连接池配置 */ function createMariaDbConfig(urlString: string): MariaDbPoolConfig { const url = new URL(urlString); const database = decodeURIComponent(url.pathname.replace(/^\//, "")); if (!url.hostname || !url.username || !database) { throw new Error("DATABASE_URL must include host, user and database"); } const port = url.port ? Number(url.port) : 3306; if (!Number.isInteger(port) || port <= 0) { throw new Error("DATABASE_URL port is invalid"); } return { host: url.hostname, port, user: decodeURIComponent(url.username), password: decodeURIComponent(url.password), database, connectionLimit: getNumberParam(url, "connection_limit", 5), acquireTimeout: getNumberParam(url, "pool_timeout", 30) * 1000, connectTimeout: getNumberParam(url, "connect_timeout", 10) * 1000 }; } const mariaDbConfig = createMariaDbConfig(databaseUrl); const adapter = new PrismaMariaDb(mariaDbConfig, { database: mariaDbConfig.database }); /** Reuse PrismaClient during dev hot reloads so Nuxt does not create duplicate pools. */ export const prisma = globalForPrisma.prisma ?? new PrismaClient({ adapter, log: ["warn", "error"] }); if (process.env.NODE_ENV !== "production") { globalForPrisma.prisma = prisma; }