Skip to content

Instantly share code, notes, and snippets.

@caingougou
Last active May 14, 2024 19:02
Show Gist options
  • Save caingougou/96cb5dd45739f2d94b070c0191248be3 to your computer and use it in GitHub Desktop.
Save caingougou/96cb5dd45739f2d94b070c0191248be3 to your computer and use it in GitHub Desktop.
Automatically generate a migration for current changes in local database
<?php
namespace App\Console\Commands;
use Illuminate\Support\Str;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class DatabaseDiffGenerator extends Command {
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:db-diff';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate diff';
/**
* Execute the console command.
*/
public function handle() {
$db_file = './database/mysql.sql';
$diff_up_file = sprintf('./database/diff_up_%s.sql', date('Y-m-d_H:i:s'));
$diff_down_file = sprintf('./database/diff_down_%s.sql', date('Y-m-d_H:i:s'));
$old_db = sprintf('%s_old_version', config('database.connections.mysql.database'));
DB::statement(sprintf('CREATE DATABASE IF NOT EXISTS %s CHARACTER SET %s COLLATE %s', $old_db, config('database.connections.mysql.charset'), config('database.connections.mysql.collation')));
DB::connection()->getPdo()->exec("USE $old_db;");
DB::unprepared(file_get_contents($db_file));
$command1 = sprintf(
'/usr/local/bin/dbdiff -l drop mysql://%s:%s@%s/%s mysql://%s:%s@%s/%s > %s',
config('database.connections.mysql.username'),
config('database.connections.mysql.password'),
config('database.connections.mysql.host'),
$old_db,
config('database.connections.mysql.username'),
config('database.connections.mysql.password'),
config('database.connections.mysql.host'),
config('database.connections.mysql.database'),
$diff_up_file
);
exec($command1);
$command2 = sprintf(
'/usr/local/bin/dbdiff -l drop mysql://%s:%s@%s/%s mysql://%s:%s@%s/%s > %s',
config('database.connections.mysql.username'),
config('database.connections.mysql.password'),
config('database.connections.mysql.host'),
config('database.connections.mysql.database'),
config('database.connections.mysql.username'),
config('database.connections.mysql.password'),
config('database.connections.mysql.host'),
$old_db,
$diff_down_file
);
exec($command2);
$upContent = trim(file_get_contents($diff_up_file));
dump($upContent);
$downContent = trim(file_get_contents($diff_down_file));
dump($downContent);
if ($upContent == '') {
exec('rm ' . $diff_up_file);
exec('rm ' . $diff_down_file);
} else {
$upLines = explode("\n", $upContent);
$codeUp = '';
foreach ($upLines as $upline) {
if (($upline != '') && !Str::startsWith($upline, '--')) {
$codeUp = $codeUp . '\DB::statement("' . str_replace('--', '', $upline) . '");' . "\n\t";
}
}
$downLines = explode("\n", $downContent);
$codeDown = '';
foreach ($downLines as $downline) {
if (($downline != '') && !Str::startsWith($downline, '--')) {
$codeDown = $codeDown . '\DB::statement("' . str_replace('--', '', $downline) . '");' . "\n\t";
}
}
$code = <<<EOF
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void {
$codeUp
}
/**
* Reverse the migrations.
*/
public function down(): void {
$codeDown
}
};
EOF;
exec('rm ' . $diff_up_file);
exec('rm ' . $diff_down_file);
file_put_contents('database/migrations/' . date('Y_m_d_His') . '_diff.php', $code);
}
DB::statement(sprintf('DROP DATABASE %s', $old_db));
$mysqldump = sprintf('mysqldump -h %s -u %s -p%s --no-data %s > ' . $db_file, config('database.connections.mysql.host'), config('database.connections.mysql.username'), config('database.connections.mysql.password'), config('database.connections.mysql.database'));
exec($mysqldump);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment