394 lines
14 KiB
JavaScript
394 lines
14 KiB
JavaScript
const { getSystemDbPath, getUserDbPath } = require('./path.js');
|
||
const { systemSchema, userSchema, defaultData } = require('./schema.js');
|
||
const { openDatabase, batchInsert } = require('./utils.js');
|
||
const bcrypt = require('bcryptjs');
|
||
const { configDataSql } = require('./systemdata/configData.js');
|
||
const { dictItemsDataSql } = require('./systemdata/dictItemsData.js');
|
||
const { dictTypesDataSql } = require('./systemdata/dictTypesData.js');
|
||
const { examDataSql } = require('./systemdata/examData.js');
|
||
const { examineeDataSql } = require('./systemdata/examineeData.js');
|
||
const { questionChoicesDataSql } = require('./systemdata/questionChoicesData.js');
|
||
const { questionImagesDataSql } = require('./systemdata/questionImagesData.js');
|
||
const { questionsDataSql } = require('./systemdata/questionsData.js');
|
||
const { questionFillBlanksDataSql } = require('./systemdata/questionFillBlanksData.js');
|
||
|
||
// 数据库连接池
|
||
const dbConnections = new Map();
|
||
|
||
// 获取数据库连接
|
||
exports.getDbConnection = 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;
|
||
};
|
||
|
||
// 关闭所有数据库连接
|
||
exports.closeAllConnections = function closeAllConnections() {
|
||
dbConnections.forEach((db, path) => {
|
||
try {
|
||
db.close();
|
||
console.log(`关闭数据库连接: ${path}`);
|
||
} catch (error) {
|
||
console.error(`关闭数据库连接失败: ${path}`, error);
|
||
}
|
||
});
|
||
dbConnections.clear();
|
||
};
|
||
|
||
// 检查数据库是否已初始化
|
||
exports.checkDatabaseInitialized = async function checkDatabaseInitialized() {
|
||
try {
|
||
console.log('开始检查数据库初始化状态...');
|
||
const systemDb = await exports.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 exports.getDbConnection(systemDbPath);
|
||
|
||
// 创建表结构
|
||
console.log('开始创建系统数据库表结构...');
|
||
|
||
// 创建config表
|
||
try {
|
||
await systemDb.execAsync(systemSchema.config.trim());
|
||
console.log('创建 config 表成功');
|
||
} catch (error) {
|
||
console.error('创建 config 表失败:', error);
|
||
}
|
||
|
||
// 创建dict_types表 - 修正为驼峰命名
|
||
try {
|
||
await systemDb.execAsync(systemSchema.dictTypes.trim());
|
||
console.log('创建 dictTypes 表成功');
|
||
} catch (error) {
|
||
console.error('创建 dictTypes 表失败:', error);
|
||
}
|
||
|
||
// 创建dict_items表 - 修正为驼峰命名
|
||
try {
|
||
await systemDb.execAsync(systemSchema.dictItems.trim());
|
||
console.log('创建 dictItems 表成功');
|
||
} catch (error) {
|
||
console.error('创建 dictItems 表失败:', error);
|
||
}
|
||
|
||
// 创建questions表
|
||
try {
|
||
await systemDb.execAsync(systemSchema.questions.trim());
|
||
console.log('创建 questions 表成功');
|
||
} catch (error) {
|
||
console.error('创建 questions 表失败:', error);
|
||
}
|
||
|
||
// 创建question_datasets表 - 修正为驼峰命名
|
||
try {
|
||
await systemDb.execAsync(systemSchema.questionDatasets.trim());
|
||
console.log('创建 questionDatasets 表成功');
|
||
} catch (error) {
|
||
console.error('创建 questionDatasets 表失败:', error);
|
||
}
|
||
|
||
// 创建question_images表 - 修正为驼峰命名
|
||
try {
|
||
await systemDb.execAsync(systemSchema.questionImages.trim());
|
||
console.log('创建 questionImages 表成功');
|
||
} catch (error) {
|
||
console.error('创建 questionImages 表失败:', error);
|
||
}
|
||
|
||
// 创建question_fill_table表 - 修正为驼峰命名
|
||
try {
|
||
await systemDb.execAsync(systemSchema.questionFillTable.trim());
|
||
console.log('创建 questionFillTable 表成功');
|
||
} catch (error) {
|
||
console.error('创建 questionFillTable 表失败:', error);
|
||
}
|
||
|
||
// 创建question_fill_table_blanks表 - 修正为驼峰命名
|
||
try {
|
||
await systemDb.execAsync(systemSchema.questionFillTableBlanks.trim());
|
||
console.log('创建 questionFillTableBlanks 表成功');
|
||
} catch (error) {
|
||
console.error('创建 questionFillTableBlanks 表失败:', error);
|
||
}
|
||
|
||
// 创建question_choices表 - 修正为驼峰命名
|
||
try {
|
||
await systemDb.execAsync(systemSchema.questionChoices.trim());
|
||
console.log('创建 questionChoices 表成功');
|
||
} catch (error) {
|
||
console.error('创建 questionChoices 表失败:', error);
|
||
}
|
||
|
||
// 创建question_fill_blanks表 - 修正为驼峰命名
|
||
try {
|
||
await systemDb.execAsync(systemSchema.questionFillBlanks.trim());
|
||
console.log('创建 questionFillBlanks 表成功');
|
||
} catch (error) {
|
||
console.error('创建 questionFillBlanks 表失败:', error);
|
||
}
|
||
|
||
// 创建question_judge表 - 修正为驼峰命名
|
||
try {
|
||
await systemDb.execAsync(systemSchema.questionJudge.trim());
|
||
console.log('创建 questionJudge 表成功');
|
||
} catch (error) {
|
||
console.error('创建 questionJudge 表失败:', error);
|
||
}
|
||
|
||
// 创建question_short表 - 修正为驼峰命名
|
||
try {
|
||
await systemDb.execAsync(systemSchema.questionShort.trim());
|
||
console.log('创建 questionShort 表成功');
|
||
} catch (error) {
|
||
console.error('创建 questionShort 表失败:', error);
|
||
}
|
||
|
||
// 创建exam表
|
||
try {
|
||
await systemDb.execAsync(systemSchema.exam.trim());
|
||
console.log('创建 exam 表成功');
|
||
} catch (error) {
|
||
console.error('创建 exam 表失败:', error);
|
||
}
|
||
|
||
// 创建examinee表(系统库中的考生表)
|
||
try {
|
||
await systemDb.execAsync(systemSchema.examinee.trim());
|
||
console.log('创建 examinee 表成功');
|
||
} catch (error) {
|
||
console.error('创建 examinee 表失败:', error);
|
||
}
|
||
|
||
/// TODO: 初始化config表数据
|
||
try {
|
||
console.log('开始初始化config表数据...');
|
||
await systemDb.runAsync(configDataSql);
|
||
console.log('初始化config表数据成功');
|
||
} catch (error) {
|
||
console.error('初始化config表数据失败:', error);
|
||
}
|
||
// 初始化dict_types表数据
|
||
try {
|
||
console.log('开始初始化dict_types表数据...');
|
||
await systemDb.runAsync(dictTypesDataSql);
|
||
console.log('初始化dict_types表数据成功');
|
||
} catch (error) {
|
||
console.error('初始化dict_types表数据失败:', error);
|
||
}
|
||
// 初始化dict_items表数据
|
||
try {
|
||
console.log('开始初始化dict_items表数据...');
|
||
await systemDb.runAsync(dictItemsDataSql);
|
||
console.log('初始化dict_items表数据成功');
|
||
} catch (error) {
|
||
console.error('初始化dict_items表数据失败:', error);
|
||
}
|
||
// 初始化questions表数据
|
||
try {
|
||
console.log('开始初始化questions表数据...');
|
||
await systemDb.runAsync(questionsDataSql);
|
||
console.log('初始化questions表数据成功');
|
||
} catch (error) {
|
||
console.error('初始化questions表数据失败:', error);
|
||
}
|
||
// 初始化question_fill_blanks表数据
|
||
try {
|
||
console.log('开始初始化question_fill_blanks表数据...');
|
||
await systemDb.runAsync(questionFillBlanksDataSql);
|
||
console.log('初始化question_fill_blanks表数据成功');
|
||
} catch (error) {
|
||
console.error('初始化question_fill_blanks表数据失败:', error);
|
||
}
|
||
// 初始化question_images表数据
|
||
try {
|
||
console.log('开始初始化question_images表数据...');
|
||
await systemDb.runAsync(questionImagesDataSql);
|
||
console.log('初始化question_images表数据成功');
|
||
} catch (error) {
|
||
console.error('初始化question_images表数据失败:', error);
|
||
}
|
||
// 初始化question_choices表数据
|
||
try {
|
||
console.log('开始初始化question_choices表数据...');
|
||
await systemDb.runAsync(questionChoicesDataSql);
|
||
console.log('初始化question_choices表数据成功');
|
||
} catch (error) {
|
||
console.error('初始化question_choices表数据失败:', error);
|
||
}
|
||
// 初始化exam表数据
|
||
try {
|
||
console.log('开始初始化exam表数据...');
|
||
await systemDb.runAsync(examDataSql);
|
||
console.log('初始化exam表数据成功');
|
||
} catch (error) {
|
||
console.error('初始化exam表数据失败:', error);
|
||
}
|
||
// 初始化examinee表数据
|
||
try {
|
||
console.log('开始初始化examinee表数据...');
|
||
await systemDb.runAsync(examineeDataSql);
|
||
console.log('初始化examinee表数据成功');
|
||
} catch (error) {
|
||
console.error('初始化examinee表数据失败:', error);
|
||
}
|
||
|
||
|
||
return { success: true };
|
||
};
|
||
|
||
// 初始化用户数据库 - 注意这里使用了exports导出
|
||
exports.initializeUserDatabase = async function initializeUserDatabase() {
|
||
console.log('开始初始化用户数据库...');
|
||
const userDbPath = getUserDbPath();
|
||
const userDb = await exports.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.length);
|
||
console.log('失败操作:', results.failed.length);
|
||
if (results.failed.length > 0) {
|
||
console.error('部分操作失败:', results.failed);
|
||
}
|
||
|
||
return { success: true, results };
|
||
};
|
||
|
||
// 初始化数据库
|
||
exports.initializeDatabase = async function initializeDatabase() {
|
||
// 防止并发初始化
|
||
if (global.isInitializing) {
|
||
console.log('数据库初始化正在进行中,请勿重复触发');
|
||
return { success: false, message: '数据库初始化正在进行中' };
|
||
}
|
||
global.isInitializing = true;
|
||
|
||
try {
|
||
// 初始化系统数据库
|
||
console.log('开始数据库整体初始化...');
|
||
const systemResult = await initializeSystemDatabase();
|
||
if (!systemResult.success) {
|
||
throw new Error('系统数据库初始化失败');
|
||
}
|
||
|
||
// 初始化用户数据库
|
||
const userResult = await exports.initializeUserDatabase();
|
||
if (!userResult.success) {
|
||
throw new Error('用户数据库初始化失败');
|
||
}
|
||
|
||
// 更新初始化状态
|
||
console.log('更新数据库初始化状态...');
|
||
const systemDb = await exports.getDbConnection(getSystemDbPath());
|
||
await systemDb.runAsync('UPDATE config SET value = ? WHERE key = ?', ['true', 'initialized']);
|
||
console.log('数据库初始化状态更新成功');
|
||
|
||
console.log('数据库整体初始化成功');
|
||
global.initResult = true;
|
||
return { success: true };
|
||
} catch (error) {
|
||
console.error('数据库初始化失败:', error);
|
||
global.initResult = false;
|
||
return { success: false, error: error.message };
|
||
} finally {
|
||
global.isInitializing = false;
|
||
}
|
||
};
|
||
|
||
// 应用退出时关闭所有连接
|
||
process.on('exit', exports.closeAllConnections); |