Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ public function handle()
// "create" in the name. This will allow us to provide a convenient way
// of creating migrations that create new tables for the application.
if (! $table) {
[$table, $create] = TableGuesser::guess($name);
[$table, $create, $drop] = TableGuesser::guess($name);
}

// Now we are ready to write the migration out to disk. Once we've written
// the migration out, we will dump-autoload for the entire framework to
// make sure that the migrations are registered by the class loaders.
$this->writeMigration($name, $table, $create);
$this->writeMigration($name, $table, $create, $drop ?? false);
}

/**
Expand All @@ -104,12 +104,13 @@ public function handle()
* @param string $name
* @param string $table
* @param bool $create
* @param bool $drop
* @return void
*/
protected function writeMigration($name, $table, $create)
protected function writeMigration($name, $table, $create, $drop)
{
$file = $this->creator->create(
$name, $this->getMigrationPath(), $table, $create
$name, $this->getMigrationPath(), $table, $create, $drop
);

if (windows_os()) {
Expand Down
15 changes: 13 additions & 2 deletions src/Illuminate/Database/Console/Migrations/TableGuesser.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ class TableGuesser
'/.+_(to|from|in)_(\w+)$/',
];

const DROP_PATTERNS = [
'/^drop_(\w+)_table$/',
'/^drop_(\w+)$/',
];

/**
* Attempt to guess the table name and "creation" status of the given migration.
*
Expand All @@ -24,13 +29,19 @@ public static function guess($migration)
{
foreach (self::CREATE_PATTERNS as $pattern) {
if (preg_match($pattern, $migration, $matches)) {
return [$matches[1], $create = true];
return [$matches[1], $create = true, $drop = false];
}
}

foreach (self::CHANGE_PATTERNS as $pattern) {
if (preg_match($pattern, $migration, $matches)) {
return [$matches[2], $create = false];
return [$matches[2], $create = false, $drop = false];
}
}

foreach (self::DROP_PATTERNS as $pattern) {
if (preg_match($pattern, $migration, $matches)) {
return [$matches[1], $create = false, $drop = true];
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/Illuminate/Database/Migrations/MigrationCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,19 @@ public function __construct(Filesystem $files, $customStubPath)
* @param string $path
* @param string|null $table
* @param bool $create
* @param bool $drop
* @return string
*
* @throws \Exception
*/
public function create($name, $path, $table = null, $create = false)
public function create($name, $path, $table = null, $create = false, $drop = false)
{
$this->ensureMigrationDoesntAlreadyExist($name, $path);

// First we will get the stub file for the migration, which serves as a type
// of template for the migration. Once we have those we will populate the
// various place-holders, save the file, and run the post create event.
$stub = $this->getStub($table, $create);
$stub = $this->getStub($table, $create, $drop);

$path = $this->getPath($name, $path);

Expand Down Expand Up @@ -107,9 +108,10 @@ protected function ensureMigrationDoesntAlreadyExist($name, $migrationPath = nul
*
* @param string|null $table
* @param bool $create
* @param bool $drop
* @return string
*/
protected function getStub($table, $create)
protected function getStub($table, $create, $drop)
{
if (is_null($table)) {
$stub = $this->files->exists($customPath = $this->customStubPath.'/migration.stub')
Expand All @@ -119,6 +121,10 @@ protected function getStub($table, $create)
$stub = $this->files->exists($customPath = $this->customStubPath.'/migration.create.stub')
? $customPath
: $this->stubPath().'/migration.create.stub';
} elseif ($drop) {
$stub = $this->files->exists($customPath = $this->customStubPath.'/migration.drop.stub')
? $customPath
: $this->stubPath().'/migration.drop.stub';
} else {
$stub = $this->files->exists($customPath = $this->customStubPath.'/migration.update.stub')
? $customPath
Expand Down
26 changes: 26 additions & 0 deletions src/Illuminate/Database/Migrations/stubs/migration.drop.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?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
{
Schema::dropIfExists('{{ table }}');
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::create('{{ table }}', function (Blueprint $table) {
//
});
}
};
14 changes: 14 additions & 0 deletions tests/Database/DatabaseMigrationCreatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ public function testTableUpdateMigrationStoresMigrationFile()
$creator->create('create_bar', 'foo', 'baz');
}

public function testTableDropMigrationStoresMigrationFile()
{
$creator = $this->getCreator();
$creator->expects($this->any())->method('getDatePrefix')->willReturn('foo');
$creator->getFilesystem()->shouldReceive('exists')->once()->with('stubs/migration.drop.stub')->andReturn(false);
$creator->getFilesystem()->shouldReceive('get')->once()->with($creator->stubPath().'/migration.drop.stub')->andReturn('return new class DummyTable');
$creator->getFilesystem()->shouldReceive('ensureDirectoryExists')->once()->with('foo');
$creator->getFilesystem()->shouldReceive('put')->once()->with('foo/foo_create_bar.php', 'return new class baz');
$creator->getFilesystem()->shouldReceive('glob')->once()->with('foo/*.php')->andReturn(['foo/foo_create_bar.php']);
$creator->getFilesystem()->shouldReceive('requireOnce')->once()->with('foo/foo_create_bar.php');

$creator->create('create_bar', 'foo', 'baz', drop: true);
}

public function testTableCreationMigrationStoresMigrationFile()
{
$creator = $this->getCreator();
Expand Down
12 changes: 6 additions & 6 deletions tests/Database/DatabaseMigrationMakeCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function testBasicCreateDumpsAutoload()
$app->useDatabasePath(__DIR__);
$command->setLaravel($app);
$creator->shouldReceive('create')->once()
->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true)
->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true, false)
->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php');

$this->runCommand($command, ['name' => 'create_foo']);
Expand All @@ -44,7 +44,7 @@ public function testBasicCreateGivesCreatorProperArguments()
$app->useDatabasePath(__DIR__);
$command->setLaravel($app);
$creator->shouldReceive('create')->once()
->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true)
->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true, false)
->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php');

