-
Notifications
You must be signed in to change notification settings - Fork 11.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[11.x] Enhance database migrations #51373
Changes from 12 commits
d2f441e
b77e691
1a43f5f
fa6211a
9a38044
f2c6235
35c97a5
6af0984
694edbf
d687bca
44a7e5d
f94495e
09f8845
ba88fec
407a6d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
use Illuminate\Database\Query\Expression; | ||
use Illuminate\Database\Schema\Grammars\Grammar; | ||
use Illuminate\Database\Schema\Grammars\MySqlGrammar; | ||
use Illuminate\Database\Schema\Grammars\SQLiteGrammar; | ||
use Illuminate\Support\Fluent; | ||
use Illuminate\Support\Traits\Macroable; | ||
|
||
|
@@ -78,6 +79,13 @@ class Blueprint | |
*/ | ||
public $after; | ||
|
||
/** | ||
* The blueprint state instance. | ||
* | ||
* @var \Illuminate\Database\Schema\BlueprintState|null | ||
*/ | ||
private $state; | ||
|
||
/** | ||
* Create a new schema blueprint. | ||
* | ||
|
@@ -136,6 +144,10 @@ public function toSql(Connection $connection, Grammar $grammar) | |
$method = 'compile'.ucfirst($command->name); | ||
|
||
if (method_exists($grammar, $method) || $grammar::hasMacro($method)) { | ||
if ($this->hasState()) { | ||
$this->state->update($command); | ||
} | ||
|
||
if (! is_null($sql = $grammar->$method($this, $command, $connection))) { | ||
$statements = array_merge($statements, (array) $sql); | ||
} | ||
|
@@ -161,6 +173,8 @@ protected function ensureCommandsAreValid(Connection $connection) | |
/** | ||
* Get all of the commands matching the given names. | ||
* | ||
* @deprecated Will be removed in a future Laravel version. | ||
* | ||
* @param array $names | ||
* @return \Illuminate\Support\Collection | ||
*/ | ||
|
@@ -180,17 +194,20 @@ protected function commandsNamed(array $names) | |
*/ | ||
protected function addImpliedCommands(Connection $connection, Grammar $grammar) | ||
{ | ||
if (count($this->getAddedColumns()) > 0 && ! $this->creating()) { | ||
array_unshift($this->commands, $this->createCommand('add')); | ||
} | ||
|
||
if (count($this->getChangedColumns()) > 0 && ! $this->creating()) { | ||
array_unshift($this->commands, $this->createCommand('change')); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Step 2. We have already added |
||
$this->addFluentIndexes($connection, $grammar); | ||
|
||
$this->addFluentCommands($connection, $grammar); | ||
|
||
if (! $this->creating()) { | ||
$this->commands = array_map( | ||
fn ($command) => $command instanceof ColumnDefinition | ||
? $this->createCommand($command->change ? 'change' : 'add', ['column' => $command]) | ||
: $command, | ||
$this->commands | ||
); | ||
|
||
$this->addAlterCommands($connection, $grammar); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Step 3. We walk through the commands and convert Then we call |
||
} | ||
|
||
/** | ||
|
@@ -260,6 +277,46 @@ public function addFluentCommands(Connection $connection, Grammar $grammar) | |
} | ||
} | ||
|
||
/** | ||
* Add the alter commands if whenever needed. | ||
* | ||
* @param \Illuminate\Database\Connection $connection | ||
* @param \Illuminate\Database\Schema\Grammars\Grammar $grammar | ||
* @return void | ||
*/ | ||
public function addAlterCommands(Connection $connection, Grammar $grammar) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Step 4. SQLite doesn't support some alter commands, so we need to recreate the table in order to apply changes. |
||
{ | ||
if ($grammar instanceof SQLiteGrammar) { | ||
$alterCommands = $grammar->getAlterCommands($connection); | ||
$commands = []; | ||
$lastCommandWasAlter = false; | ||
$hasAlterCommand = false; | ||
|
||
foreach ($this->commands as $command) { | ||
if (in_array($command->name, $alterCommands)) { | ||
$lastCommandWasAlter = true; | ||
$hasAlterCommand = true; | ||
} elseif ($lastCommandWasAlter) { | ||
$commands[] = $this->createCommand('alter'); | ||
$lastCommandWasAlter = false; | ||
} | ||
|
||
$commands[] = $command; | ||
} | ||
|
||
if ($lastCommandWasAlter) { | ||
$commands[] = $this->createCommand('alter'); | ||
$lastCommandWasAlter = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IDK I prefer to keep it as is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think someone will come up with PR to remove the unused variable at some point. No reason to define it. |
||
} | ||
|
||
if ($hasAlterCommand) { | ||
$this->state = new BlueprintState($this, $connection, $grammar); | ||
} | ||
|
||
$this->commands = $commands; | ||
} | ||
} | ||
|
||
/** | ||
* Determine if the blueprint has a create command. | ||
* | ||
|
@@ -1634,6 +1691,10 @@ protected function addColumnDefinition($definition) | |
{ | ||
$this->columns[] = $definition; | ||
|
||
if (! $this->creating()) { | ||
$this->commands[] = $definition; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Step 1. When modifying a table, we also add each |
||
if ($this->after) { | ||
$definition->after($this->after); | ||
|
||
|
@@ -1671,6 +1732,10 @@ public function removeColumn($name) | |
return $c['name'] != $name; | ||
})); | ||
|
||
$this->commands = array_values(array_filter($this->commands, function ($c) use ($name) { | ||
hafezdivandari marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return ! $c instanceof ColumnDefinition || $c['name'] != $name; | ||
})); | ||
|
||
return $this; | ||
} | ||
|
||
|
@@ -1740,6 +1805,27 @@ public function getCommands() | |
return $this->commands; | ||
} | ||
|
||
/** | ||
* Get the state of the blueprint. | ||
* | ||
* @return \Illuminate\Database\Schema\BlueprintState | ||
*/ | ||
public function getState() | ||
{ | ||
return $this->state; | ||
} | ||
|
||
/* | ||
* Determine if the blueprint has state. | ||
* | ||
* @param mixed $name | ||
* @return bool | ||
*/ | ||
private function hasState(): bool | ||
{ | ||
return ! is_null($this->state); | ||
hafezdivandari marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/** | ||
* Get the columns on the blueprint that should be added. | ||
* | ||
|
@@ -1755,6 +1841,8 @@ public function getAddedColumns() | |
/** | ||
* Get the columns on the blueprint that should be changed. | ||
* | ||
* @deprecated Will be removed in a future Laravel version. | ||
* | ||
* @return \Illuminate\Database\Schema\ColumnDefinition[] | ||
*/ | ||
public function getChangedColumns() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Step 5. When compiling to SQL, we update the state on each command.