74 lines
2.4 KiB
TypeScript
74 lines
2.4 KiB
TypeScript
// server/utils/db.ts - Prisma Client 单例,当前答题 API 不依赖数据库,保留给后续业务使用
|
||
import { PrismaMariaDb } from "@prisma/adapter-mariadb";
|
||
|
||
import { PrismaClient } from "~~/prisma/generated/client";
|
||
|
||
/**
|
||
* 将 `DATABASE_URL` 解析为 MariaDB driver 的连接池配置
|
||
*
|
||
* Prisma 7 使用 driver adapter 后,需要显式传入 adapter;
|
||
* 这里不把连接串原样传给前端或日志,只在服务端初始化连接池
|
||
*/
|
||
const createMariaDbConfig = () => {
|
||
const databaseUrl = process.env.DATABASE_URL;
|
||
|
||
if (!databaseUrl) {
|
||
throw new Error("DATABASE_URL is not set.");
|
||
}
|
||
|
||
const url = new URL(databaseUrl);
|
||
|
||
return {
|
||
host: url.hostname,
|
||
port: Number(url.port || 3306),
|
||
user: decodeURIComponent(url.username),
|
||
password: decodeURIComponent(url.password),
|
||
database: decodeURIComponent(url.pathname.slice(1)),
|
||
connectionLimit: 5,
|
||
connectTimeout: 15_000,
|
||
// 正常情况下连接应立即可用;5s 内拿不到连接说明池已耗尽,快速报错优于无限挂起
|
||
acquireTimeout: 5_000
|
||
};
|
||
};
|
||
|
||
type MariaDbConfig = ReturnType<typeof createMariaDbConfig>;
|
||
|
||
/**
|
||
* 创建 Prisma Client
|
||
*
|
||
* 连接池超时设置比默认值更宽松,是因为当前数据库是远程 MySQL,
|
||
* 默认超时时间过短时 Node driver 可能还没建好 socket 就失败
|
||
*/
|
||
const prismaClientSingleton = (config: MariaDbConfig) => {
|
||
const adapter = new PrismaMariaDb(config);
|
||
return new PrismaClient({ adapter });
|
||
};
|
||
|
||
type PrismaClientSingleton = ReturnType<typeof prismaClientSingleton>;
|
||
|
||
/**
|
||
* 开发环境热更新会反复加载模块
|
||
*
|
||
* 把 Prisma Client 挂到 globalThis 上,可以避免每次 HMR 都新建连接池
|
||
*/
|
||
const globalForPrisma = globalThis as unknown as {
|
||
prisma: PrismaClientSingleton | undefined;
|
||
prismaConfigSignature: string | undefined;
|
||
};
|
||
|
||
const mariaDbConfig = createMariaDbConfig();
|
||
const prismaConfigSignature = JSON.stringify(mariaDbConfig);
|
||
|
||
/** 全项目唯一 Prisma Client 实例 */
|
||
export const prisma =
|
||
globalForPrisma.prisma &&
|
||
globalForPrisma.prismaConfigSignature === prismaConfigSignature
|
||
? globalForPrisma.prisma
|
||
: prismaClientSingleton(mariaDbConfig);
|
||
|
||
// 生产环境由进程生命周期管理;开发环境缓存到全局,减少 HMR 连接泄漏
|
||
if (process.env.NODE_ENV !== "production") {
|
||
globalForPrisma.prisma = prisma;
|
||
globalForPrisma.prismaConfigSignature = prismaConfigSignature;
|
||
}
|