Skip to content

Commit ab7fe07

Browse files
authored
Merge pull request #8 from VanOns/feature/import-improvements
Import improvements
2 parents 54712c3 + 8e29c17 commit ab7fe07

File tree

2 files changed

+93
-20
lines changed

2 files changed

+93
-20
lines changed

config/environment-importer.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,32 @@
5151
|--------------------------------------------------------------------------
5252
|
5353
| Here you can define the path to where the binary lives, which will be used to
54-
| dump the database. On macOS, you can install this using Homebrew:
55-
| https://formulae.brew.sh/formula/mysql-client
54+
| dump the database.
55+
|
56+
| Example binaries: mysqldump, mongodump, mariadb-dump, pg_dump, etc.
5657
|
5758
| NOTE: Don't include the binary itself in the path.
5859
|
5960
*/
6061

6162
'db_dump_binary_path' => env('LEI_DB_DUMP_BINARY_PATH', '/usr/bin'),
6263

64+
/*
65+
|--------------------------------------------------------------------------
66+
| Database Import Binary Path
67+
|--------------------------------------------------------------------------
68+
|
69+
| Here you can define the path to where the binary lives, which will
70+
| be used to import the database.
71+
|
72+
| Example binaries: mysql, mongoimport, mariadb, psql, etc.
73+
|
74+
| NOTE: Don't include the binary itself in the path.
75+
|
76+
*/
77+
78+
'db_import_binary_path' => env('LEI_DB_IMPORT_BINARY_PATH', '/usr/bin'),
79+
6380
/*
6481
|--------------------------------------------------------------------------
6582
| Backup Path

src/Commands/ImportEnvironmentCommand.php

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@ protected function createDumpForImport(string $dumpPath, string $dumpFile): void
245245
$this->line('[DB] Processing persist tables...');
246246

247247
foreach ($persistTables as $table) {
248+
if (!Schema::hasTable($table)) {
249+
continue;
250+
}
251+
248252
$tableDumpFile = "{$dumpPath}/local_{$table}.sql";
249253
$files[] = $tableDumpFile;
250254

@@ -426,32 +430,84 @@ protected function wipeLocalDatabase(): void
426430

427431
/**
428432
* Import the database dump.
433+
*
434+
* @throws ImportEnvironmentException
429435
*/
430436
protected function importDatabaseDump(string $dumpFile): void
431437
{
432438
$this->line('[DB] Importing database dump...');
433439

434-
$handle = fopen($dumpFile, 'rb');
435-
436-
/**
437-
* The following code will read the dump file line by line and execute each statement, which is useful for large
438-
* database dumps. The end of each statement is determined by a semicolon. We do it this way because it's a lot
439-
* less resource-intensive than loading the entire dump file into memory and executing it as a single query.
440-
*/
441-
$query = '';
442-
while (($line = fgets($handle)) !== false) {
443-
$query .= $line;
444-
445-
// Check if the line ends with a semicolon, meaning it's a complete statement.
446-
if (str_ends_with(trim($line), ';')) {
447-
DB::unprepared($query); // Execute the query.
448-
$query = ''; // Reset for next query.
449-
}
440+
match ($connection = DB::getDefaultConnection()) {
441+
'mysql' => $this->importMysqlDump($dumpFile),
442+
'sqlite' => $this->importSqliteDump($dumpFile),
443+
'pgsql' => $this->importPgsqlDump($dumpFile),
444+
default => throw new ImportEnvironmentException('Unsupported database connection type: ' . $connection),
445+
};
446+
447+
$this->info("[DB] Imported database dump from \"{$dumpFile}\".");
448+
}
449+
450+
/**
451+
* Import the database dump using the MySQL client.
452+
*
453+
* @throws ImportEnvironmentException
454+
*/
455+
protected function importMysqlDump(string $dumpFile): void
456+
{
457+
$binary = rtrim($this->getConfigValue('db_import_binary_path', '/usr/bin'), '/') . '/mysql';
458+
$command = sprintf(
459+
'%s --host=%s --port=%s --user=%s %s < %s',
460+
escapeshellcmd($binary),
461+
DB::getConfig('host'),
462+
DB::getConfig('port'),
463+
DB::getConfig('username'),
464+
DB::getConfig('database'),
465+
escapeshellarg($dumpFile)
466+
);
467+
468+
$process = Process::fromShellCommandline($command, env: [
469+
'MYSQL_PWD' => DB::getConfig('password'),
470+
]);
471+
472+
$process->run();
473+
474+
if (!$process->isSuccessful()) {
475+
throw new ImportEnvironmentException('Failed to import MySQL database dump: ' . $process->getErrorOutput());
450476
}
477+
}
451478

452-
fclose($handle);
479+
/**
480+
* @throws ImportEnvironmentException
481+
*/
482+
protected function importSqliteDump(string $dumpFile): void
483+
{
484+
$destination = DB::getConfig('database');
453485

454-
$this->info("[DB] Imported database dump from \"{$dumpFile}\".");
486+
if (!File::copy($dumpFile, $destination)) {
487+
throw new ImportEnvironmentException("Failed to import SQLite database dump from \"{$dumpFile}\" to \"{$destination}\"");
488+
}
489+
}
490+
491+
/**
492+
* @throws ImportEnvironmentException
493+
*/
494+
protected function importPgsqlDump(string $dumpFile): void
495+
{
496+
$binary = rtrim($this->getConfigValue('db_import_binary_path', '/usr/bin'), '/') . '/psql';
497+
$process = new Process([
498+
$binary,
499+
'--host=' . DB::getConfig('host'),
500+
'--port=' . DB::getConfig('port'),
501+
'--username=' . DB::getConfig('username'),
502+
'--dbname=' . DB::getConfig('database'),
503+
'-f', $dumpFile,
504+
], null, ['PGPASSWORD' => DB::getConfig('password')]);
505+
506+
$process->run();
507+
508+
if (!$process->isSuccessful()) {
509+
throw new ImportEnvironmentException('Failed to import PostgreSQL database dump: ' . $process->getErrorOutput());
510+
}
455511
}
456512

457513
/**

0 commit comments

Comments
 (0)