XNSim/XNSimHtml/utils/db-utils.js

646 lines
20 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const Database = require('better-sqlite3');
const { getXNCorePath } = require('./file-utils');
// 查询ATAChapters表
function getATAChapters() {
try {
const xnCorePath = getXNCorePath();
if (!xnCorePath) {
throw new Error('XNCore环境变量未设置无法获取数据库路径');
}
const dbPath = xnCorePath + '/database/XNSim.db';
if (!dbPath) {
throw new Error('无法找到数据库文件');
}
// 打开数据库连接
const db = new Database(dbPath, { readonly: true });
// 直接使用ATAChapters表名查询
const chapters = db.prepare("SELECT ID, Name, Name_CN FROM 'ATAChapters' ORDER BY ID").all();
db.close();
return chapters;
} catch (error) {
console.error('获取ATA章节数据失败:', error.message);
throw error;
}
}
// 根据章节ID查询XNModels表中的模型
function getModelsByChapterId(chapterId, productName) {
try {
const xnCorePath = getXNCorePath();
if (!xnCorePath) {
throw new Error('XNCore环境变量未设置无法获取数据库路径');
}
const dbPath = xnCorePath + '/database/XNSim.db';
if (!dbPath) {
throw new Error('无法找到数据库文件');
}
// 打开数据库连接
const db = new Database(dbPath, { readonly: true });
// 根据productName是否为空构建不同的查询
let query;
let params;
if (!productName || productName === '' || productName === 'undefined') {
query = `
SELECT ProductName, Chapters_ID, ModelName, ModelName_CN, Description, ClassName
FROM 'XNModels'
WHERE Chapters_ID = ?
ORDER BY ModelName
`;
params = [chapterId];
} else {
query = `
SELECT ProductName, Chapters_ID, ModelName, ModelName_CN, Description, ClassName
FROM 'XNModels'
WHERE Chapters_ID = ? AND ProductName = ?
ORDER BY ModelName
`;
params = [chapterId, productName];
}
const models = db.prepare(query).all(...params);
db.close();
return models;
} catch (error) {
console.error(`获取章节${chapterId}的模型数据失败:`, error.message);
throw error;
}
}
// 根据ClassName查询XNModelsVersion表中的模型版本
function getModelVersionsByClassName(className, productName) {
try {
const xnCorePath = getXNCorePath();
if (!xnCorePath) {
throw new Error('XNCore环境变量未设置无法获取数据库路径');
}
const dbPath = xnCorePath + '/database/XNSim.db';
if (!dbPath) {
throw new Error('无法找到数据库文件');
}
// 打开数据库连接
const db = new Database(dbPath, { readonly: true });
// 根据productName是否为空构建不同的查询
let query;
let params;
if (!productName || productName === '') {
query = `
SELECT ProductName, ClassName, Name, Version, CodePath, Author, Description,
CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority,
DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName
FROM 'XNModelsVersion'
WHERE ClassName = ?
ORDER BY Version DESC
`;
params = [className];
} else {
query = `
SELECT ProductName, ClassName, Name, Version, CodePath, Author, Description,
CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority,
DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName
FROM 'XNModelsVersion'
WHERE ClassName = ? AND ProductName = ?
ORDER BY Version DESC
`;
params = [className, productName];
}
const versions = db.prepare(query).all(...params);
db.close();
return versions;
} catch (error) {
console.error(`获取模型${className}的版本数据失败:`, error.message);
throw error;
}
}
// 保存或更新模型版本信息
function saveModelVersion(versionData) {
try {
// 验证必填字段
const requiredFields = ['ClassName', 'Name', 'Version', 'Author', 'ProductName'];
for (const field of requiredFields) {
if (!versionData[field]) {
throw new Error(`${field} 是必填字段`);
}
}
const xnCorePath = getXNCorePath();
if (!xnCorePath) {
throw new Error('XNCore环境变量未设置无法获取数据库路径');
}
const dbPath = xnCorePath + '/database/XNSim.db';
if (!dbPath) {
throw new Error('无法找到数据库文件');
}
// 打开数据库连接
const db = new Database(dbPath);
// 检查是否为更新模式
if (versionData.isUpdate) {
// 查询是否存在要更新的版本
const existingVersion = db.prepare(`
SELECT COUNT(*) as count FROM 'XNModelsVersion'
WHERE ClassName = ? AND Version = ? AND ProductName = ?
`).get(versionData.ClassName, versionData.originalVersion || versionData.Version, versionData.ProductName);
if (existingVersion.count === 0) {
// 不存在要更新的版本,创建新版本
return saveNewVersion(db, versionData);
}
// 使用前端传来的修改时间,如果没有则生成当前时间
let changeTime = versionData.ChangeTime;
if (!changeTime) {
// 生成当前时间格式为YYYY-MM-DD HH:MM:SS
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
changeTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
// 更新现有版本
const updateResult = db.prepare(`
UPDATE 'XNModelsVersion'
SET
Name = ?,
Version = ?,
Author = ?,
Description = ?,
CodePath = ?,
ChangeTime = ?,
RunFreqGroup = ?,
RunNode = ?,
Priority = ?,
DataPackagePath = ?,
DataPackageHeaderPath = ?,
DataPackageEntryPoint = ?,
DataPackageInterfaceName = ?,
ProductName = ?
WHERE ClassName = ? AND Version = ? AND ProductName = ?
`).run(
versionData.Name,
versionData.Version,
versionData.Author,
versionData.Description || '',
versionData.CodePath || '',
changeTime,
versionData.RunFreqGroup || '',
versionData.RunNode || '',
versionData.Priority || '0',
versionData.DataPackagePath || '',
versionData.DataPackageHeaderPath || '',
versionData.DataPackageEntryPoint || '',
versionData.DataPackageInterfaceName || '',
versionData.ProductName,
versionData.ClassName,
versionData.originalVersion || versionData.Version,
versionData.ProductName
);
db.close();
return {
success: true,
isNew: false,
changes: updateResult.changes,
message: '模型版本更新成功'
};
} else {
// 创建新版本
return saveNewVersion(db, versionData);
}
} catch (error) {
console.error('保存模型版本时出错:', error);
throw error;
}
}
// 内部函数:保存新版本
function saveNewVersion(db, versionData) {
try {
// 检查版本是否已存在
const existingVersion = db.prepare(`
SELECT COUNT(*) as count FROM 'XNModelsVersion'
WHERE ClassName = ? AND Version = ? AND ProductName = ?
`).get(versionData.ClassName, versionData.Version, versionData.ProductName);
if (existingVersion.count > 0) {
db.close();
throw new Error(`版本 ${versionData.Version} 已存在,请使用其他版本号`);
}
// 生成当前时间格式为YYYY-MM-DD HH:MM:SS
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
// 使用前端传来的时间或生成的时间
const createTime = versionData.CreatTime || formattedDateTime;
const changeTime = versionData.ChangeTime || formattedDateTime;
// 插入新版本
const insertResult = db.prepare(`
INSERT INTO 'XNModelsVersion' (
ProductName, ClassName, Name, Version, CodePath, Author, Description,
CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority,
DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`).run(
versionData.ProductName,
versionData.ClassName,
versionData.Name,
versionData.Version,
versionData.CodePath || '',
versionData.Author,
versionData.Description || '',
createTime,
changeTime,
versionData.RunFreqGroup || '',
versionData.RunNode || '',
versionData.Priority || '0',
versionData.DataPackagePath || '',
versionData.DataPackageHeaderPath || '',
versionData.DataPackageEntryPoint || '',
versionData.DataPackageInterfaceName || ''
);
db.close();
return {
success: true,
isNew: true,
id: insertResult.lastInsertRowid,
message: '模型版本创建成功'
};
} catch (error) {
if (db) db.close();
console.error('创建模型版本失败:', error);
throw error;
}
}
// 查询XNServices表中的所有服务
function getServices() {
try {
const xnCorePath = getXNCorePath();
if (!xnCorePath) {
throw new Error('XNCore环境变量未设置无法获取数据库路径');
}
const dbPath = xnCorePath + '/database/XNSim.db';
if (!dbPath) {
throw new Error('无法找到数据库文件');
}
// 打开数据库连接
const db = new Database(dbPath, { readonly: true });
// 查询所有服务
const services = db.prepare(`
SELECT ServiceName, ServiceName_CN, Description, ClassName
FROM 'XNServices'
ORDER BY ServiceName
`).all();
db.close();
return services;
} catch (error) {
console.error('获取服务列表数据失败:', error.message);
throw error;
}
}
// 根据ClassName查询XNServiceVersion表中的服务版本
function getServiceVersionsByClassName(className) {
try {
const xnCorePath = getXNCorePath();
if (!xnCorePath) {
throw new Error('XNCore环境变量未设置无法获取数据库路径');
}
const dbPath = xnCorePath + '/database/XNSim.db';
if (!dbPath) {
throw new Error('无法找到数据库文件');
}
// 打开数据库连接
const db = new Database(dbPath, { readonly: true });
// 查询该类名下的所有版本
const versions = db.prepare(`
SELECT ClassName, Name, Version, CodePath, Author, Description,
CreatTime, ChangeTime
FROM 'XNServiceVersion'
WHERE ClassName = ?
ORDER BY Version DESC
`).all(className);
db.close();
return versions;
} catch (error) {
console.error(`获取服务${className}的版本数据失败:`, error.message);
throw error;
}
}
// 保存或更新服务版本信息
function saveServiceVersion(versionData) {
try {
// 验证必填字段
const requiredFields = ['ClassName', 'Name', 'Version', 'Author'];
for (const field of requiredFields) {
if (!versionData[field]) {
throw new Error(`${field} 是必填字段`);
}
}
const xnCorePath = getXNCorePath();
if (!xnCorePath) {
throw new Error('XNCore环境变量未设置无法获取数据库路径');
}
const dbPath = xnCorePath + '/database/XNSim.db';
if (!dbPath) {
throw new Error('无法找到数据库文件');
}
// 打开数据库连接
const db = new Database(dbPath);
// 检查是否为更新模式
if (versionData.isUpdate) {
// 查询是否存在要更新的版本
const existingVersion = db.prepare(`
SELECT COUNT(*) as count FROM 'XNServiceVersion'
WHERE ClassName = ? AND Version = ?
`).get(versionData.ClassName, versionData.originalVersion || versionData.Version);
if (existingVersion.count === 0) {
// 不存在要更新的版本,创建新版本
return saveNewServiceVersion(db, versionData);
}
// 使用前端传来的修改时间,如果没有则生成当前时间
let changeTime = versionData.ChangeTime;
if (!changeTime) {
// 生成当前时间格式为YYYY-MM-DD HH:MM:SS
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
changeTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
// 更新现有版本
const updateResult = db.prepare(`
UPDATE 'XNServiceVersion'
SET
Name = ?,
Version = ?,
Author = ?,
Description = ?,
CodePath = ?,
ChangeTime = ?
WHERE ClassName = ? AND Version = ?
`).run(
versionData.Name,
versionData.Version,
versionData.Author,
versionData.Description || '',
versionData.CodePath || '',
changeTime, // 使用前端传来的时间或生成的当前时间
versionData.ClassName,
versionData.originalVersion || versionData.Version
);
db.close();
return {
success: true,
isNew: false,
changes: updateResult.changes,
message: '服务版本更新成功'
};
} else {
// 创建新版本
return saveNewServiceVersion(db, versionData);
}
} catch (error) {
console.error('保存服务版本时出错:', error);
throw error;
}
}
// 内部函数:保存新的服务版本
function saveNewServiceVersion(db, versionData) {
try {
// 检查版本是否已存在
const existingVersion = db.prepare(`
SELECT COUNT(*) as count FROM 'XNServiceVersion'
WHERE ClassName = ? AND Version = ?
`).get(versionData.ClassName, versionData.Version);
if (existingVersion.count > 0) {
db.close();
throw new Error(`版本 ${versionData.Version} 已存在,请使用其他版本号`);
}
// 生成当前时间格式为YYYY-MM-DD HH:MM:SS
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
// 使用前端传来的时间或生成的时间
const createTime = versionData.CreatTime || formattedDateTime;
const changeTime = versionData.ChangeTime || formattedDateTime;
// 插入新版本
const insertResult = db.prepare(`
INSERT INTO 'XNServiceVersion' (
ClassName, Name, Version, CodePath, Author, Description,
CreatTime, ChangeTime
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
`).run(
versionData.ClassName,
versionData.Name,
versionData.Version,
versionData.CodePath || '',
versionData.Author,
versionData.Description || '',
createTime, // 使用前端传来的创建时间或生成的当前时间
changeTime // 使用前端传来的修改时间或生成的当前时间
);
db.close();
return {
success: true,
isNew: true,
id: insertResult.lastInsertRowid,
message: '服务版本创建成功'
};
} catch (error) {
if (db) db.close();
console.error('创建服务版本失败:', error);
throw error;
}
}
// 创建新服务
function createService(serviceData) {
try {
// 验证必填字段
const requiredFields = ['ClassName', 'ServiceName', 'ServiceName_CN'];
for (const field of requiredFields) {
if (!serviceData[field]) {
throw new Error(`${field} 是必填字段`);
}
}
// 验证类名是否以XN开头
if (!serviceData.ClassName.startsWith('XN')) {
throw new Error('服务类名必须以XN开头');
}
const xnCorePath = getXNCorePath();
if (!xnCorePath) {
throw new Error('XNCore环境变量未设置无法获取数据库路径');
}
const dbPath = xnCorePath + '/database/XNSim.db';
if (!dbPath) {
throw new Error('无法找到数据库文件');
}
// 打开数据库连接
const db = new Database(dbPath);
// 检查服务类名是否已存在
const existingService = db.prepare(`
SELECT COUNT(*) as count FROM 'XNServices'
WHERE ClassName = ?
`).get(serviceData.ClassName);
if (existingService.count > 0) {
db.close();
throw new Error(`服务类名 ${serviceData.ClassName} 已存在,请使用其他类名`);
}
// 检查服务名称是否已存在
const existingServiceName = db.prepare(`
SELECT COUNT(*) as count FROM 'XNServices'
WHERE ServiceName = ?
`).get(serviceData.ServiceName);
if (existingServiceName.count > 0) {
db.close();
throw new Error(`服务名称 ${serviceData.ServiceName} 已存在,请使用其他名称`);
}
// 插入新服务
const insertResult = db.prepare(`
INSERT INTO 'XNServices' (
ClassName, ServiceName, ServiceName_CN, Description
) VALUES (?, ?, ?, ?)
`).run(
serviceData.ClassName,
serviceData.ServiceName,
serviceData.ServiceName_CN,
serviceData.Description || ''
);
db.close();
return {
success: true,
id: insertResult.lastInsertRowid,
message: '服务创建成功'
};
} catch (error) {
console.error('创建服务失败:', error);
throw error;
}
}
// 查询Products表中的所有产品
function getProducts() {
try {
const xnCorePath = getXNCorePath();
if (!xnCorePath) {
throw new Error('XNCore环境变量未设置无法获取数据库路径');
}
const dbPath = xnCorePath + '/database/XNSim.db';
if (!dbPath) {
throw new Error('无法找到数据库文件');
}
// 打开数据库连接
const db = new Database(dbPath, { readonly: true });
// 查询所有产品
const products = db.prepare(`
SELECT ProductName, Description
FROM 'Products'
ORDER BY ProductName
`).all();
db.close();
return products;
} catch (error) {
console.error('获取产品列表数据失败:', error.message);
throw error;
}
}
module.exports = {
getATAChapters,
getModelsByChapterId,
getModelVersionsByClassName,
saveModelVersion,
getServices,
getServiceVersionsByClassName,
saveServiceVersion,
createService,
getProducts
};