This commit is contained in:
Flatlogic Bot 2026-05-01 19:08:05 +00:00
parent da3da25764
commit 0e49a0bd6f

View File

@ -163,7 +163,96 @@ function splitSqlStatements(string $sql): array
return $statements;
}
function isIgnorableMigrationError(PDOException $exception): bool
function tableExists(PDO $pdo, string $tableName): bool
{
static $cache = [];
$normalized = strtolower($tableName);
if (array_key_exists($normalized, $cache)) {
return $cache[$normalized];
}
$stmt = $pdo->prepare('SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = :table LIMIT 1');
$stmt->execute(['table' => $tableName]);
$cache[$normalized] = (bool) $stmt->fetchColumn();
return $cache[$normalized];
}
function schemaDefinesTable(string $tableName): bool
{
static $tables = null;
if ($tables === null) {
$tables = [];
$schemaFiles = [
__DIR__ . '/db/schema.sql',
__DIR__ . '/complete_schema.sql',
];
foreach ($schemaFiles as $schemaFile) {
if (!is_file($schemaFile)) {
continue;
}
$sql = file_get_contents($schemaFile);
if ($sql === false) {
continue;
}
if (preg_match_all('/CREATE\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?\s+`?([a-zA-Z0-9_]+)`?/i', $sql, $matches)) {
foreach ($matches[1] as $name) {
$tables[strtolower($name)] = true;
}
}
}
}
return isset($tables[strtolower($tableName)]);
}
function extractMissingTableName(PDOException $exception): ?string
{
$message = $exception->getMessage();
if (preg_match("/Table '([^']+)' doesn't exist/i", $message, $matches)) {
$qualifiedName = str_replace('`', '', $matches[1]);
$parts = explode('.', $qualifiedName);
$tableName = trim((string) end($parts));
return $tableName !== '' ? $tableName : null;
}
return null;
}
function statementMentionsTable(string $statement, string $tableName): bool
{
$pattern = '/(^|[^a-zA-Z0-9_])`?' . preg_quote($tableName, '/') . '`?([^a-zA-Z0-9_]|$)/i';
return preg_match($pattern, $statement) === 1;
}
function isLegacyMissingTableError(PDO $pdo, PDOException $exception, string $statement): bool
{
$driverCode = isset($exception->errorInfo[1]) ? (int) $exception->errorInfo[1] : null;
$message = strtolower($exception->getMessage());
if ($driverCode !== 1146 && !str_contains($message, 'base table or view not found')) {
return false;
}
$missingTable = extractMissingTableName($exception);
if ($missingTable === null || !statementMentionsTable($statement, $missingTable)) {
return false;
}
if (tableExists($pdo, $missingTable) || schemaDefinesTable($missingTable)) {
return false;
}
return true;
}
function isIgnorableMigrationError(PDO $pdo, PDOException $exception, string $statement): bool
{
$driverCode = isset($exception->errorInfo[1]) ? (int) $exception->errorInfo[1] : null;
$message = strtolower($exception->getMessage());
@ -189,6 +278,10 @@ function isIgnorableMigrationError(PDOException $exception): bool
}
}
if (isLegacyMissingTableError($pdo, $exception, $statement)) {
return true;
}
return false;
}
@ -209,7 +302,7 @@ function executeSqlMigration(PDO $pdo, string $filePath): void
try {
$pdo->exec($statement);
} catch (PDOException $exception) {
if (isIgnorableMigrationError($exception)) {
if (isIgnorableMigrationError($pdo, $exception, $statement)) {
migrationOutput(' - skipped statement ' . ($number + 1) . ': ' . $exception->getMessage());
continue;
}