From: Côme Chilliet Date: Fri, 3 Mar 2023 09:35:50 +0000 (+0100) Subject: Add chunking in SystemTagObjectMapper::getTagIdsForObjects X-Git-Tag: v27.0.0beta1~344^2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=refs%2Fpull%2F37029%2Fhead;p=nextcloud-server.git Add chunking in SystemTagObjectMapper::getTagIdsForObjects This avoids crashing on Oracle with more than 1000 objects Signed-off-by: Côme Chilliet --- diff --git a/lib/private/SystemTag/SystemTagObjectMapper.php b/lib/private/SystemTag/SystemTagObjectMapper.php index 5a09a1754f2..b61a81a1fa7 100644 --- a/lib/private/SystemTag/SystemTagObjectMapper.php +++ b/lib/private/SystemTag/SystemTagObjectMapper.php @@ -77,23 +77,25 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper { ->from(self::RELATION_TABLE) ->where($query->expr()->in('objectid', $query->createParameter('objectids'))) ->andWhere($query->expr()->eq('objecttype', $query->createParameter('objecttype'))) - ->setParameter('objectids', $objIds, IQueryBuilder::PARAM_STR_ARRAY) ->setParameter('objecttype', $objectType) ->addOrderBy('objectid', 'ASC') ->addOrderBy('systemtagid', 'ASC'); - + $chunks = array_chunk($objIds, 900, false); $mapping = []; foreach ($objIds as $objId) { $mapping[$objId] = []; } + foreach ($chunks as $chunk) { + $query->setParameter('objectids', $chunk, IQueryBuilder::PARAM_STR_ARRAY); + $result = $query->executeQuery(); + while ($row = $result->fetch()) { + $objectId = $row['objectid']; + $mapping[$objectId][] = $row['systemtagid']; + } - $result = $query->execute(); - while ($row = $result->fetch()) { - $objectId = $row['objectid']; - $mapping[$objectId][] = $row['systemtagid']; + $result->closeCursor(); } - $result->closeCursor(); return $mapping; } diff --git a/tests/lib/SystemTag/SystemTagObjectMapperTest.php b/tests/lib/SystemTag/SystemTagObjectMapperTest.php index c988db69c30..e77709c781f 100644 --- a/tests/lib/SystemTag/SystemTagObjectMapperTest.php +++ b/tests/lib/SystemTag/SystemTagObjectMapperTest.php @@ -141,6 +141,17 @@ class SystemTagObjectMapperTest extends TestCase { $this->assertEquals([], $tagIdMapping); } + public function testGetTagIdsForALotOfObjects() { + $ids = range(1, 10500); + $tagIdMapping = $this->tagMapper->getTagIdsForObjects( + $ids, + 'testtype' + ); + + $this->assertEquals(10500, count($tagIdMapping)); + $this->assertEquals([$this->tag1->getId(), $this->tag2->getId()], $tagIdMapping[1]); + } + public function testGetObjectsForTags() { $objectIds = $this->tagMapper->getObjectIdsForTags( [$this->tag1->getId(), $this->tag2->getId(), $this->tag3->getId()], @@ -165,7 +176,7 @@ class SystemTagObjectMapperTest extends TestCase { ], $objectIds); } - + public function testGetObjectsForTagsLimitWithMultipleTags() { $this->expectException(\InvalidArgumentException::class); @@ -189,7 +200,7 @@ class SystemTagObjectMapperTest extends TestCase { ], $objectIds); } - + public function testGetObjectsForNonExistingTag() { $this->expectException(\OCP\SystemTag\TagNotFoundException::class); @@ -227,7 +238,7 @@ class SystemTagObjectMapperTest extends TestCase { $this->assertTrue(true, 'No error when reassigning/unassigning'); } - + public function testAssignNonExistingTags() { $this->expectException(\OCP\SystemTag\TagNotFoundException::class); @@ -254,7 +265,7 @@ class SystemTagObjectMapperTest extends TestCase { ], $tagIdMapping, 'None of the tags got assigned'); } - + public function testUnassignNonExistingTags() { $this->expectException(\OCP\SystemTag\TagNotFoundException::class); @@ -385,7 +396,7 @@ class SystemTagObjectMapperTest extends TestCase { ); } - + public function testHaveTagNonExisting() { $this->expectException(\OCP\SystemTag\TagNotFoundException::class);