$this->runCommand($command, ['name' => 'create_foo']);
Expand All @@ -60,7 +60,7 @@ public function testBasicCreateGivesCreatorProperArgumentsWhenNameIsStudlyCase()
$app->useDatabasePath(__DIR__);
$command->setLaravel($app);
$creator->shouldReceive('create')->once()
->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true)
->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true, false)
->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php');

$this->runCommand($command, ['name' => 'CreateFoo']);
Expand All @@ -76,7 +76,7 @@ public function testBasicCreateGivesCreatorProperArgumentsWhenTableIsSet()
$app->useDatabasePath(__DIR__);
$command->setLaravel($app);
$creator->shouldReceive('create')->once()
->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'users', true)
->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'users', true, false)
->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php');

$this->runCommand($command, ['name' => 'create_foo', '--create' => 'users']);
Expand All @@ -92,7 +92,7 @@ public function testBasicCreateGivesCreatorProperArgumentsWhenCreateTablePattern
$app->useDatabasePath(__DIR__);
$command->setLaravel($app);
$creator->shouldReceive('create')->once()
->with('create_users_table', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'users', true)
->with('create_users_table', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'users', true, false)
->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_users_table.php');

$this->runCommand($command, ['name' => 'create_users_table']);
Expand All @@ -108,7 +108,7 @@ public function testCanSpecifyPathToCreateMigrationsIn()
$command->setLaravel($app);
$app->setBasePath('/home/laravel');
$creator->shouldReceive('create')->once()
->with('create_foo', '/home/laravel/vendor/laravel-package/migrations', 'users', true)
->with('create_foo', '/home/laravel/vendor/laravel-package/migrations', 'users', true, false)
->andReturn('/home/laravel/vendor/laravel-package/migrations/2021_04_23_110457_create_foo.php');
$this->runCommand($command, ['name' => 'create_foo', '--path' => 'vendor/laravel-package/migrations', '--create' => 'users']);
}
Expand Down
40 changes: 30 additions & 10 deletions tests/Database/TableGuesserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,67 @@ class TableGuesserTest extends TestCase
{
public function testMigrationIsProperlyParsed()
{
[$table, $create] = TableGuesser::guess('create_users_table');
[$table, $create, $drop] = TableGuesser::guess('create_users_table');
$this->assertSame('users', $table);
$this->assertTrue($create);
$this->assertFalse($drop);

[$table, $create] = TableGuesser::guess('add_status_column_to_users_table');
[$table, $create, $drop] = TableGuesser::guess('add_status_column_to_users_table');
$this->assertSame('users', $table);
$this->assertFalse($create);
$this->assertFalse($drop);

[$table, $create] = TableGuesser::guess('add_is_sent_to_crm_column_to_users_table');
[$table, $create, $drop] = TableGuesser::guess('add_is_sent_to_crm_column_to_users_table');
$this->assertSame('users', $table);
$this->assertFalse($create);
$this->assertFalse($drop);

[$table, $create] = TableGuesser::guess('change_status_column_in_users_table');
[$table, $create, $drop] = TableGuesser::guess('change_status_column_in_users_table');
$this->assertSame('users', $table);
$this->assertFalse($create);
$this->assertFalse($drop);

[$table, $create] = TableGuesser::guess('drop_status_column_from_users_table');
[$table, $create, $drop] = TableGuesser::guess('drop_status_column_from_users_table');
$this->assertSame('users', $table);
$this->assertFalse($create);
$this->assertFalse($drop);

[$table, $create, $drop] = TableGuesser::guess('drop_users_table');
$this->assertSame('users', $table);
$this->assertFalse($create);
$this->assertTrue($drop);
}

public function testMigrationIsProperlyParsedWithoutTableSuffix()
{
[$table, $create] = TableGuesser::guess('create_users');
[$table, $create, $drop] = TableGuesser::guess('create_users');
$this->assertSame('users', $table);
$this->assertTrue($create);
$this->assertFalse($drop);

[$table, $create, $drop] = TableGuesser::guess('add_status_column_to_users');
$this->assertSame('users', $table);
$this->assertFalse($create);
$this->assertFalse($drop);

[$table, $create] = TableGuesser::guess('add_status_column_to_users');
[$table, $create, $drop] = TableGuesser::guess('add_is_sent_to_crm_column_column_to_users');
$this->assertSame('users', $table);
$this->assertFalse($create);
$this->assertFalse($drop);

[$table, $create] = TableGuesser::guess('add_is_sent_to_crm_column_column_to_users');
[$table, $create, $drop] = TableGuesser::guess('change_status_column_in_users');
$this->assertSame('users', $table);
$this->assertFalse($create);
$this->assertFalse($drop);

[$table, $create] = TableGuesser::guess('change_status_column_in_users');
[$table, $create, $drop] = TableGuesser::guess('drop_status_column_from_users');
$this->assertSame('users', $table);
$this->assertFalse($create);
$this->assertFalse($drop);

[$table, $create] = TableGuesser::guess('drop_status_column_from_users');
[$table, $create, $drop] = TableGuesser::guess('drop_users');
$this->assertSame('users', $table);
$this->assertFalse($create);
$this->assertTrue($drop);
}
}