]> source.dussan.org Git - nextcloud-server.git/commitdiff
Add chunking in SystemTagObjectMapper::getTagIdsForObjects 37029/head
authorCôme Chilliet <come.chilliet@nextcloud.com>
Fri, 3 Mar 2023 09:35:50 +0000 (10:35 +0100)
committerCôme Chilliet (Rebase PR Action) <come-nc@users.noreply.github.com>
Mon, 13 Mar 2023 17:36:10 +0000 (17:36 +0000)
This avoids crashing on Oracle with more than 1000 objects

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
lib/private/SystemTag/SystemTagObjectMapper.php
tests/lib/SystemTag/SystemTagObjectMapperTest.php

index 5a09a1754f27a086f94b03c284a09c2bed5469e5..b61a81a1fa701986d3307b1c90b2a5de7d01f72a 100644 (file)
@@ -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;
        }
index c988db69c304b9f97dcd38e8687ffb0d7bbde299..e77709c781fcc31161ecfa3a5cf64812443a5785 100644 (file)
@@ -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);