```
feat(resultStore): 支持数据库文件迁移和兼容性处理 - 添加对旧版 results.sqlite 到新版 results.db 的自动迁移支持 - 实现数据库连接时的错误处理和日志记录 - 修改数据库事务模式为 DELETE 模式以提高稳定性 - 增加对临时 WAL 和 SHM 文件的清理处理 - 提供环境变量配置的数据库路径优先级支持 ```
This commit is contained in:
@@ -1,15 +1,23 @@
|
||||
import Database from 'better-sqlite3';
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
||||
import {
|
||||
copyFileSync,
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
readFileSync,
|
||||
renameSync,
|
||||
unlinkSync,
|
||||
writeFileSync,
|
||||
} from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname, join } from 'path';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
const DB_PATH =
|
||||
process.env.APP_DB_PATH ||
|
||||
process.env.RESULTS_DB_PATH ||
|
||||
join(__dirname, '..', 'data', 'results.sqlite');
|
||||
const DEFAULT_DB_DIR = join(__dirname, '..', 'data');
|
||||
const DEFAULT_DB_PATH = join(DEFAULT_DB_DIR, 'results.db');
|
||||
const LEGACY_DB_PATH = join(DEFAULT_DB_DIR, 'results.sqlite');
|
||||
const DB_PATH = resolveDbPath();
|
||||
const CONFIG_PATH = join(__dirname, '..', 'config.json');
|
||||
const MAX_RESULT_RECORDS = 500;
|
||||
const DEFAULT_TASK_MODE = 'qwen3.5-plus';
|
||||
@@ -22,6 +30,55 @@ function clone(value) {
|
||||
return JSON.parse(JSON.stringify(value));
|
||||
}
|
||||
|
||||
function removeFileIfExists(filePath) {
|
||||
if (!existsSync(filePath)) return;
|
||||
unlinkSync(filePath);
|
||||
}
|
||||
|
||||
function migrateLegacyDbIfNeeded(nextPath, legacyPath) {
|
||||
if (existsSync(nextPath) || !existsSync(legacyPath)) return nextPath;
|
||||
|
||||
const legacyDb = new Database(legacyPath);
|
||||
|
||||
try {
|
||||
legacyDb.pragma('wal_checkpoint(TRUNCATE)');
|
||||
} catch (_error) {
|
||||
// Ignore checkpoint failures and still attempt to switch to single-file mode.
|
||||
}
|
||||
|
||||
legacyDb.pragma('journal_mode = DELETE');
|
||||
legacyDb.close();
|
||||
|
||||
try {
|
||||
renameSync(legacyPath, nextPath);
|
||||
} catch (_error) {
|
||||
copyFileSync(legacyPath, nextPath);
|
||||
}
|
||||
|
||||
removeFileIfExists(`${legacyPath}-shm`);
|
||||
removeFileIfExists(`${legacyPath}-wal`);
|
||||
|
||||
return nextPath;
|
||||
}
|
||||
|
||||
function resolveDbPath() {
|
||||
const explicitPath = process.env.APP_DB_PATH || process.env.RESULTS_DB_PATH;
|
||||
if (explicitPath) return explicitPath;
|
||||
|
||||
mkdirSync(DEFAULT_DB_DIR, { recursive: true });
|
||||
|
||||
try {
|
||||
return migrateLegacyDbIfNeeded(DEFAULT_DB_PATH, LEGACY_DB_PATH);
|
||||
} catch (error) {
|
||||
if (existsSync(LEGACY_DB_PATH)) {
|
||||
console.warn(`[resultStore] Legacy database migration skipped: ${error.message}`);
|
||||
return LEGACY_DB_PATH;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function generateResultId() {
|
||||
return `result-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
||||
}
|
||||
@@ -141,7 +198,13 @@ function getDb() {
|
||||
|
||||
mkdirSync(dirname(DB_PATH), { recursive: true });
|
||||
db = new Database(DB_PATH);
|
||||
db.pragma('journal_mode = WAL');
|
||||
|
||||
try {
|
||||
db.pragma('journal_mode = DELETE');
|
||||
} catch (error) {
|
||||
console.warn(`[resultStore] Database journal mode unchanged: ${error.message}`);
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user