Skip to content

Commit

Permalink
Merge pull request #3 from mahmoudmohamedramadan/development
Browse files Browse the repository at this point in the history
[1.x] wip
  • Loading branch information
mahmoudmohamedramadan authored Jun 21, 2024
2 parents 9d2587a + 5daa0b6 commit 52bd416
Showing 1 changed file with 85 additions and 52 deletions.
137 changes: 85 additions & 52 deletions src/Console/Commands/CustomFreshCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,13 @@ public function handle()
fn () => $this->call('migrate', ['--force' => true])
);

$migrations = $this->getMigrations(
explode(",", $this->argument("table"))
);
$database = $this->getDatabaseInfo(explode(",", $this->argument("table")));

$this->components->info('Preparing database.');

$this->components->task('Dropping the tables', $this->dropTables(
$migrations["tableNames"],
$migrations["migrationNames"]
$this->collectMigrations($database),
$this->collectTables($database)
));

$this->call('migrate', ['--force' => true]);
Expand All @@ -59,108 +57,143 @@ public function handle()
}

/**
* Get the listed tables in the database.
*
* @return array
*/
protected function getTables()
{
return DB::connection()->getDoctrineSchemaManager()->listTableNames();
}

/**
* Get the correct table names with their migration.
* Get the correct table names with their migrations.
*
* @param array $tablesToBeDropped
* @param array $tablesNeededToDrop
* @return array
*/
protected function getMigrations(array $tablesToBeDropped)
protected function getDatabaseInfo(array $tablesNeededToDrop)
{
$migrationsPath = database_path('migrations');

// At first, we will filter the given array of tables, and then iterate over
// each one to check if the passed table has a migration then we will check if
// the `tableNames` has been set by the `getMigrationsInfo` method or not
// the `tables` has been set by the `guessDatabaseInfo` method or not
// because if it is set, it means the table is there
// or we will ask the developer to choose the correct table instead.
foreach (array_filter($tablesToBeDropped) as $index => $table) {
$migrationsInfo = $this->getMigrationsInfo($migrationsPath, $table);

if (empty($migrationsInfo["tableNames"][$index])) {
// In case the table is not there, we will recall the method again
// to update the database info.
foreach (array_filter($tablesNeededToDrop) as $index => $table) {
$info = $this->guessDatabaseInfo($table);

$database["migrations"][] = array_values($info["migrations"]);
$database["tables"][] = array_values($info["tables"]);

if (empty($database["tables"][$index])) {
$value = $this->choice(
"Choose the correct table instead ({$table})",
array_diff(
$this->getTables(),
array_merge($migrationsInfo["tableNames"], ["migrations"])
array_merge($this->collectTables($database), ["migrations"])
)
);

$migrationsInfo = $this->getMigrationsInfo($migrationsPath, $value);
$info = $this->guessDatabaseInfo($value);

$database["migrations"][$index] = array_values($info["migrations"]);
$database["tables"][$index] = array_values($info["tables"]);
}
}

return $migrationsInfo;
return $database;
}

/**
* Get the migrations that match the given table.
* Try to guess the database info based on the table name.
*
* @param string $migrationsPath
* @param string $table
* @return array
*/
protected function getMigrationsInfo(string $migrationsPath, string $table)
protected function guessDatabaseInfo(string $table)
{
$migrationsInfo = ["migrationNames" => [], "tableNames" => []];

if (!empty($migrationName = glob("{$migrationsPath}/*_create_{$table}_table.php"))) {
array_push($migrationsInfo["tableNames"], $table);
array_push($migrationsInfo["migrationNames"], basename($migrationName[0]));
} elseif (!empty($migrationName = glob("{$migrationsPath}/*_create_{$table}.php"))) {
array_push($migrationsInfo["tableNames"], $table);
array_push($migrationsInfo["migrationNames"], basename($migrationName[0]));
$migrationsPath = database_path('migrations');
$database = ["migrations" => [], "tables" => []];

if (!empty($migration = glob("{$migrationsPath}/*_create_{$table}_table.php"))) {
array_push($database["tables"], $table);
array_push($database["migrations"], basename($migration[0]));
} elseif (!empty($migration = glob("{$migrationsPath}/*_create_{$table}.php"))) {
array_push($database["tables"], $table);
array_push($database["migrations"], basename($migration[0]));
}

if (!empty($migrationName = glob("{$migrationsPath}/*_to_{$table}_table.php"))) {
array_push($migrationsInfo["migrationNames"], basename($migrationName[0]));
if (!empty($migration = glob("{$migrationsPath}/*_to_{$table}_table.php"))) {
array_push($database["migrations"], basename($migration[0]));
}

if (!empty($migrationName = glob("{$migrationsPath}/*_from_{$table}_table.php"))) {
array_push($migrationsInfo["migrationNames"], basename($migrationName[0]));
if (!empty($migration = glob("{$migrationsPath}/*_from_{$table}_table.php"))) {
array_push($database["migrations"], basename($migration[0]));
}

if (!empty($migrationName = glob("{$migrationsPath}/*_in_{$table}_table.php"))) {
array_push($migrationsInfo["migrationNames"], basename($migrationName[0]));
if (!empty($migration = glob("{$migrationsPath}/*_in_{$table}_table.php"))) {
array_push($database["migrations"], basename($migration[0]));
}

return $migrationsInfo;
return $database;
}

/**
* Drop all tables except the given array of table names.
*
* @param array $tableNames
* @param array $migrationNames
* @param array $migrations
* @param array $tables
* @return void
*/
protected function dropTables(array $tableNames, array $migrationNames)
protected function dropTables(array $migrations, array $tables)
{
DB::table("migrations")->truncate();

foreach ($migrationNames as $migration) {
foreach ($migrations as $migration) {
DB::table("migrations")
->insert(["migration" => substr_replace($migration, "", -4), "batch" => 1]);
}

$droppedTables = array_diff(
$tablesShouldBeDropped = array_diff(
$this->getTables(),
array_merge(array_filter($tableNames), ["migrations"])
array_merge(array_filter($tables), ["migrations"])
);

Schema::disableForeignKeyConstraints();

foreach ($droppedTables as $table) {
foreach ($tablesShouldBeDropped as $table) {
Schema::dropIfExists($table);
}
}

/**
* Get all listed tables in the database.
*
* @return array
*/
protected function getTables()
{
return DB::connection()->getDoctrineSchemaManager()->listTableNames();
}

/**
* Get the listed tables that should not be dropped.
*
* @param array $database
* @return array
*/
protected function collectTables(array $database)
{
return array_column($database["tables"], 0);
}

/**
* Get the listed migrations that should not be dropped.
*
* @param array $database
* @return array
*/
protected function collectMigrations(array $database)
{
return array_reduce($database["migrations"], function ($carry, $migration) {
if (is_array($migration)) {
return array_merge($carry, $migration);
}

return array_merge($carry, [$migration]);
}, []);
}
}

0 comments on commit 52bd416

Please sign in to comment.