import { mkdirSync, existsSync } from 'node:fs' import { join, resolve } from 'node:path' import Database from 'better-sqlite3' import { drizzle, type BetterSQLite3Database } from 'drizzle-orm/better-sqlite3' import { migrate } from 'drizzle-orm/better-sqlite3/migrator' import * as schema from '../db/schema' export { schema } export const tables = schema let _db: BetterSQLite3Database | null = null export function dataDir() { // 运行时读取环境变量(runtimeConfig 的默认值在构建时就已固定) const dir = resolve(process.env.NOVEL_DATA_DIR || useRuntimeConfig().dataDir || './data') if (!existsSync(dir)) mkdirSync(dir, { recursive: true }) return dir } function migrationsFolder() { const candidates = [ resolve(process.cwd(), 'server/db/migrations'), resolve(process.cwd(), '../server/db/migrations') ] const found = candidates.find(p => existsSync(join(p, 'meta', '_journal.json'))) if (!found) throw new Error('找不到数据库迁移目录 server/db/migrations,请在项目根目录启动应用') return found } export function useDb() { if (_db) return _db const sqlite = new Database(join(dataDir(), 'app.db')) sqlite.pragma('journal_mode = WAL') sqlite.pragma('foreign_keys = ON') _db = drizzle({ client: sqlite, schema }) migrate(_db, { migrationsFolder: migrationsFolder() }) return _db }