76 lines
2.6 KiB
JavaScript
76 lines
2.6 KiB
JavaScript
import { createRequire } from 'node:module';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const mysql2Version = require('mysql2/package.json').version;
|
|
|
|
export const MYSQL2_EXPORTER_METADATA = Object.freeze({
|
|
name: 'mysql2-show-create',
|
|
version: '1.0.0',
|
|
driverName: 'mysql2',
|
|
driverVersion: mysql2Version,
|
|
});
|
|
|
|
export const DEFAULT_EXPORT_LIMITS = Object.freeze({
|
|
connectTimeoutMs: 5_000,
|
|
queryTimeoutMs: 5_000,
|
|
totalTimeoutMs: 30_000,
|
|
maxObjects: 5_000,
|
|
maxDefinitionBytes: 1_048_576,
|
|
});
|
|
|
|
export class SchemaExportError extends Error {
|
|
constructor(code, message) {
|
|
super(message);
|
|
this.name = 'SchemaExportError';
|
|
this.code = code;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 配置在 Schema 治理入口已完成 development、主机白名单和固定库名校验;这里仅映射
|
|
* 连接所需字段,固定禁用多语句以防止未来元数据查询被拼接为任意 SQL。
|
|
*/
|
|
export function buildConnectionOptions(config) {
|
|
return {
|
|
host: config.MYSQL_HOST,
|
|
port: Number(config.MYSQL_PORT),
|
|
user: config.MYSQL_USERNAME,
|
|
password: config.MYSQL_PASSWORD,
|
|
database: config.MYSQL_DATABASE,
|
|
charset: 'utf8mb4',
|
|
timezone: '+08:00',
|
|
connectTimeout: DEFAULT_EXPORT_LIMITS.connectTimeoutMs,
|
|
multipleStatements: false,
|
|
enableKeepAlive: true,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 元数据对象名仍需防御性转义,避免控制字符破坏 `SHOW CREATE` 查询边界;名称不合法时
|
|
* 不回显输入,确保异常路径不会把潜在敏感值写入日志。
|
|
*/
|
|
export function quoteIdentifier(identifier) {
|
|
if (typeof identifier !== 'string' || identifier.length === 0 || /[\u0000-\u001F\u007F]/.test(identifier)) {
|
|
throw new SchemaExportError('INVALID_IDENTIFIER', 'Schema 标识符不能为空且不得包含控制字符');
|
|
}
|
|
|
|
return `\`${identifier.replaceAll('`', '``')}\``;
|
|
}
|
|
|
|
/**
|
|
* 导出器只接受项目数据库兼容基线,拒绝 MariaDB 和 MySQL 5.7 之外的服务器,避免相同
|
|
* `SHOW CREATE` 文本在不兼容语义下被误认为可恢复的 Schema 快照。
|
|
*/
|
|
export function assertMysql57ServerMetadata(metadata) {
|
|
const serverVersion = metadata?.serverVersion ?? '';
|
|
if (!/^5\.7\.\d+(?:[-+].*)?$/.test(serverVersion) || /mariadb/i.test(serverVersion)) {
|
|
throw new SchemaExportError('UNSUPPORTED_SERVER_VERSION', 'MySQL 服务端必须为 5.7.x');
|
|
}
|
|
if (metadata.databaseCharset !== 'utf8mb4') {
|
|
throw new SchemaExportError('INVALID_DATABASE_CHARSET', '数据库字符集必须为 utf8mb4');
|
|
}
|
|
if (metadata.databaseCollation !== 'utf8mb4_general_ci') {
|
|
throw new SchemaExportError('INVALID_DATABASE_COLLATION', '数据库排序规则必须为 utf8mb4_general_ci');
|
|
}
|
|
}
|