8
8
use Illuminate \Database \Query \Expression ;
9
9
use Illuminate \Database \Schema \Grammars \Grammar ;
10
10
use Illuminate \Database \Schema \Grammars \MySqlGrammar ;
11
+ use Illuminate \Database \Schema \Grammars \SQLiteGrammar ;
11
12
use Illuminate \Support \Fluent ;
12
13
use Illuminate \Support \Traits \Macroable ;
13
14
@@ -78,6 +79,13 @@ class Blueprint
78
79
*/
79
80
public $ after ;
80
81
82
+ /**
83
+ * The blueprint state instance.
84
+ *
85
+ * @var \Illuminate\Database\Schema\BlueprintState|null
86
+ */
87
+ protected $ state ;
88
+
81
89
/**
82
90
* Create a new schema blueprint.
83
91
*
@@ -136,6 +144,10 @@ public function toSql(Connection $connection, Grammar $grammar)
136
144
$ method = 'compile ' .ucfirst ($ command ->name );
137
145
138
146
if (method_exists ($ grammar , $ method ) || $ grammar ::hasMacro ($ method )) {
147
+ if ($ this ->hasState ()) {
148
+ $ this ->state ->update ($ command );
149
+ }
150
+
139
151
if (! is_null ($ sql = $ grammar ->$ method ($ this , $ command , $ connection ))) {
140
152
$ statements = array_merge ($ statements , (array ) $ sql );
141
153
}
@@ -161,6 +173,8 @@ protected function ensureCommandsAreValid(Connection $connection)
161
173
/**
162
174
* Get all of the commands matching the given names.
163
175
*
176
+ * @deprecated Will be removed in a future Laravel version.
177
+ *
164
178
* @param array $names
165
179
* @return \Illuminate\Support\Collection
166
180
*/
@@ -180,17 +194,20 @@ protected function commandsNamed(array $names)
180
194
*/
181
195
protected function addImpliedCommands (Connection $ connection , Grammar $ grammar )
182
196
{
183
- if (count ($ this ->getAddedColumns ()) > 0 && ! $ this ->creating ()) {
184
- array_unshift ($ this ->commands , $ this ->createCommand ('add ' ));
185
- }
186
-
187
- if (count ($ this ->getChangedColumns ()) > 0 && ! $ this ->creating ()) {
188
- array_unshift ($ this ->commands , $ this ->createCommand ('change ' ));
189
- }
190
-
191
197
$ this ->addFluentIndexes ($ connection , $ grammar );
192
198
193
199
$ this ->addFluentCommands ($ connection , $ grammar );
200
+
201
+ if (! $ this ->creating ()) {
202
+ $ this ->commands = array_map (
203
+ fn ($ command ) => $ command instanceof ColumnDefinition
204
+ ? $ this ->createCommand ($ command ->change ? 'change ' : 'add ' , ['column ' => $ command ])
205
+ : $ command ,
206
+ $ this ->commands
207
+ );
208
+
209
+ $ this ->addAlterCommands ($ connection , $ grammar );
210
+ }
194
211
}
195
212
196
213
/**
@@ -260,6 +277,48 @@ public function addFluentCommands(Connection $connection, Grammar $grammar)
260
277
}
261
278
}
262
279
280
+ /**
281
+ * Add the alter commands if whenever needed.
282
+ *
283
+ * @param \Illuminate\Database\Connection $connection
284
+ * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
285
+ * @return void
286
+ */
287
+ public function addAlterCommands (Connection $ connection , Grammar $ grammar )
288
+ {
289
+ if (! $ grammar instanceof SQLiteGrammar) {
290
+ return ;
291
+ }
292
+
293
+ $ alterCommands = $ grammar ->getAlterCommands ($ connection );
294
+
295
+ [$ commands , $ lastCommandWasAlter , $ hasAlterCommand ] = [
296
+ [], false , false ,
297
+ ];
298
+
299
+ foreach ($ this ->commands as $ command ) {
300
+ if (in_array ($ command ->name , $ alterCommands )) {
301
+ $ hasAlterCommand = true ;
302
+ $ lastCommandWasAlter = true ;
303
+ } elseif ($ lastCommandWasAlter ) {
304
+ $ commands [] = $ this ->createCommand ('alter ' );
305
+ $ lastCommandWasAlter = false ;
306
+ }
307
+
308
+ $ commands [] = $ command ;
309
+ }
310
+
311
+ if ($ lastCommandWasAlter ) {
312
+ $ commands [] = $ this ->createCommand ('alter ' );
313
+ }
314
+
315
+ if ($ hasAlterCommand ) {
316
+ $ this ->state = new BlueprintState ($ this , $ connection , $ grammar );
317
+ }
318
+
319
+ $ this ->commands = $ commands ;
320
+ }
321
+
263
322
/**
264
323
* Determine if the blueprint has a create command.
265
324
*
@@ -1634,6 +1693,10 @@ protected function addColumnDefinition($definition)
1634
1693
{
1635
1694
$ this ->columns [] = $ definition ;
1636
1695
1696
+ if (! $ this ->creating ()) {
1697
+ $ this ->commands [] = $ definition ;
1698
+ }
1699
+
1637
1700
if ($ this ->after ) {
1638
1701
$ definition ->after ($ this ->after );
1639
1702
@@ -1671,6 +1734,10 @@ public function removeColumn($name)
1671
1734
return $ c ['name ' ] != $ name ;
1672
1735
}));
1673
1736
1737
+ $ this ->commands = array_values (array_filter ($ this ->commands , function ($ c ) use ($ name ) {
1738
+ return ! $ c instanceof ColumnDefinition || $ c ['name ' ] != $ name ;
1739
+ }));
1740
+
1674
1741
return $ this ;
1675
1742
}
1676
1743
@@ -1740,6 +1807,27 @@ public function getCommands()
1740
1807
return $ this ->commands ;
1741
1808
}
1742
1809
1810
+ /*
1811
+ * Determine if the blueprint has state.
1812
+ *
1813
+ * @param mixed $name
1814
+ * @return bool
1815
+ */
1816
+ private function hasState (): bool
1817
+ {
1818
+ return ! is_null ($ this ->state );
1819
+ }
1820
+
1821
+ /**
1822
+ * Get the state of the blueprint.
1823
+ *
1824
+ * @return \Illuminate\Database\Schema\BlueprintState
1825
+ */
1826
+ public function getState ()
1827
+ {
1828
+ return $ this ->state ;
1829
+ }
1830
+
1743
1831
/**
1744
1832
* Get the columns on the blueprint that should be added.
1745
1833
*
@@ -1755,6 +1843,8 @@ public function getAddedColumns()
1755
1843
/**
1756
1844
* Get the columns on the blueprint that should be changed.
1757
1845
*
1846
+ * @deprecated Will be removed in a future Laravel version.
1847
+ *
1758
1848
* @return \Illuminate\Database\Schema\ColumnDefinition[]
1759
1849
*/
1760
1850
public function getChangedColumns ()
0 commit comments