Files
Gnuboard5/bin/check-runtime-ddl.php
T
whitedot 5bdbf360b0 refactor: 일반 실행 경로의 DB 변경을 버전형 마이그레이션으로 이전
과거 누적 DDL과 데이터 보정을 시점별 SQL로 분리하고 관리자·CLI 실행기를 제공한다. 실행 순서, 잠금, 체크섬, 성공·실패 이력 및 개별 실행의 선행 조건을 검증한다.

기존 스키마의 부분 적용 복구와 설치 SQL 정합성 검사를 추가하고 실행·복구 절차를 문서화한다.
2026-09-09 07:58:05 +00:00

70 lines
2.0 KiB
PHP
Executable File

#!/usr/bin/env php
<?php
if (PHP_SAPI !== 'cli') {
exit("CLI에서만 실행할 수 있습니다.\n");
}
$root = dirname(dirname(__FILE__));
$scan_paths = array('');
$excluded = array(
'lib/migration.lib.php',
'lib/PHPExcel/',
'data/',
'install/',
'migrations/',
'bin/check-migration-runner.php'
);
$lifecycle_ddl_files = array(
'adm/board_delete.inc.php'
);
$errors = array();
foreach ($scan_paths as $scan_path) {
$base = $root . '/' . $scan_path;
if (!is_dir($base)) {
continue;
}
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($base));
foreach ($iterator as $file) {
$pathname = $file->getPathname();
if (!$file->isFile() || strtolower(pathinfo($pathname, PATHINFO_EXTENSION)) !== 'php') {
continue;
}
$relative = str_replace($root . '/', '', str_replace('\\', '/', $pathname));
$skip = false;
foreach ($excluded as $exclude) {
if ($relative === $exclude || strpos($relative, $exclude) === 0) {
$skip = true;
break;
}
}
if ($skip) {
continue;
}
if (in_array($relative, $lifecycle_ddl_files)) {
continue;
}
$contents = file_get_contents($pathname);
$contents = preg_replace('/^.*\$schema_create.*$/m', '', $contents);
if (preg_match_all('/\b(?:ALTER\s+TABLE|CREATE\s+TABLE|DROP\s+TABLE|RENAME\s+(?:TABLE|TO)|TRUNCATE\s+TABLE)\b/i', $contents, $matches, PREG_OFFSET_CAPTURE)) {
foreach ($matches[0] as $match) {
$line = substr_count(substr($contents, 0, $match[1]), "\n") + 1;
$errors[] = $relative . ':' . $line . ': ' . preg_replace('/\s+/', ' ', trim($match[0]));
}
}
}
}
if ($errors) {
foreach ($errors as $error) {
fwrite(STDERR, '[실패] ' . $error . "\n");
}
exit(1);
}
echo "일반 실행 경로에 DDL 문이 없습니다.\n";