Skip to content

fix(migration): support the new OCP DB schema API - #13459

Open
ChristophWurst wants to merge 1 commit into
mainfrom
fix/migration-gettable-itable-type
Open

fix(migration): support the new OCP DB schema API#13459
ChristophWurst wants to merge 1 commit into
mainfrom
fix/migration-gettable-itable-type

Conversation

@ChristophWurst

Copy link
Copy Markdown
Member

OCP's ISchemaWrapper::getTable() now returns OCP\DB\Schema\ITable instead of Doctrine\DBAL\Schema\Table on newer server versions. Widen the addMailboxKey() parameter types to Table|ITable so the migration works on both, and suppress the not-yet-vendored ITable stub in psalm.

Assisted-by: Claude:claude-opus-4-8

Ref nextcloud/server#63013

馃 AI (if applicable)

  • The content of this PR was partly or fully generated using AI

@ChristophWurst

Copy link
Copy Markdown
Member Author

/backport to stable5.11

@ChristophWurst

Copy link
Copy Markdown
Member Author

/backport to stable5.10

@ChristophWurst
ChristophWurst removed the request for review from GretaD August 11, 2026 07:23
@ChristophWurst

Copy link
Copy Markdown
Member Author

There are more changes necessary to make Psalm happy, but there are also legit gaps.

  1. There is no replacement to enumerate all foreign keys:
    $fks = $attachmentsTable->getForeignKeys();
  2. ModifyColumn changed in a breaking way. It's not possible to be compatible with 34 and 35 at the same time:
    $recipientsTable->modifyColumn('id', [
    'type' => Type::getType(Types::BIGINT),
    ]);

@CarlSchwan

Copy link
Copy Markdown
Member

There are more changes necessary to make Psalm happy, but there are also legit gaps.

1. There is no replacement to enumerate all foreign keys: https://github.com/nextcloud/mail/blob/1968041ebcbd120bfce97be65d40fe636428252b/lib/Migration/Version1130Date20220412111833.php#L116

This should still work, since getForeignKeys is not implemented in Table, it's forwarding the method call to the DBAL Table via the __call in OC\DB\Schema\Table

2. ModifyColumn changed in a breaking way. It's not possible to be compatible with 34 and 35 at the same time: https://github.com/nextcloud/mail/blob/1968041ebcbd120bfce97be65d40fe636428252b/lib/Migration/Version1130Date20220412111833.php#L129-L131

Same, modifyColumn in OCP\DB\Schema, has some more strict type hints but at runtime this should still work as it is just forwarding the arguments.

@CarlSchwan

Copy link
Copy Markdown
Member

Looking at the latest psalm issues, I probably went to far for requiring non empty lowercase string for index. I will change that

@nextcloud-command nextcloud-command added the AI assisted This PR contains AI-assisted commits label Aug 12, 2026
@CarlSchwan

Copy link
Copy Markdown
Member

Last psalm issue seems to be a false positive from psalm

*/
foreach ($mailboxesTable->getIndexes() as $index) {
if ($index->isUnique() && $index->spansColumns(['account_id', 'name'])) {
if ($index->isUnique() && $index->getColumns() === ['account_id', 'name']) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to also expose spansColumns because it ignores the order.

As hardening we should array diff expected and actual columns and test for an empty array.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the other matters. An index on [a,b] is very different from [b,a].

For this specific case we only need to catch the condition where the ordering is [account_id, name], right?

@kesselb kesselb Aug 16, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spansColumns does not ignore the order.
The change can be reverted, spansColumns is part of IIndex now.

Comment on lines -62 to -74
'precision' => 10,
'scale' => 5,
]);
])->setPrecision(10)->setScale(5);
$table->addColumn('precision_important', Types::DECIMAL, [
'notnull' => true,
'precision' => 10,
'scale' => 5,
]);
])->setPrecision(10)->setScale(5);
$table->addColumn('f1_score_important', Types::DECIMAL, [
'notnull' => true,
'precision' => 10,
'scale' => 5,
]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be reverted, last version support precision and scale

Comment on lines -64 to +77
$accountsSignatureColumn = $accountsTable->getColumn('signature');

$this->connection->executeStatement(
sprintf($alterQuery, $accountsTable->getName(), $accountsSignatureColumn->getName())
sprintf($alterQuery, $accountsTable->getName(), 'signature')
);

$aliasesTable = $schema->getTable('mail_aliases');
$aliasesSignatureColumn = $accountsTable->getColumn('signature');

$this->connection->executeStatement(
sprintf($alterQuery, $aliasesTable->getName(), $aliasesSignatureColumn->getName())
sprintf($alterQuery, $aliasesTable->getName(), 'signature')
);

unset(
$accountsTable,
$accountsSignatureColumn,
$aliasesTable,
$aliasesSignatureColumn
$aliasesTable

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here getName return a non-empty-string

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is that IColumn::getName does not exist. It works because of __call but Psalm won't like it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread lib/Migration/Version5006Date20251015082003.php
@ChristophWurst
ChristophWurst force-pushed the fix/migration-gettable-itable-type branch from d4e6d22 to 0deecae Compare August 17, 2026 13:28
@ChristophWurst ChristophWurst changed the title fix(migration): accept ITable from getTable() in addMailboxKey fix(migration): support the new OCP DB schema API Aug 17, 2026
ISchemaWrapper::getTable() now returns OCP\DB\Schema\ITable instead of
the Doctrine Table on server 35+. Widen addMailboxKey() to accept both
so the migrations keep running on server 32-35, and reference the
foreign table and column by name so the call type-checks against the
stricter interface.

Replace the Doctrine-only calls the reduced interface no longer exposes:
a column-name literal instead of IColumn::getName(), and getPrimaryKey()
instead of hasPrimaryKey(). Fix the mis-cased notNull option on
classification_enabled so the boolean column stays nullable, which the
new schema validation now enforces.

Constrain the sort direction in MessageMapper::findByIds() to a literal
so it satisfies IQueryBuilder::orderBy()'s tightened, taint-checked
parameter. Normalizing in one place keeps every caller working and
avoids threading a direction type through the search stack.

ITable exists only in the newer OCP stubs, so it is suppressed in psalm
for the older matrix versions. Version1130's foreign-key enumeration and
column type change forward to Doctrine at runtime and were handled
server-side, so that migration is left unchanged.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Christoph Wurst <1374172+ChristophWurst@users.noreply.github.com>
@ChristophWurst
ChristophWurst force-pushed the fix/migration-gettable-itable-type branch from 0deecae to b5283cf Compare August 18, 2026 14:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants