fix(core): handle parameter limits in files metadata deletion

Bind each existing MAX_IN_PARAMETERS chunk in dropMetadataForFiles instead of passing the full file ID array to every query. Add a regression test that verifies the exact chunks sent to the query builder.

Resolves: #62325

Signed-off-by: Edmond <edmnd@users.noreply.github.com>
pull/62331/head
Edmond 2 weeks ago
parent e68d903945
commit 12ff385bbf
  1. 2
      lib/private/FilesMetadata/Service/MetadataRequestService.php
  2. 33
      tests/lib/FilesMetadata/FilesMetadataManagerTest.php

@ -155,7 +155,7 @@ class MetadataRequestService {
foreach ($chunks as $chunk) {
$qb = $this->dbConnection->getQueryBuilder();
$qb->delete(self::TABLE_METADATA)
->where($qb->expr()->in('file_id', $qb->createNamedParameter($fileIds, IQueryBuilder::PARAM_INT_ARRAY)))
->where($qb->expr()->in('file_id', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)))
->hintShardKey('storage', $storage);
$qb->executeStatement();
}

@ -94,4 +94,37 @@ class FilesMetadataManagerTest extends TestCase {
$this->assertEquals($file->getId(), $retrieved->getFileId());
$this->assertEquals('yes', $retrieved->getString('istest'));
}
public function testDropMetadataForFilesChunking(): void {
$connection = $this->createMock(IDBConnection::class);
$qb = $this->createMock(\OCP\DB\QueryBuilder\IQueryBuilder::class);
$expr = $this->createMock(\OCP\DB\QueryBuilder\IExpressionBuilder::class);
$connection->method('getQueryBuilder')->willReturn($qb);
$qb->method('expr')->willReturn($expr);
$qb->method('delete')->willReturnSelf();
$qb->method('where')->willReturnSelf();
$qb->method('hintShardKey')->willReturnSelf();
$fileIds = range(1, \OCP\DB\QueryBuilder\IQueryBuilder::MAX_IN_PARAMETERS * 2 + 1);
$expectedChunks = array_chunk($fileIds, \OCP\DB\QueryBuilder\IQueryBuilder::MAX_IN_PARAMETERS);
$boundChunks = [];
$qb->expects($this->exactly(count($expectedChunks)))
->method('createNamedParameter')
->willReturnCallback(function (array $chunk, $type) use (&$boundChunks): string {
$this->assertSame(\OCP\DB\QueryBuilder\IQueryBuilder::PARAM_INT_ARRAY, $type);
$boundChunks[] = $chunk;
return ':param';
});
$qb->expects($this->exactly(count($expectedChunks)))
->method('executeStatement')
->willReturn(1);
$service = new MetadataRequestService($connection, $this->logger);
$service->dropMetadataForFiles(123, $fileIds);
$this->assertSame($expectedChunks, $boundChunks);
}
}

Loading…
Cancel
Save