electron-vue-exam-single/electron/db/index.js

425 lines
16 KiB
JavaScript

// 将 CommonJS 导入改为 ES 模块导入(注意添加 .js 扩展名)
import { getSystemDbPath, getUserDbPath } from './path.js';
import { systemSchema, userSchema, defaultData } from './schema.js';
import { openDatabase, batchInsert } from './utils.js';
import * as argon2 from "argon2";
// 数据库连接池
const dbConnections = new Map();
// 获取数据库连接
export async function getDbConnection(dbPath) {
if (dbConnections.has(dbPath)) {
console.log(`使用现有数据库连接: ${dbPath}`);
return dbConnections.get(dbPath);
}
const db = await openDatabase(dbPath);
dbConnections.set(dbPath, db);
return db;
}
// 关闭所有数据库连接
export function closeAllConnections() {
dbConnections.forEach((db, path) => {
try {
db.close();
console.log(`关闭数据库连接: ${path}`);
} catch (error) {
console.error(`关闭数据库连接失败: ${path}`, error);
}
});
dbConnections.clear();
}
// 检查数据库是否已初始化
export async function checkDatabaseInitialized() {
try {
console.log('开始检查数据库初始化状态...');
const systemDb = await getDbConnection(getSystemDbPath());
console.log('成功打开系统数据库');
const result = await systemDb.getAsync('SELECT value FROM config WHERE key = ?', ['initialized']);
console.log('查询初始化状态结果:', result);
const isInitialized = result && result.value === 'true';
console.log('数据库初始化状态:', isInitialized ? '已初始化' : '未初始化');
return isInitialized;
} catch (error) {
console.error('检查数据库初始化状态失败:', error);
return false;
}
}
// 初始化系统数据库
async function initializeSystemDatabase() {
console.log('开始初始化系统数据库...');
const systemDbPath = getSystemDbPath();
const systemDb = await getDbConnection(systemDbPath);
// 记录成功和失败的操作
const results = { success: [], failed: [] };
// 创建表结构
console.log('开始创建系统数据库表结构...');
// 创建config表
try {
await systemDb.execAsync(systemSchema.config.trim());
console.log('创建 config 表成功');
results.success.push('创建 config 表');
} catch (error) {
console.error('创建 config 表失败:', error);
results.failed.push({ operation: '创建 config 表', error: error.message });
}
// 创建dict_types表
try {
await systemDb.execAsync(systemSchema.dictTypes.trim());
console.log('创建 dict_types 表成功');
results.success.push('创建 dict_types 表');
} catch (error) {
console.error('创建 dict_types 表失败:', error);
results.failed.push({ operation: '创建 dict_types 表', error: error.message });
}
// 创建dict_items表
try {
await systemDb.execAsync(systemSchema.dictItems.trim());
console.log('创建 dict_items 表成功');
results.success.push('创建 dict_items 表');
} catch (error) {
console.error('创建 dict_items 表失败:', error);
results.failed.push({ operation: '创建 dict_items 表', error: error.message });
}
// 创建questions表
try {
await systemDb.execAsync(systemSchema.questions.trim());
console.log('创建 questions 表成功');
results.success.push('创建 questions 表');
} catch (error) {
console.error('创建 questions 表失败:', error);
results.failed.push({ operation: '创建 questions 表', error: error.message });
}
// 创建question_datasets表
try {
await systemDb.execAsync(systemSchema.questionDatasets.trim());
console.log('创建 question_datasets 表成功');
results.success.push('创建 question_datasets 表');
} catch (error) {
console.error('创建 question_datasets 表失败:', error);
results.failed.push({ operation: '创建 question_datasets 表', error: error.message });
}
// 创建question_images表
try {
await systemDb.execAsync(systemSchema.questionImages.trim());
console.log('创建 question_images 表成功');
results.success.push('创建 question_images 表');
} catch (error) {
console.error('创建 question_images 表失败:', error);
results.failed.push({ operation: '创建 question_images 表', error: error.message });
}
// 创建question_fill_table表
try {
await systemDb.execAsync(systemSchema.questionFillTable.trim());
console.log('创建 question_fill_table 表成功');
results.success.push('创建 question_fill_table 表');
} catch (error) {
console.error('创建 question_fill_table 表失败:', error);
results.failed.push({ operation: '创建 question_fill_table 表', error: error.message });
}
// 创建question_fill_table_blanks表
try {
await systemDb.execAsync(systemSchema.questionFillTableBlanks.trim());
console.log('创建 question_fill_table_blanks 表成功');
results.success.push('创建 question_fill_table_blanks 表');
} catch (error) {
console.error('创建 question_fill_table_blanks 表失败:', error);
results.failed.push({ operation: '创建 question_fill_table_blanks 表', error: error.message });
}
// 创建question_choices表
try {
await systemDb.execAsync(systemSchema.questionChoices.trim());
console.log('创建 question_choices 表成功');
results.success.push('创建 question_choices 表');
} catch (error) {
console.error('创建 question_choices 表失败:', error);
results.failed.push({ operation: '创建 question_choices 表', error: error.message });
}
// 创建question_fill_blanks表
try {
await systemDb.execAsync(systemSchema.questionFillBlanks.trim());
console.log('创建 question_fill_blanks 表成功');
results.success.push('创建 question_fill_blanks 表');
} catch (error) {
console.error('创建 question_fill_blanks 表失败:', error);
results.failed.push({ operation: '创建 question_fill_blanks 表', error: error.message });
}
// 创建question_judge表
try {
await systemDb.execAsync(systemSchema.questionJudge.trim());
console.log('创建 question_judge 表成功');
results.success.push('创建 question_judge 表');
} catch (error) {
console.error('创建 question_judge 表失败:', error);
results.failed.push({ operation: '创建 question_judge 表', error: error.message });
}
// 创建question_short表
try {
await systemDb.execAsync(systemSchema.questionShort.trim());
console.log('创建 question_short 表成功');
results.success.push('创建 question_short 表');
} catch (error) {
console.error('创建 question_short 表失败:', error);
results.failed.push({ operation: '创建 question_short 表', error: error.message });
}
// 创建exam表
try {
await systemDb.execAsync(systemSchema.exam.trim());
console.log('创建 exam 表成功');
results.success.push('创建 exam 表');
} catch (error) {
console.error('创建 exam 表失败:', error);
results.failed.push({ operation: '创建 exam 表', error: error.message });
}
// 创建examinee表
try {
await systemDb.execAsync(systemSchema.examinee.trim());
console.log('创建 examinee 表成功');
results.success.push('创建 examinee 表');
} catch (error) {
console.error('创建 examinee 表失败:', error);
results.failed.push({ operation: '创建 examinee 表', error: error.message });
}
// 插入默认数据
console.log('开始插入默认数据...');
// 处理密码哈希
try {
const plainPassword = defaultData.config.find(item => item.key === 'admin_password').value;
const hashedPassword = await argon2.hash(plainPassword);
// 更新密码为哈希值
const configData = defaultData.config.map(item => {
if (item.key === 'admin_password') {
return { ...item, value: hashedPassword };
}
return item;
});
// 插入config表数据
try {
await batchInsert(systemDb, 'config', configData);
console.log('插入 config 表数据成功');
results.success.push('插入 config 表数据');
} catch (error) {
console.error('插入 config 表数据失败:', error);
results.failed.push({ operation: '插入 config 表数据', error: error.message });
}
} catch (error) {
console.error('处理密码哈希失败:', error);
results.failed.push({ operation: '处理密码哈希', error: error.message });
}
// 插入dict_types表数据
try {
await batchInsert(systemDb, 'dict_types', defaultData.dictTypes);
console.log('插入 dict_types 表数据成功');
results.success.push('插入 dict_types 表数据');
} catch (error) {
console.error('插入 dict_types 表数据失败:', error);
results.failed.push({ operation: '插入 dict_types 表数据', error: error.message });
}
// 插入dict_items表数据
try {
await batchInsert(systemDb, 'dict_items', defaultData.dictItems);
console.log('插入 dict_items 表数据成功');
results.success.push('插入 dict_items 表数据');
} catch (error) {
console.error('插入 dict_items 表数据失败:', error);
results.failed.push({ operation: '插入 dict_items 表数据', error: error.message });
}
console.log('系统数据库初始化结果:');
console.log('成功操作:', results.success);
console.log('失败操作:', results.failed);
// 如果有失败操作,抛出错误
if (results.failed.length > 0) {
console.log(`系统数据库初始化有 ${results.failed.length} 个操作失败,请查看日志`);
// 输出详细的失败信息
results.failed.forEach((item, index) => {
console.log(`${index + 1}. ${item.operation} 失败: ${item.error}`);
});
}
return true;
}
// 初始化用户数据库
async function initializeUserDatabase() {
console.log('开始初始化用户数据库...');
const userDbPath = getUserDbPath();
const userDb = await getDbConnection(userDbPath);
// 记录成功和失败的操作
const results = { success: [], failed: [] };
// 创建表结构
console.log('开始创建用户数据库表结构...');
// 创建examinee表
try {
await userDb.execAsync(userSchema.examinee.trim());
console.log('创建 examinee 表成功');
results.success.push('创建 examinee 表');
} catch (error) {
console.error('创建 examinee 表失败:', error);
results.failed.push({ operation: '创建 examinee 表', error: error.message });
}
// 创建examinee_papers表
try {
await userDb.execAsync(userSchema.examinee_papers.trim());
console.log('创建 examinee_papers 表成功');
results.success.push('创建 examinee_papers 表');
} catch (error) {
console.error('创建 examinee_papers 表失败:', error);
results.failed.push({ operation: '创建 examinee_papers 表', error: error.message });
}
// 创建paper_questions表
try {
await userDb.execAsync(userSchema.paper_questions.trim());
console.log('创建 paper_questions 表成功');
results.success.push('创建 paper_questions 表');
} catch (error) {
console.error('创建 paper_questions 表失败:', error);
results.failed.push({ operation: '创建 paper_questions 表', error: error.message });
}
// 创建question_datasets表
try {
await userDb.execAsync(userSchema.question_datasets.trim());
console.log('创建 question_datasets 表成功');
results.success.push('创建 question_datasets 表');
} catch (error) {
console.error('创建 question_datasets 表失败:', error);
results.failed.push({ operation: '创建 question_datasets 表', error: error.message });
}
// 创建question_images表
try {
await userDb.execAsync(userSchema.question_images.trim());
console.log('创建 question_images 表成功');
results.success.push('创建 question_images 表');
} catch (error) {
console.error('创建 question_images 表失败:', error);
results.failed.push({ operation: '创建 question_images 表', error: error.message });
}
// 创建question_choices表
try {
await userDb.execAsync(userSchema.question_choices.trim());
console.log('创建 question_choices 表成功');
results.success.push('创建 question_choices 表');
} catch (error) {
console.error('创建 question_choices 表失败:', error);
results.failed.push({ operation: '创建 question_choices 表', error: error.message });
}
// 创建question_fill_blanks表
try {
await userDb.execAsync(userSchema.question_fill_blanks.trim());
console.log('创建 question_fill_blanks 表成功');
results.success.push('创建 question_fill_blanks 表');
} catch (error) {
console.error('创建 question_fill_blanks 表失败:', error);
results.failed.push({ operation: '创建 question_fill_blanks 表', error: error.message });
}
console.log('用户数据库初始化结果:');
console.log('成功操作:', results.success);
console.log('失败操作:', results.failed);
// 如果有失败操作,仅打印错误信息,不抛出异常
if (results.failed.length > 0) {
console.error(`用户数据库初始化有 ${results.failed.length} 个操作失败,请查看日志`);
// 输出详细的失败信息
results.failed.forEach((item, index) => {
console.error(`${index + 1}. ${item.operation} 失败: ${item.error}`);
});
}
return true;
}
// 初始化数据库
export async function initializeDatabase() {
try {
console.log('开始初始化数据库...');
// 确保只有一个初始化请求在执行
if (global.isInitializing) {
console.log('数据库初始化已在进行中,等待完成...');
while (global.isInitializing) {
await new Promise(resolve => setTimeout(resolve, 100));
}
return global.initResult;
}
global.isInitializing = true;
global.initResult = false;
// 先初始化系统数据库
console.log('开始初始化系统数据库...');
const systemResult = await initializeSystemDatabase();
console.log('系统数据库初始化结果:', systemResult ? '成功' : '失败');
if (!systemResult) {
throw new Error('系统数据库初始化失败');
}
// 再初始化用户数据库
console.log('开始初始化用户数据库...');
const userResult = await initializeUserDatabase();
console.log('用户数据库初始化结果:', userResult ? '成功' : '失败');
if (!userResult) {
throw new Error('用户数据库初始化失败');
}
// 更新初始化状态
console.log('更新数据库初始化状态...');
const systemDb = await getDbConnection(getSystemDbPath());
await systemDb.runAsync('UPDATE config SET value = ? WHERE key = ?', ['true', 'initialized']);
console.log('数据库初始化状态更新成功');
console.log('数据库整体初始化成功');
global.initResult = true;
return true;
} catch (error) {
console.error('数据库初始化失败:', error);
global.initResult = false;
return false;
} finally {
global.isInitializing = false;
}
}
// 应用退出时关闭所有连接
process.on('exit', closeAllConnections);