File manager - Edit - /var/www/html/homologBancodetalentos/app/Support/TalentBank/LegacySqlDumpImporter.php
Back
<?php namespace App\Support\TalentBank; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\DB; use RuntimeException; use Throwable; /** * Importa um dump MySQL (.sql) para um banco temporário na mesma instância, * expõe a conexão Laravel 'mysql_bt_legacy' apontando para esse banco e * opcionalmente destrói o banco ao final. * * Uso típico: * $importer = new LegacySqlDumpImporter('/path/to/siati_app.sql'); * $importer->import($progressCallback); * // ... usar conexão 'mysql_bt_legacy' ... * $importer->cleanup(); */ class LegacySqlDumpImporter { private string $sqlPath; private string $tempDatabase; private bool $dropAfter; private bool $imported = false; public function __construct( string $sqlPath, ?string $tempDatabase = null, ?bool $dropAfter = null, ) { $this->sqlPath = $sqlPath; $this->tempDatabase = $tempDatabase ?? (string) config('talent_bank_legacy_import.temp_database', 'bt_legacy_import_temp'); $this->dropAfter = $dropAfter ?? (bool) config('talent_bank_legacy_import.drop_temp_database_after_import', true); } public function getSqlPath(): string { return $this->sqlPath; } public function getTempDatabase(): string { return $this->tempDatabase; } /** * Valida o arquivo, cria o banco temporário, importa o dump e reconfigura * a conexão 'mysql_bt_legacy' para apontar para o banco criado. * * @param callable|null $progressCallback fn(string $step, string $message): void * @throws RuntimeException */ public function import(?callable $progressCallback = null): void { $this->ensureFileReadable(); $progress = $progressCallback ?? static function () {}; $progress('validate', "Arquivo validado: {$this->sqlPath}"); $this->createDatabase($progress); $this->reconfigureConnection(); $this->executeDump($progress); $this->imported = true; $progress('done', "Dump importado com sucesso para o banco `{$this->tempDatabase}`."); } /** * Remove o banco temporário, se drop_after estiver habilitado. * Seguro de chamar mesmo se import() não foi executado. */ public function cleanup(bool $force = false): void { if (! $this->dropAfter && ! $force) { return; } try { $db = $this->quoteName($this->tempDatabase); DB::statement("DROP DATABASE IF EXISTS {$db}"); } catch (Throwable) { // silencia — cleanup é best-effort } } public function isImported(): bool { return $this->imported; } // ------------------------------------------------------------------------- private function ensureFileReadable(): void { if (! file_exists($this->sqlPath)) { throw new RuntimeException("Arquivo de dump não encontrado: {$this->sqlPath}"); } if (! is_readable($this->sqlPath)) { throw new RuntimeException("Arquivo de dump sem permissão de leitura: {$this->sqlPath}"); } if (filesize($this->sqlPath) === 0) { throw new RuntimeException("Arquivo de dump está vazio: {$this->sqlPath}"); } } private function createDatabase(?callable $progress): void { $db = $this->quoteName($this->tempDatabase); $progress('create_db', "Criando banco temporário `{$this->tempDatabase}`..."); DB::statement("DROP DATABASE IF EXISTS {$db}"); DB::statement("CREATE DATABASE {$db} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); $progress('create_db', "Banco `{$this->tempDatabase}` criado."); } private function reconfigureConnection(): void { // Herda credenciais da conexão padrão e aponta para o banco temporário $base = config('database.connections.mysql', []); Config::set("database.connections.mysql_bt_legacy.database", $this->tempDatabase); // Garante que host/port/user/pass estão em sincronia com o padrão foreach (['host', 'port', 'username', 'password', 'unix_socket'] as $key) { if (isset($base[$key])) { Config::set("database.connections.mysql_bt_legacy.{$key}", $base[$key]); } } // Força Laravel a recriar o PDO com a nova config DB::purge('mysql_bt_legacy'); DB::reconnect('mysql_bt_legacy'); } private function executeDump(?callable $progress): void { $progress('import_dump', 'Importando dump SQL (pode demorar alguns minutos)...'); $mysqlBin = $this->findMysqlBinary(); $cfg = config('database.connections.mysql_bt_legacy', []); $host = (string) ($cfg['host'] ?? '127.0.0.1'); $port = (string) ($cfg['port'] ?? '3306'); $user = (string) ($cfg['username'] ?? 'root'); $pass = (string) ($cfg['password'] ?? ''); // Monta argv sem shell — proc_open não usa shell, então não há redirecionamento $args = [ $mysqlBin, '-h', $host, '-P', $port, '-u', $user, ]; if ($pass !== '') { $args[] = '-p' . $pass; } $args[] = '--default-character-set=utf8mb4'; $args[] = $this->tempDatabase; // Abre o arquivo .sql como stdin — compatível com Windows e Unix $fileHandle = fopen($this->sqlPath, 'rb'); if ($fileHandle === false) { throw new RuntimeException("Não foi possível abrir o arquivo: {$this->sqlPath}"); } $descriptors = [ 0 => $fileHandle, // stdin = arquivo sql 1 => ['pipe', 'w'], // stdout 2 => ['pipe', 'w'], // stderr ]; $process = proc_open($args, $descriptors, $pipes); fclose($fileHandle); if (! is_resource($process)) { throw new RuntimeException('Não foi possível iniciar o processo mysql.'); } $stdout = stream_get_contents($pipes[1]); $stderr = stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); $exitCode = proc_close($process); if ($exitCode !== 0) { $detail = trim($stderr ?: $stdout); throw new RuntimeException( "Falha ao importar dump (exit {$exitCode}): {$detail}" ); } $progress('import_dump', 'Dump SQL importado com sucesso.'); } private function findMysqlBinary(): string { // 1. Caminho configurado explicitamente via env $configured = (string) config('talent_bank_legacy_import.mysql_binary', ''); if ($configured !== '' && file_exists($configured)) { return $configured; } // 2. Laragon (Windows) — procura nas versões instaladas, mais recente primeiro if (PHP_OS_FAMILY === 'Windows') { $laragonBase = 'C:\\laragon\\bin\\mysql'; if (is_dir($laragonBase)) { $dirs = glob($laragonBase . '\\*', GLOB_ONLYDIR); if ($dirs) { rsort($dirs); foreach ($dirs as $dir) { $bin = $dir . '\\bin\\mysql.exe'; if (file_exists($bin)) { return $bin; } } } } // PATH do Windows via where.exe $out = []; $code = 0; exec('where mysql.exe 2>NUL', $out, $code); if ($code === 0 && ! empty($out[0]) && file_exists(trim($out[0]))) { return trim($out[0]); } } // 3. Unix: which foreach (['mysql', 'mysql8', '/usr/bin/mysql', '/usr/local/bin/mysql'] as $candidate) { $out = []; $code = 0; exec("which {$candidate} 2>/dev/null", $out, $code); if ($code === 0 && ! empty($out[0])) { return trim($out[0]); } } throw new RuntimeException( 'Binário mysql não encontrado. Instale o MySQL Client ou defina TALENT_BANK_MYSQL_BINARY=/caminho/para/mysql no .env.' ); } private function quoteName(string $name): string { // Backtick-quote seguro: escapa backticks internos return '`' . str_replace('`', '``', $name) . '`'; } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.28 | Generation time: 0.02 |
proxy
|
phpinfo
|
Settings