diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index a99e03042f5..9254ba2ad10 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -3237,7 +3237,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $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(); } @@ -3772,7 +3772,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } $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))) @@ -3788,7 +3788,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription ->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 140a1b44fa1..c21b1c9c576 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -1268,7 +1268,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { ->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 698fdee496e..5fac0b17dff 100644 --- a/apps/dav/lib/DAV/CustomPropertiesBackend.php +++ b/apps/dav/lib/DAV/CustomPropertiesBackend.php @@ -497,7 +497,7 @@ class CustomPropertiesBackend implements BackendInterface { 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 1a1ee187390..4ec9aabe716 100644 --- a/apps/files_sharing/lib/SharesReminderJob.php +++ b/apps/files_sharing/lib/SharesReminderJob.php @@ -35,7 +35,6 @@ use Psr\Log\LoggerInterface; */ 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 @@ class SharesReminderJob extends TimedJob { $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 @@ class SharesReminderJob extends TimedJob { '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 @@ class SharesReminderJob extends TimedJob { ->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 c81ee7010ae..447ae811b9d 100644 --- a/apps/user_ldap/lib/Db/GroupMembershipMapper.php +++ b/apps/user_ldap/lib/Db/GroupMembershipMapper.php @@ -64,7 +64,7 @@ class GroupMembershipMapper extends QBMapper { $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 4a34f9105d0..abd729a31b4 100644 --- a/lib/private/Comments/Manager.php +++ b/lib/private/Comments/Manager.php @@ -707,7 +707,7 @@ class Manager implements ICommentsManager { } $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 3cd1c90da24..8d38785d3b8 100644 --- a/lib/private/DB/QueryBuilder/Sharded/CrossShardMoveHelper.php +++ b/lib/private/DB/QueryBuilder/Sharded/CrossShardMoveHelper.php @@ -85,7 +85,7 @@ class CrossShardMoveHelper { ->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 @@ class CrossShardMoveHelper { $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 7f7f6458ec8..9ae5b6daf43 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -623,7 +623,7 @@ class Cache implements ICache { ->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(); } @@ -649,13 +649,13 @@ class Cache implements ICache { // 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( @@ -764,7 +764,7 @@ class Cache implements ICache { $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 722866dd1b3..82fccfd4a63 100644 --- a/lib/private/Files/Cache/Propagator.php +++ b/lib/private/Files/Cache/Propagator.php @@ -206,7 +206,7 @@ class Propagator implements IPropagator { // 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 6efefc149ad..693a82be52f 100644 --- a/lib/private/Files/Cache/StorageGlobal.php +++ b/lib/private/Files/Cache/StorageGlobal.php @@ -45,7 +45,7 @@ class StorageGlobal { ->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 b4c51643c2f..499dc9b88aa 100644 --- a/lib/private/Files/Search/QueryOptimizer/SplitLargeIn.php +++ b/lib/private/Files/Search/QueryOptimizer/SplitLargeIn.php @@ -9,6 +9,7 @@ namespace OC\Files\Search\QueryOptimizer; 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 @@ class SplitLargeIn extends ReplacingOptimizerStep { 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 a8c46a20bd3..86ad3ec08bf 100644 --- a/lib/private/Files/SetupManager.php +++ b/lib/private/Files/SetupManager.php @@ -28,6 +28,7 @@ use OCA\Files_Sharing\ISharedMountPoint; 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 @@ class SetupManager implements ISetupManager { ); $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 90c2845cad2..bbf61850071 100644 --- a/lib/private/FilesMetadata/Service/IndexRequestService.php +++ b/lib/private/FilesMetadata/Service/IndexRequestService.php @@ -186,7 +186,7 @@ class IndexRequestService { * @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 c274c70812d..223bcee8d94 100644 --- a/lib/private/FilesMetadata/Service/MetadataRequestService.php +++ b/lib/private/FilesMetadata/Service/MetadataRequestService.php @@ -150,7 +150,7 @@ class MetadataRequestService { * @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 fb83ea8df19..c3e6df7cc30 100644 --- a/lib/private/Group/Database.php +++ b/lib/private/Group/Database.php @@ -342,7 +342,7 @@ class Database extends ABackend implements $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 @@ class Database extends ABackend implements } } - 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 13e6a714516..99427b74b29 100644 --- a/lib/private/Preview/Storage/LocalPreviewStorage.php +++ b/lib/private/Preview/Storage/LocalPreviewStorage.php @@ -315,7 +315,7 @@ class LocalPreviewStorage implements IPreviewStorage { ->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 @@ class LocalPreviewStorage implements IPreviewStorage { ->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 0e2a7318f22..1685ac63c91 100644 --- a/lib/private/Repair/RemoveBrokenProperties.php +++ b/lib/private/Repair/RemoveBrokenProperties.php @@ -51,7 +51,7 @@ class RemoveBrokenProperties implements IRepairStep { $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 1d446acd5e1..77c719efcc6 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -685,7 +685,7 @@ class DefaultShareProvider implements $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 f7895c51652..4643d46cccd 100644 --- a/lib/private/TagManager.php +++ b/lib/private/TagManager.php @@ -128,7 +128,7 @@ class TagManager implements ITagManager, IEventListener { $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 a999150d452..89d6b61e0ab 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 *