// 校验合并后的 SQL 文件:语句切分、引号闭合、括号平衡、首关键字白名单
|
const fs = require('node:fs');
|
// 先剔除整行注释(本文件中注释均为整行,且注释内会出现示例 SQL 的分号)
|
const raw = fs.readFileSync(__dirname + '/config_export_all_20260928.sql', 'utf8');
|
const s = raw
|
.split(/\r?\n/)
|
.filter((l) => !l.trimStart().startsWith('--'))
|
.join('\n');
|
|
let inS = false;
|
let start = 0;
|
let depth = 0;
|
let maxDepth = 0;
|
let statements = 0;
|
const keywords = new Set();
|
const ESC = '\\';
|
|
for (let i = 0; i < s.length; i++) {
|
const c = s[i];
|
if (!inS) {
|
if (c === "'") {
|
inS = true;
|
} else if (c === '(') {
|
depth++;
|
if (depth > maxDepth) maxDepth = depth;
|
} else if (c === ')') {
|
depth--;
|
if (depth < 0) throw new Error(`第 ${i} 字符处括号提前闭合`);
|
} else if (c === ';') {
|
const st = s.slice(start, i).trim();
|
if (st) {
|
const body = st
|
.split(/\r?\n/)
|
.filter((l) => l.trim() && !l.trim().startsWith('--'))
|
.join('\n');
|
const m = body.match(/^(\w+)/);
|
if (!m) throw new Error(`语句无法识别首关键字:${st.slice(0, 80)}`);
|
keywords.add(m[1].toUpperCase());
|
statements++;
|
}
|
start = i + 1;
|
}
|
} else if (c === "'") {
|
if (s[i - 1] === ESC && s[i - 2] !== ESC) {
|
// 反斜杠转义的引号,仍在字符串内
|
} else if (s[i + 1] === "'") {
|
i++; // '' 转义
|
} else {
|
inS = false;
|
}
|
}
|
}
|
|
console.log('语句数 :', statements);
|
console.log('括号结尾深度:', depth, '(应为 0)');
|
console.log('最大嵌套深度:', maxDepth);
|
console.log('未闭合字符串:', inS, '(应为 false)');
|
console.log('首关键字集合:', [...keywords].sort().join(' '));
|