diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 6bde7ba7d1117..5094a3d3bd80f 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -2988,7 +2988,7 @@ public function deleteOutdatedSchedulingObjects(int $modifiedBefore, int $limit) $deleteQuery = $this->db->getQueryBuilder(); $deleteQuery->delete('schedulingobjects') ->where($deleteQuery->expr()->in('id', $deleteQuery->createParameter('ids'), IQueryBuilder::PARAM_INT_ARRAY)); - foreach (array_chunk($ids, 1000) as $chunk) { + foreach (array_chunk($ids, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) { $deleteQuery->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $numDeleted += $deleteQuery->executeStatement(); } @@ -3523,7 +3523,7 @@ public function purgeCachedEventsForSubscription(int $subscriptionId, array $cal } $this->atomic(function () use ($subscriptionId, $calendarObjectIds, $calendarObjectUris): void { - foreach (array_chunk($calendarObjectIds, 1000) as $chunk) { + foreach (array_chunk($calendarObjectIds, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) { $query = $this->db->getQueryBuilder(); $query->delete($this->dbObjectPropertiesTable) ->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId))) @@ -3539,7 +3539,7 @@ public function purgeCachedEventsForSubscription(int $subscriptionId, array $cal ->executeStatement(); } - foreach (array_chunk($calendarObjectUris, 1000) as $chunk) { + foreach (array_chunk($calendarObjectUris, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) { $query = $this->db->getQueryBuilder(); $query->delete('calendarchanges') ->where($query->expr()->eq('calendarid', $query->createNamedParameter($subscriptionId))) diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php index 140a1b44fa169..c21b1c9c576e2 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -1268,7 +1268,7 @@ private function searchByAddressBookIds(array $addressBookIds, ->from($this->dbCardsTable, 'c') ->where($query->expr()->in('c.id', $query->createParameter('matches'))); - foreach (array_chunk($matches, 1000) as $matchesChunk) { + foreach (array_chunk($matches, IQueryBuilder::MAX_IN_PARAMETERS) as $matchesChunk) { $query->setParameter('matches', $matchesChunk, IQueryBuilder::PARAM_INT_ARRAY); $result = $query->executeQuery(); $cardResults[] = $result->fetchAllAssociative(); diff --git a/apps/dav/lib/DAV/CustomPropertiesBackend.php b/apps/dav/lib/DAV/CustomPropertiesBackend.php index 698fdee496ea8..5fac0b17dff27 100644 --- a/apps/dav/lib/DAV/CustomPropertiesBackend.php +++ b/apps/dav/lib/DAV/CustomPropertiesBackend.php @@ -497,7 +497,7 @@ private function getUserProperties(string $path, array $requestedProperties): ar if (!empty($requestedProperties)) { // request only a subset $qb->andWhere($qb->expr()->in('propertyname', $qb->createParameter('requestedProperties'))); - $chunks = array_chunk($requestedProperties, 1000); + $chunks = array_chunk($requestedProperties, IQueryBuilder::MAX_IN_PARAMETERS); foreach ($chunks as $chunk) { $qb->setParameter('requestedProperties', $chunk, IQueryBuilder::PARAM_STR_ARRAY); $result = $qb->executeQuery(); diff --git a/apps/files_sharing/lib/SharesReminderJob.php b/apps/files_sharing/lib/SharesReminderJob.php index 1a1ee1873902d..4ec9aabe716ea 100644 --- a/apps/files_sharing/lib/SharesReminderJob.php +++ b/apps/files_sharing/lib/SharesReminderJob.php @@ -35,7 +35,6 @@ */ class SharesReminderJob extends TimedJob { private const SECONDS_BEFORE_REMINDER = 24 * 60 * 60; - private const CHUNK_SIZE = 1000; private int $folderMimeTypeId; public function __construct( @@ -131,7 +130,7 @@ private function getSharesData(): array { $qb->expr()->isNull('f.fileid') ) ) - ->setMaxResults(SharesReminderJob::CHUNK_SIZE); + ->setMaxResults(IQueryBuilder::MAX_IN_PARAMETERS); $shares = $qb->executeQuery()->fetchAllAssociative(); return array_map(fn ($share): array => [ @@ -178,7 +177,7 @@ private function getSharesDataSharded(): array|\Iterator { 'share_type' => (int)$share['share_type'], 'file_source' => (int)$share['file_source'], ], $shares); - return $this->filterSharesWithEmptyFolders($shares, self::CHUNK_SIZE); + return $this->filterSharesWithEmptyFolders($shares, IQueryBuilder::MAX_IN_PARAMETERS); } /** @@ -193,7 +192,7 @@ private function filterSharesWithEmptyFolders(array $shares, int $maxResults): a ->where($query->expr()->eq('size', $query->createNamedParameter(0), IQueryBuilder::PARAM_INT_ARRAY)) ->andWhere($query->expr()->eq('mimetype', $query->createNamedParameter($this->folderMimeTypeId, IQueryBuilder::PARAM_INT))) ->andWhere($query->expr()->in('fileid', $query->createParameter('fileids'))); - $chunks = array_chunk($shares, SharesReminderJob::CHUNK_SIZE); + $chunks = array_chunk($shares, IQueryBuilder::MAX_IN_PARAMETERS); $results = []; foreach ($chunks as $chunk) { $chunkFileIds = array_map(fn ($share): int => $share['file_source'], $chunk); diff --git a/apps/user_ldap/lib/Db/GroupMembershipMapper.php b/apps/user_ldap/lib/Db/GroupMembershipMapper.php index c81ee7010aeea..447ae811b9d1a 100644 --- a/apps/user_ldap/lib/Db/GroupMembershipMapper.php +++ b/apps/user_ldap/lib/Db/GroupMembershipMapper.php @@ -64,7 +64,7 @@ public function deleteGroups(array $removedGroups): void { $query->delete($this->getTableName()) ->where($query->expr()->in('groupid', $query->createParameter('groupids'))); - foreach (array_chunk($removedGroups, 1000) as $removedGroupsChunk) { + foreach (array_chunk($removedGroups, IQueryBuilder::MAX_IN_PARAMETERS) as $removedGroupsChunk) { $query->setParameter('groupids', $removedGroupsChunk, IQueryBuilder::PARAM_STR_ARRAY); $query->executeStatement(); } diff --git a/lib/private/Comments/Manager.php b/lib/private/Comments/Manager.php index c6857162f2bee..3f00a16d5913d 100644 --- a/lib/private/Comments/Manager.php +++ b/lib/private/Comments/Manager.php @@ -703,7 +703,7 @@ public function getNumberOfUnreadCommentsForObjects(string $objectType, array $o } $unreadComments = array_fill_keys($objectIds, 0); - foreach (array_chunk($objectIds, 1000) as $chunk) { + foreach (array_chunk($objectIds, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) { $query->setParameter('ids', $chunk, IQueryBuilder::PARAM_STR_ARRAY); $result = $query->executeQuery(); diff --git a/lib/private/DB/QueryBuilder/Sharded/CrossShardMoveHelper.php b/lib/private/DB/QueryBuilder/Sharded/CrossShardMoveHelper.php index 3cd1c90da2424..8d38785d3b8db 100644 --- a/lib/private/DB/QueryBuilder/Sharded/CrossShardMoveHelper.php +++ b/lib/private/DB/QueryBuilder/Sharded/CrossShardMoveHelper.php @@ -85,7 +85,7 @@ public function loadItems(IDBConnection $connection, string $table, string $prim ->from($table) ->where($query->expr()->in($primaryColumn, $query->createParameter('keys'))); - $chunks = array_chunk($primaryKeys, 1000); + $chunks = array_chunk($primaryKeys, IQueryBuilder::MAX_IN_PARAMETERS); $results = []; foreach ($chunks as $chunk) { @@ -152,7 +152,7 @@ public function deleteItems(IDBConnection $connection, string $table, string $pr $query = $connection->getQueryBuilder(); $query->delete($table) ->where($query->expr()->in($primaryColumn, $query->createParameter('keys'))); - $chunks = array_chunk($primaryKeys, 1000); + $chunks = array_chunk($primaryKeys, IQueryBuilder::MAX_IN_PARAMETERS); foreach ($chunks as $chunk) { $query->setParameter('keys', $chunk, IQueryBuilder::PARAM_INT_ARRAY); diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index 9a897ba68bc3c..e75926dea8b1e 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -619,7 +619,7 @@ private function removeChildren(ICacheEntry $entry) { ->where($query->expr()->in('fileid', $query->createParameter('childIds'))) ->hintShardKey('storage', $this->getNumericStorageId()); - foreach (array_chunk($childIds, 1000) as $childIdChunk) { + foreach (array_chunk($childIds, IQueryBuilder::MAX_IN_PARAMETERS) as $childIdChunk) { $query->setParameter('childIds', $childIdChunk, IQueryBuilder::PARAM_INT_ARRAY); $query->executeStatement(); } @@ -645,13 +645,13 @@ private function removeChildren(ICacheEntry $entry) { // Sorting before chunking allows the db to find the entries close to each // other in the index sort($parentIds, SORT_NUMERIC); - foreach (array_chunk($parentIds, 1000) as $parentIdChunk) { + foreach (array_chunk($parentIds, IQueryBuilder::MAX_IN_PARAMETERS) as $parentIdChunk) { $query->setParameter('parentIds', $parentIdChunk, IQueryBuilder::PARAM_INT_ARRAY); $query->executeStatement(); } $cacheEntryRemovedEvents = []; - foreach (array_chunk(array_combine($deletedIds, $deletedPaths), 1000) as $chunk) { + foreach (array_chunk(array_combine($deletedIds, $deletedPaths), IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) { /** @var array $chunk */ foreach ($chunk as $fileId => $filePath) { $cacheEntryRemovedEvents[] = new CacheEntryRemovedEvent( @@ -760,7 +760,7 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) { $childIds = $this->getChildIds($sourceStorageId, $sourcePath); - $childChunks = array_chunk($childIds, 1000); + $childChunks = array_chunk($childIds, IQueryBuilder::MAX_IN_PARAMETERS); $query = $this->getQueryBuilder(); diff --git a/lib/private/Files/Cache/Propagator.php b/lib/private/Files/Cache/Propagator.php index 722866dd1b349..82fccfd4a639f 100644 --- a/lib/private/Files/Cache/Propagator.php +++ b/lib/private/Files/Cache/Propagator.php @@ -206,7 +206,7 @@ public function commitBatch(): void { // queries as a faster lookup than the path_hash $hashes = array_map(static fn (array $a): string => $a['hash'], $this->batch); - foreach (array_chunk($hashes, 1000) as $hashesChunk) { + foreach (array_chunk($hashes, IQueryBuilder::MAX_IN_PARAMETERS) as $hashesChunk) { $query = $this->connection->getQueryBuilder(); $result = $query->select('fileid', 'path', 'path_hash', 'size') ->from('filecache') diff --git a/lib/private/Files/Cache/StorageGlobal.php b/lib/private/Files/Cache/StorageGlobal.php index 6efefc149adb4..693a82be52f5b 100644 --- a/lib/private/Files/Cache/StorageGlobal.php +++ b/lib/private/Files/Cache/StorageGlobal.php @@ -45,7 +45,7 @@ public function loadForStorageIds(array $storageIds): void { ->from('storages') ->where($builder->expr()->in('id', $builder->createParameter('ids'), IQueryBuilder::PARAM_STR_ARRAY)); - foreach (array_chunk($storageIds, 1000) as $chunk) { + foreach (array_chunk($storageIds, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) { $query->setParameter('ids', $chunk, IQueryBuilder::PARAM_STR_ARRAY); $result = $query->executeQuery(); diff --git a/lib/private/Files/Search/QueryOptimizer/SplitLargeIn.php b/lib/private/Files/Search/QueryOptimizer/SplitLargeIn.php index b4c51643c2f08..499dc9b88aa39 100644 --- a/lib/private/Files/Search/QueryOptimizer/SplitLargeIn.php +++ b/lib/private/Files/Search/QueryOptimizer/SplitLargeIn.php @@ -9,6 +9,7 @@ use OC\Files\Search\SearchBinaryOperator; use OC\Files\Search\SearchComparison; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\Search\ISearchBinaryOperator; use OCP\Files\Search\ISearchComparison; use OCP\Files\Search\ISearchOperator; @@ -22,9 +23,9 @@ public function processOperator(ISearchOperator &$operator): bool { if ( $operator instanceof ISearchComparison && $operator->getType() === ISearchComparison::COMPARE_IN - && count($operator->getValue()) > 1000 + && count($operator->getValue()) > IQueryBuilder::MAX_IN_PARAMETERS ) { - $chunks = array_chunk($operator->getValue(), 1000); + $chunks = array_chunk($operator->getValue(), IQueryBuilder::MAX_IN_PARAMETERS); $chunkComparisons = array_map(function (array $values) use ($operator) { return new SearchComparison(ISearchComparison::COMPARE_IN, $operator->getField(), $values, $operator->getExtra()); }, $chunks); diff --git a/lib/private/Files/SetupManager.php b/lib/private/Files/SetupManager.php index a8c46a20bd31a..86ad3ec08bffb 100644 --- a/lib/private/Files/SetupManager.php +++ b/lib/private/Files/SetupManager.php @@ -28,6 +28,7 @@ use OCA\Files_Sharing\SharedMount; use OCP\App\IAppManager; use OCP\Constants; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Diagnostics\IEventLogger; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Config\IAuthoritativeMountProvider; @@ -605,7 +606,7 @@ public function setupForPath(string $path, bool $includeChildren = false): void ); $rootsMetadata = []; - foreach (array_chunk($rootIds, 1000) as $chunk) { + foreach (array_chunk($rootIds, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) { foreach ($this->fileAccess->getByFileIds($chunk) as $id => $fileMetadata) { $rootsMetadata[$id] = $fileMetadata; } diff --git a/lib/private/FilesMetadata/Service/IndexRequestService.php b/lib/private/FilesMetadata/Service/IndexRequestService.php index 90c2845cad283..bbf6185007175 100644 --- a/lib/private/FilesMetadata/Service/IndexRequestService.php +++ b/lib/private/FilesMetadata/Service/IndexRequestService.php @@ -186,7 +186,7 @@ public function dropIndex(int $fileId, string $key = ''): void { * @throws DbException */ public function dropIndexForFiles(array $fileIds, string $key = ''): void { - $chunks = array_chunk($fileIds, 1000); + $chunks = array_chunk($fileIds, IQueryBuilder::MAX_IN_PARAMETERS); foreach ($chunks as $chunk) { $qb = $this->dbConnection->getQueryBuilder(); diff --git a/lib/private/FilesMetadata/Service/MetadataRequestService.php b/lib/private/FilesMetadata/Service/MetadataRequestService.php index c274c70812d12..223bcee8d942c 100644 --- a/lib/private/FilesMetadata/Service/MetadataRequestService.php +++ b/lib/private/FilesMetadata/Service/MetadataRequestService.php @@ -150,7 +150,7 @@ public function dropMetadata(int $fileId): void { * @throws Exception */ public function dropMetadataForFiles(int $storage, array $fileIds): void { - $chunks = array_chunk($fileIds, 1000); + $chunks = array_chunk($fileIds, IQueryBuilder::MAX_IN_PARAMETERS); foreach ($chunks as $chunk) { $qb = $this->dbConnection->getQueryBuilder(); diff --git a/lib/private/Group/Database.php b/lib/private/Group/Database.php index fb83ea8df1954..c3e6df7cc3038 100644 --- a/lib/private/Group/Database.php +++ b/lib/private/Group/Database.php @@ -342,7 +342,7 @@ public function groupsExists(array $gids): array { $qb->select('gid', 'displayname') ->from('groups') ->where($qb->expr()->in('gid', $qb->createParameter('ids'))); - foreach (array_chunk($notFoundGids, 1000) as $chunk) { + foreach (array_chunk($notFoundGids, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) { $qb->setParameter('ids', $chunk, IQueryBuilder::PARAM_STR_ARRAY); $result = $qb->executeQuery(); while ($row = $result->fetch()) { @@ -553,7 +553,7 @@ public function getGroupsDetails(array $gids): array { } } - foreach (array_chunk($notFoundGids, 1000) as $chunk) { + foreach (array_chunk($notFoundGids, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) { $query = $this->dbConn->getQueryBuilder(); $query->select('gid', 'displayname') ->from('groups') diff --git a/lib/private/Preview/Storage/LocalPreviewStorage.php b/lib/private/Preview/Storage/LocalPreviewStorage.php index 13e6a7145167b..99427b74b2901 100644 --- a/lib/private/Preview/Storage/LocalPreviewStorage.php +++ b/lib/private/Preview/Storage/LocalPreviewStorage.php @@ -315,7 +315,7 @@ private function fetchFilecacheByFileIds(array $fileIds): array { ->from('filecache') ->where($qb->expr()->in('fileid', $qb->createParameter('fileIds'))) ->runAcrossAllShards(); - foreach (array_chunk($fileIds, 1000) as $chunk) { + foreach (array_chunk($fileIds, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) { $qb->setParameter('fileIds', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $rows = $qb->executeQuery(); while ($row = $rows->fetchAssociative()) { @@ -342,7 +342,7 @@ private function fetchFilecacheByPathHashes(array $pathHashes): array { ->from('filecache') ->where($qb->expr()->in('path_hash', $qb->createParameter('pathHashes'))) ->runAcrossAllShards(); - foreach (array_chunk($pathHashes, 1000) as $chunk) { + foreach (array_chunk($pathHashes, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) { $qb->setParameter('pathHashes', $chunk, IQueryBuilder::PARAM_STR_ARRAY); $rows = $qb->executeQuery(); while ($row = $rows->fetchAssociative()) { diff --git a/lib/private/Repair/RemoveBrokenProperties.php b/lib/private/Repair/RemoveBrokenProperties.php index 0e2a7318f22c7..1685ac63c91f8 100644 --- a/lib/private/Repair/RemoveBrokenProperties.php +++ b/lib/private/Repair/RemoveBrokenProperties.php @@ -51,7 +51,7 @@ public function run(IOutput $output): void { $qb = $this->db->getQueryBuilder(); $qb->delete('properties') ->where($qb->expr()->in('id', $qb->createParameter('ids'), IQueryBuilder::PARAM_STR_ARRAY)); - foreach (array_chunk($brokenIds, 1000) as $chunkIds) { + foreach (array_chunk($brokenIds, IQueryBuilder::MAX_IN_PARAMETERS) as $chunkIds) { $qb->setParameter('ids', $chunkIds, IQueryBuilder::PARAM_STR_ARRAY); $qb->executeStatement(); } diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php index cb91a44e60290..2944bbff43ebf 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -685,7 +685,7 @@ private function getSharesInFolderInternal(?string $userId, Folder $node, ?bool $shares = []; - $chunks = array_chunk($childMountRootIds, 1000); + $chunks = array_chunk($childMountRootIds, IQueryBuilder::MAX_IN_PARAMETERS); // Force the request to be run when there is 0 mount. if (count($chunks) === 0) { diff --git a/lib/private/TagManager.php b/lib/private/TagManager.php index f7895c516526b..4643d46cccd6b 100644 --- a/lib/private/TagManager.php +++ b/lib/private/TagManager.php @@ -128,7 +128,7 @@ public function handle(Event $event): void { $qb1 = $qb1->delete('vcategory') ->where($qb1->expr()->in('uid', $qb1->createParameter('chunk'))); - foreach (array_chunk($tagsIds, 1000) as $tagChunk) { + foreach (array_chunk($tagsIds, IQueryBuilder::MAX_IN_PARAMETERS) as $tagChunk) { $qb->setParameter('chunk', $tagChunk, IQueryBuilder::PARAM_INT_ARRAY); $qb1->setParameter('chunk', $tagChunk, IQueryBuilder::PARAM_INT_ARRAY); try { diff --git a/lib/public/DB/QueryBuilder/IQueryBuilder.php b/lib/public/DB/QueryBuilder/IQueryBuilder.php index a999150d4529b..89d6b61e0abdf 100644 --- a/lib/public/DB/QueryBuilder/IQueryBuilder.php +++ b/lib/public/DB/QueryBuilder/IQueryBuilder.php @@ -120,6 +120,14 @@ interface IQueryBuilder { */ public const MAX_ROW_DELETION = 100000; + /** + * @since 35.0.0 Indicates how many parameters can be passed to a IN query + * with Oracle database server. + * + * Mostly useful as magic value to give to array_chunk + */ + public const MAX_IN_PARAMETERS = 1000; + /** * Enable/disable automatic prefixing of table names with the oc_ prefix *