You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/db/ColumnSchema.php
+20
Original file line number
Diff line number
Diff line change
@@ -25,4 +25,24 @@ class ColumnSchema extends \yii\db\ColumnSchema
25
25
* ```
26
26
*/
27
27
public$xDbType;
28
+
29
+
/**
30
+
* Used only for MySQL/MariaDB
31
+
* @var array|null
32
+
* [
33
+
* index => int # position: starts from 1
34
+
* after => ?string # after column
35
+
* before => ?string # before column
36
+
* ]
37
+
* If `before` is null then column is last
38
+
* If `after` is null then column is first
39
+
* If both are null then table has only 1 column
40
+
*/
41
+
public ?array$fromPosition = null;
42
+
public ?array$toPosition = null;
43
+
44
+
/**
45
+
* From `$this->fromPosition` and `$this->toPosition` we can check if the position is changed or not. This is done in `BaseMigrationBuilder::setColumnsPositions()`
if (!isset($columnNames[$key+1])) { // if new col is added at last then no need to add 'AFTER' SQL part. This is checked as if next column is present or not
532
-
returnnull;
533
-
}
534
-
535
-
// in case of `down()` code of migration, putting 'after <colName>' in add column statmenet is erroneous because <colName> may not exist.
536
-
// Example: From col a, b, c, d, if I drop c and d then their migration code will be generated like:
537
-
// `up()` code
538
-
// drop c
539
-
// drop d
540
-
// `down()` code
541
-
// add d after c (c does not exist! Error!)
542
-
// add c
543
-
if ($forDrop) {
544
-
returnnull;
545
-
}
546
-
547
-
548
-
returnself::POS_AFTER . '' . $prevColName;
549
-
550
-
// if no `$columnSchema` is found, previous column does not exist. This happens when 'after column' is not yet added in migration or added after currently undertaken column
if (($key === count($columnNames) - 1) && !$forAlter) {
184
+
returnnull;
185
+
}
186
+
187
+
if (array_key_exists($prevColName, $forDrop ? $this->tableSchema->columns : $this->newColumns)) {
188
+
if ($forDrop && !$forAlter) {
189
+
// if the previous column is the last one in the want names then no need for AFTER
190
+
$cols = array_keys($this->newColumns);
191
+
if ($prevColName === array_pop($cols)) {
192
+
returnnull;
193
+
}
194
+
}
195
+
if ($forAlter && $forDrop) {
196
+
if (!array_key_exists($prevColName, $this->newColumns)) {
197
+
returnnull;
198
+
}
199
+
}
200
+
returnself::POS_AFTER . '' . $prevColName;
201
+
}
202
+
returnnull;
203
+
204
+
// if no `$columnSchema` is found, previous column does not exist. This happens when 'after column' is not yet added in migration or added after currently undertaken column
if ($namesForDrop && $wantNames === $haveNamesWoDropCols) {
252
+
return;
253
+
}
254
+
// check both above simultaneously
255
+
if ($namesForCreate && $namesForDrop && ($wantNamesWoNewCols === $haveNamesWoDropCols)) {
256
+
return;
257
+
}
258
+
259
+
$takenIndices = $nonRedundantIndices = []; # $nonRedundantIndices are the wanted ones which are created by moving of one or more columns. Example: if a column is moved from 2nd to 8th position then we will consider only one column is moved ignoring index/position change(-1) of 4rd to 8th column (4->3, 5->4 ...). So migration for this unwanted indices changes won't be generated. `$takenIndices` might have redundant indices
0 commit comments