aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_sharing/lib/DeleteOrphanedSharesJob.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_sharing/lib/DeleteOrphanedSharesJob.php')
-rw-r--r--apps/files_sharing/lib/DeleteOrphanedSharesJob.php81
1 files changed, 48 insertions, 33 deletions
diff --git a/apps/files_sharing/lib/DeleteOrphanedSharesJob.php b/apps/files_sharing/lib/DeleteOrphanedSharesJob.php
index 6c6d5bfede5..63f057e3bf4 100644
--- a/apps/files_sharing/lib/DeleteOrphanedSharesJob.php
+++ b/apps/files_sharing/lib/DeleteOrphanedSharesJob.php
@@ -1,29 +1,10 @@
<?php
declare(strict_types=1);
-
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Vincent Petry <vincent@nextcloud.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2020-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Files_Sharing;
@@ -45,27 +26,20 @@ class DeleteOrphanedSharesJob extends TimedJob {
private const CHUNK_SIZE = 1000;
- private const INTERVAL = 24 * 60 * 60; // 1 day
-
- private IDBConnection $db;
-
- private LoggerInterface $logger;
+ private const INTERVAL = 24 * 60 * 60;
/**
* sets the correct interval for this timed job
*/
public function __construct(
ITimeFactory $time,
- IDBConnection $db,
- LoggerInterface $logger
+ private IDBConnection $db,
+ private LoggerInterface $logger,
) {
parent::__construct($time);
- $this->db = $db;
-
$this->setInterval(self::INTERVAL); // 1 day
$this->setTimeSensitivity(self::TIME_INSENSITIVE);
- $this->logger = $logger;
}
/**
@@ -74,6 +48,11 @@ class DeleteOrphanedSharesJob extends TimedJob {
* @param array $argument unused argument
*/
public function run($argument) {
+ if ($this->db->getShardDefinition('filecache')) {
+ $this->shardingCleanup();
+ return;
+ }
+
$qbSelect = $this->db->getQueryBuilder();
$qbSelect->select('id')
->from('share', 's')
@@ -107,7 +86,7 @@ class DeleteOrphanedSharesJob extends TimedJob {
$result->closeCursor();
$deleteQb->setParameter('ids', $ids, IQueryBuilder::PARAM_INT_ARRAY);
$deleted = $deleteQb->executeStatement();
- $this->logger->debug("{deleted} orphaned share(s) deleted", [
+ $this->logger->debug('{deleted} orphaned share(s) deleted', [
'app' => 'DeleteOrphanedSharesJob',
'deleted' => $deleted,
]);
@@ -115,4 +94,40 @@ class DeleteOrphanedSharesJob extends TimedJob {
}, $this->db);
} while ($deleted >= self::CHUNK_SIZE && $this->time->getTime() <= $cutOff);
}
+
+ private function shardingCleanup(): void {
+ $qb = $this->db->getQueryBuilder();
+ $qb->selectDistinct('file_source')
+ ->from('share', 's');
+ $sourceFiles = $qb->executeQuery()->fetchAll(PDO::FETCH_COLUMN);
+
+ $deleteQb = $this->db->getQueryBuilder();
+ $deleteQb->delete('share')
+ ->where(
+ $deleteQb->expr()->in('file_source', $deleteQb->createParameter('ids'), IQueryBuilder::PARAM_INT_ARRAY)
+ );
+
+ $chunks = array_chunk($sourceFiles, self::CHUNK_SIZE);
+ foreach ($chunks as $chunk) {
+ $deletedFiles = $this->findMissingSources($chunk);
+ $this->atomic(function () use ($deletedFiles, $deleteQb) {
+ $deleteQb->setParameter('ids', $deletedFiles, IQueryBuilder::PARAM_INT_ARRAY);
+ $deleted = $deleteQb->executeStatement();
+ $this->logger->debug('{deleted} orphaned share(s) deleted', [
+ 'app' => 'DeleteOrphanedSharesJob',
+ 'deleted' => $deleted,
+ ]);
+ return $deleted;
+ }, $this->db);
+ }
+ }
+
+ private function findMissingSources(array $ids): array {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('fileid')
+ ->from('filecache')
+ ->where($qb->expr()->in('fileid', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)));
+ $found = $qb->executeQuery()->fetchAll(\PDO::FETCH_COLUMN);
+ return array_diff($ids, $found);
+ }
}