prepare( 'SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?' ); $stmt->execute([$table]); return $stmt->fetchColumn() !== false; }; /** @return list */ $tableColumns = static function (PDO $pdo, string $table): array { $stmt = $pdo->prepare( 'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION' ); $stmt->execute([$table]); return array_map('strval', $stmt->fetchAll(PDO::FETCH_COLUMN)); }; $targetsToClear = []; $copies = []; $sourceTableCount = 0; foreach (app_database_table_names() as $baseName) { if ($baseName === 'schema_migrations') { continue; } $sourceTable = app_db_table_name($baseName, $sourcePrefix); $targetTable = app_db_table_name($baseName, $targetPrefix); $sourceExists = $tableExists($rawPdo, $sourceTable); $targetExists = $tableExists($rawPdo, $targetTable); if ($sourceExists) { $sourceTableCount++; } if ($sourceExists && !$targetExists) { throw new RuntimeException("Zieltabelle {$targetTable} fehlt nach den Migrationen."); } if (!$targetExists) { continue; } $targetsToClear[] = $targetTable; if (!$sourceExists) { continue; } $sourceColumns = $tableColumns($rawPdo, $sourceTable); $targetColumns = $tableColumns($rawPdo, $targetTable); if ($sourceColumns !== $targetColumns) { throw new RuntimeException("Spalten von {$sourceTable} und {$targetTable} stimmen nicht überein."); } $copies[] = [$sourceTable, $targetTable, $sourceColumns]; } if ($sourceTableCount === 0) { throw new RuntimeException('Im Quellschema wurden keine Anwendungstabellen gefunden.'); } $copiedRows = 0; $rawPdo->exec('SET FOREIGN_KEY_CHECKS = 0'); try { $rawPdo->beginTransaction(); foreach ($targetsToClear as $targetTable) { $rawPdo->exec('DELETE FROM ' . $quoteIdentifier($targetTable)); } foreach ($copies as [$sourceTable, $targetTable, $columns]) { $quotedColumns = implode(', ', array_map($quoteIdentifier, $columns)); $sourceRows = (int)$rawPdo ->query('SELECT COUNT(*) FROM ' . $quoteIdentifier($sourceTable)) ->fetchColumn(); if ($sourceRows > 0) { $rawPdo->exec( 'INSERT INTO ' . $quoteIdentifier($targetTable) . ' (' . $quotedColumns . ') SELECT ' . $quotedColumns . ' FROM ' . $quoteIdentifier($sourceTable) ); } $targetRows = (int)$rawPdo ->query('SELECT COUNT(*) FROM ' . $quoteIdentifier($targetTable)) ->fetchColumn(); if ($sourceRows !== $targetRows) { throw new RuntimeException( "Zeilenzahl stimmt für {$sourceTable} -> {$targetTable} nicht: {$sourceRows} != {$targetRows}." ); } $copiedRows += $targetRows; echo "{$sourceTable} -> {$targetTable}: {$targetRows} Zeile(n)\n"; } $rawPdo->commit(); } catch (Throwable $e) { if ($rawPdo->inTransaction()) { $rawPdo->rollBack(); } throw $e; } finally { $rawPdo->exec('SET FOREIGN_KEY_CHECKS = 1'); } echo "Datenübernahme abgeschlossen: {$copiedRows} Zeile(n). Das Quellschema blieb unverändert.\n";