From 7535f77eaab9a4271257f128871078db396b3cc8 Mon Sep 17 00:00:00 2001 From: digua Date: Mon, 11 May 2026 19:56:14 +0800 Subject: [PATCH] feat(node-runtime): add DatabaseManager for session DB lifecycle Phase 1.7: add DatabaseManager to @openchatlab/node-runtime that handles opening, caching, listing, and closing chat session databases using the DatabaseAdapter and PathProvider interfaces from core. --- packages/node-runtime/src/database-manager.ts | 83 +++++++++++++++++++ packages/node-runtime/src/index.ts | 3 +- 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 packages/node-runtime/src/database-manager.ts diff --git a/packages/node-runtime/src/database-manager.ts b/packages/node-runtime/src/database-manager.ts new file mode 100644 index 00000000..3afeefb6 --- /dev/null +++ b/packages/node-runtime/src/database-manager.ts @@ -0,0 +1,83 @@ +/** + * 数据库连接管理器 + * + * 管理 ChatLab 会话数据库的打开、缓存与关闭。 + * 等效于 electron/main/worker/core/dbCore.ts 中的 dbCache 机制, + * 但基于 DatabaseAdapter 接口而非直接使用 better-sqlite3。 + */ + +import * as fs from 'fs' +import * as path from 'path' +import type { DatabaseAdapter, PathProvider } from '@openchatlab/core' +import { isChatSessionDb } from '@openchatlab/core' +import { openBetterSqliteDatabase } from './better-sqlite3-adapter' + +export class DatabaseManager { + private cache = new Map() + + constructor(private pathProvider: PathProvider) {} + + /** + * 打开指定会话的数据库(带缓存) + */ + open(sessionId: string, options?: { readonly?: boolean }): DatabaseAdapter | null { + if (this.cache.has(sessionId)) { + return this.cache.get(sessionId)! + } + + const dbPath = this.getDbPath(sessionId) + if (!fs.existsSync(dbPath)) return null + + const adapter = openBetterSqliteDatabase(dbPath, { + readonly: options?.readonly ?? true, + }) + this.cache.set(sessionId, adapter) + return adapter + } + + /** + * 关闭指定会话的数据库连接 + */ + close(sessionId: string): void { + const adapter = this.cache.get(sessionId) + if (adapter) { + adapter.close() + this.cache.delete(sessionId) + } + } + + /** + * 关闭所有数据库连接 + */ + closeAll(): void { + for (const [id, adapter] of this.cache) { + adapter.close() + this.cache.delete(id) + } + } + + /** + * 列举数据库目录下的所有聊天会话 ID + */ + listSessionIds(): string[] { + const dbDir = this.pathProvider.getDatabaseDir() + if (!fs.existsSync(dbDir)) return [] + + return fs + .readdirSync(dbDir) + .filter((f) => f.endsWith('.db')) + .map((f) => f.replace('.db', '')) + .filter((id) => { + const db = this.open(id) + if (!db) return false + return isChatSessionDb(db) + }) + } + + /** + * 获取数据库文件路径 + */ + getDbPath(sessionId: string): string { + return path.join(this.pathProvider.getDatabaseDir(), `${sessionId}.db`) + } +} diff --git a/packages/node-runtime/src/index.ts b/packages/node-runtime/src/index.ts index f6c239e0..d3d162ca 100644 --- a/packages/node-runtime/src/index.ts +++ b/packages/node-runtime/src/index.ts @@ -2,8 +2,9 @@ * @openchatlab/node-runtime * * Node.js 运行时适配器,提供 better-sqlite3 数据库适配器、 - * 路径管理等平台特定实现。 + * 路径管理、数据库连接管理等平台特定实现。 */ export { BetterSqliteAdapter, openBetterSqliteDatabase } from './better-sqlite3-adapter' export { NodePathProvider } from './node-path-provider' +export { DatabaseManager } from './database-manager'