find proc
const fs = require('fs/promises');
const path = require('path');
const PROCEDURE_HEADER_LABEL = '\uD504\uB85C\uC2DC\uC838\uBA85'; // 프로시져명
const TARGET_TABLE_COMMENT = '/*###암호화대상테이블###*/';
async function main() {
const appDir = __dirname;
const procedurePath = path.join(appDir, 'allprocedure.txt');
const targetsPath = path.join(appDir, 'crypto-targets.json');
const outputPath = path.join(appDir, 'outproc.txt');
const [procedureText, targets] = await Promise.all([
fs.readFile(procedurePath, 'utf8'),
readCryptoTargets(targetsPath),
]);
const procedures = parseProcedures(procedureText);
const matchedProcedures = [];
const seen = new Set();
for (const procedure of procedures) {
if (!hasCryptoTarget(procedure.body, targets)) continue;
const key = procedure.name.toUpperCase();
if (seen.has(key)) continue;
seen.add(key);
matchedProcedures.push(formatProcedure(procedure.name, markCryptoTargetTables(procedure.body, targets)));
}
await fs.writeFile(outputPath, `${matchedProcedures.join('\n')}${matchedProcedures.length ? '\n' : ''}`, 'utf8');
console.log(`Done. procedures: ${procedures.length}, matched: ${matchedProcedures.length}, output: ${outputPath}`);
}
function parseProcedures(text) {
const procedures = [];
const headerPattern = new RegExp(`^\\s*${PROCEDURE_HEADER_LABEL}\\s*:\\s*(.+?)\\s*$`, 'gmi');
const headers = [...text.matchAll(headerPattern)];
for (let index = 0; index < headers.length; index += 1) {
const header = headers[index];
const nextHeader = headers[index + 1];
const name = header[1].trim();
const bodyStart = header.index + header[0].length;
const bodyEnd = nextHeader ? nextHeader.index : text.length;
const body = trimProcedureSeparators(text.slice(bodyStart, bodyEnd));
if (name) procedures.push({ name, body });
}
return procedures;
}
function trimProcedureSeparators(text) {
return text
.replace(/^\s*-{3,}\s*(?:\r?\n|$)/, '')
.replace(/(?:^|\r?\n)\s*-{3,}\s*$/, '')
.trim();
}
function formatProcedure(name, body) {
return [
'---------------------------',
`${PROCEDURE_HEADER_LABEL} : ${name}`,
'---------------------------',
body.trim(),
'---------------------------',
].join('\n');
}
function hasCryptoTarget(text, targets) {
return targets.some((target) => (
hasBoundaryToken(text, target.tableName)
|| hasBoundaryToken(text, target.plainColumn)
));
}
function markCryptoTargetTables(text, targets) {
let next = text;
const tableNames = [...new Set(targets.map((target) => target.tableName).filter(Boolean))];
for (const tableName of tableNames) {
next = markBoundaryToken(next, tableName, TARGET_TABLE_COMMENT);
}
return next;
}
function markBoundaryToken(text, token, comment) {
const commentRanges = commentTokenRanges(text);
const pattern = new RegExp(`(^|[^A-Za-z0-9_])(${escapeRegExp(token)})(?=$|[^A-Za-z0-9_])`, 'gi');
return text.replace(pattern, (match, prefix, foundToken, offset) => {
const tokenStart = offset + prefix.length;
const afterMatch = text.slice(offset + match.length);
if (isInsideRanges(tokenStart, commentRanges)) return match;
if (new RegExp(`^\\s*${escapeRegExp(comment)}`).test(afterMatch)) return match;
return `${prefix}${foundToken} ${comment}`;
});
}
function commentTokenRanges(text) {
const ranges = [];
const commentPattern = /|\/\*[\s\S]*?\*\//g;
for (const match of text.matchAll(commentPattern)) {
const start = match.index ?? 0;
ranges.push({ start, end: start + match[0].length });
}
return ranges;
}
function isInsideRanges(index, ranges) {
return ranges.some((range) => index >= range.start && index < range.end);
}
async function readCryptoTargets(filePath) {
const text = await fs.readFile(filePath, 'utf8');
const parsed = JSON.parse(text);
if (!Array.isArray(parsed)) {
throw new Error(`crypto-targets.json must be an array: ${filePath}`);
}
return parsed
.map((target) => ({
tableName: normalizeRequired(target.tableName),
plainColumn: normalizeRequired(target.plainColumn),
}))
.filter((target) => target.tableName && target.plainColumn);
}
function hasBoundaryToken(text, token) {
return token ? boundaryPattern(token).test(text) : false;
}
function boundaryPattern(token) {
return new RegExp(`(^|[^A-Za-z0-9_])${escapeRegExp(token)}(?=$|[^A-Za-z0-9_])`, 'i');
}
function normalizeRequired(value) {
return String(value ?? '').trim();
}
function escapeRegExp(value) {
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
main().catch((error) => {
console.error(error instanceof Error ? error.message : error);
process.exitCode = 1;
});
댓글
댓글 쓰기