Skip to content

Commit a9ec992

Browse files
fix(migration): make option_type migration self-sufficient
Version050300Date20260716000000 guarded changeSchema() against a missing option_type column but ran an unguarded UPDATE on it in postSchemaChange(), aborting occ upgrade on any instance where the column was absent. Create the column when missing and guard the backfill in both migrations. Fixes #3562 Assisted-by: Claude Code:claude-opus-5 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
1 parent db5a674 commit a9ec992

2 files changed

Lines changed: 36 additions & 9 deletions

File tree

lib/Migration/Version050300Date20250914000000.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
3434
$schema = $schemaClosure();
3535
$table = $schema->getTable('forms_v2_options');
3636

37-
if (!$table->hascolumn('option_type')) {
37+
if (!$table->hasColumn('option_type')) {
3838
$table->addColumn('option_type', Types::STRING, [
3939
'notnull' => false,
40+
'length' => 255,
4041
'default' => null,
4142
]);
4243
}
@@ -50,6 +51,12 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
5051
* @param array $options
5152
*/
5253
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
54+
/** @var ISchemaWrapper $schema */
55+
$schema = $schemaClosure();
56+
if (!$schema->getTable('forms_v2_options')->hasColumn('option_type')) {
57+
return;
58+
}
59+
5360
$qbUpdate = $this->db->getQueryBuilder();
5461

5562
$qbUpdate->update('forms_v2_options')

lib/Migration/Version050300Date20260716000000.php

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use Closure;
1313
use OCP\DB\ISchemaWrapper;
14+
use OCP\DB\Types;
1415
use OCP\IDBConnection;
1516
use OCP\Migration\IOutput;
1617
use OCP\Migration\SimpleMigrationStep;
@@ -20,6 +21,11 @@
2021
* rows that were stored without a type. Options created through the API
2122
* without an explicit optionType previously kept a null type, which the
2223
* frontend does not render.
24+
*
25+
* The column is normally created by Version050300Date20250914000000. That
26+
* migration being recorded in oc_migrations is not a guarantee that its DDL
27+
* was applied, so this step recreates the column when it is missing instead
28+
* of failing the whole upgrade.
2329
*/
2430
class Version050300Date20260716000000 extends SimpleMigrationStep {
2531

@@ -38,17 +44,25 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
3844
/** @var ISchemaWrapper $schema */
3945
$schema = $schemaClosure();
4046
$table = $schema->getTable('forms_v2_options');
41-
$changed = false;
4247

43-
if ($table->hasColumn('option_type')) {
44-
$column = $table->getColumn('option_type');
45-
if ($column->getDefault() === null) {
46-
$column->setDefault('choice');
47-
$changed = true;
48-
}
48+
if (!$table->hasColumn('option_type')) {
49+
$table->addColumn('option_type', Types::STRING, [
50+
'notnull' => false,
51+
'length' => 255,
52+
'default' => 'choice',
53+
]);
54+
55+
return $schema;
56+
}
57+
58+
$column = $table->getColumn('option_type');
59+
if ($column->getDefault() === null) {
60+
$column->setDefault('choice');
61+
62+
return $schema;
4963
}
5064

51-
return $changed ? $schema : null;
65+
return null;
5266
}
5367

5468
/**
@@ -57,6 +71,12 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
5771
* @param array $options
5872
*/
5973
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
74+
/** @var ISchemaWrapper $schema */
75+
$schema = $schemaClosure();
76+
if (!$schema->getTable('forms_v2_options')->hasColumn('option_type')) {
77+
return;
78+
}
79+
6080
$qbUpdate = $this->db->getQueryBuilder();
6181

6282
$qbUpdate->update('forms_v2_options')

0 commit comments

Comments
 (0)