ddd
This commit is contained in:
parent
da3da25764
commit
0e49a0bd6f
97
migrate.php
97
migrate.php
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user