diff options
author | Louis <louis@chmn.me> | 2024-03-06 15:52:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-06 15:52:39 +0100 |
commit | 75c489cc4b96e927f0ce0c3724e47141d6f104ee (patch) | |
tree | 4d598db98809564971cb1a357a9cabc2917dd292 | |
parent | c651e06a6d1296cbca03a706d9cded707e70af74 (diff) | |
parent | fcdc8b47f23299747873b635b6f95c9f418e6645 (diff) | |
download | nextcloud-server-75c489cc4b96e927f0ce0c3724e47141d6f104ee.tar.gz nextcloud-server-75c489cc4b96e927f0ce0c3724e47141d6f104ee.zip |
Merge pull request #43263 from nextcloud/artonge/fix/versions_cleanup
Cleanup versions entities in versions:clean command
-rw-r--r-- | apps/files_versions/lib/Command/CleanUp.php | 5 | ||||
-rw-r--r-- | apps/files_versions/lib/Db/VersionsMapper.php | 35 | ||||
-rw-r--r-- | apps/files_versions/tests/Command/CleanupTest.php | 30 | ||||
-rw-r--r-- | tests/Core/Command/TwoFactorAuth/CleanupTest.php | 7 |
4 files changed, 72 insertions, 5 deletions
diff --git a/apps/files_versions/lib/Command/CleanUp.php b/apps/files_versions/lib/Command/CleanUp.php index 519b3689a58..eda482357b3 100644 --- a/apps/files_versions/lib/Command/CleanUp.php +++ b/apps/files_versions/lib/Command/CleanUp.php @@ -24,6 +24,7 @@ */ namespace OCA\Files_Versions\Command; +use OCA\Files_Versions\Db\VersionsMapper; use OCP\Files\IRootFolder; use OCP\IUserBackend; use OCP\IUserManager; @@ -37,6 +38,7 @@ class CleanUp extends Command { public function __construct( protected IRootFolder $rootFolder, protected IUserManager $userManager, + protected VersionsMapper $versionMapper, ) { parent::__construct(); } @@ -119,6 +121,9 @@ class CleanUp extends Command { \OC_Util::tearDownFS(); \OC_Util::setupFS($user); + $userHomeStorageId = $this->rootFolder->getUserFolder($user)->getStorage()->getCache()->getNumericStorageId(); + $this->versionMapper->deleteAllVersionsForUser($userHomeStorageId, $path); + $fullPath = '/' . $user . '/files_versions' . ($path ? '/' . $path : ''); if ($this->rootFolder->nodeExists($fullPath)) { $this->rootFolder->get($fullPath)->delete(); diff --git a/apps/files_versions/lib/Db/VersionsMapper.php b/apps/files_versions/lib/Db/VersionsMapper.php index bc6e8b264de..f7f92c70f03 100644 --- a/apps/files_versions/lib/Db/VersionsMapper.php +++ b/apps/files_versions/lib/Db/VersionsMapper.php @@ -27,6 +27,7 @@ declare(strict_types=1); namespace OCA\Files_Versions\Db; use OCP\AppFramework\Db\QBMapper; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; /** @@ -83,4 +84,38 @@ class VersionsMapper extends QBMapper { ->where($qb->expr()->eq('file_id', $qb->createNamedParameter($fileId))) ->executeStatement(); } + + public function deleteAllVersionsForUser(int $storageId, string $path = null): void { + $fileIdsGenerator = $this->getFileIdsGenerator($storageId, $path); + + $versionEntitiesDeleteQuery = $this->db->getQueryBuilder(); + $versionEntitiesDeleteQuery->delete($this->getTableName()) + ->where($versionEntitiesDeleteQuery->expr()->in('file_id', $versionEntitiesDeleteQuery->createParameter('file_ids'))); + + foreach ($fileIdsGenerator as $fileIds) { + $versionEntitiesDeleteQuery->setParameter('file_ids', $fileIds, IQueryBuilder::PARAM_INT_ARRAY); + $versionEntitiesDeleteQuery->executeStatement(); + } + } + + private function getFileIdsGenerator(int $storageId, ?string $path): \Generator { + $offset = 0; + do { + $filesIdsSelect = $this->db->getQueryBuilder(); + $filesIdsSelect->select('fileid') + ->from('filecache') + ->where($filesIdsSelect->expr()->eq('storage', $filesIdsSelect->createNamedParameter($storageId, IQueryBuilder::PARAM_STR))) + ->andWhere($filesIdsSelect->expr()->like('path', $filesIdsSelect->createNamedParameter('files' . ($path ? '/' . $this->db->escapeLikeParameter($path) : '') . '/%', IQueryBuilder::PARAM_STR))) + ->andWhere($filesIdsSelect->expr()->gt('fileid', $filesIdsSelect->createParameter('offset'))) + ->setMaxResults(1000) + ->orderBy('fileid', 'ASC'); + + $filesIdsSelect->setParameter('offset', $offset, IQueryBuilder::PARAM_INT); + $result = $filesIdsSelect->executeQuery(); + $fileIds = $result->fetchAll(\PDO::FETCH_COLUMN); + $offset = end($fileIds); + + yield $fileIds; + } while (!empty($fileIds)); + } } diff --git a/apps/files_versions/tests/Command/CleanupTest.php b/apps/files_versions/tests/Command/CleanupTest.php index b5463aa61db..085b25822f3 100644 --- a/apps/files_versions/tests/Command/CleanupTest.php +++ b/apps/files_versions/tests/Command/CleanupTest.php @@ -27,7 +27,10 @@ namespace OCA\Files_Versions\Tests\Command; use OC\User\Manager; use OCA\Files_Versions\Command\CleanUp; +use OCP\Files\Cache\ICache; +use OCP\Files\Folder; use OCP\Files\IRootFolder; +use OCP\Files\Storage\IStorage; use Test\TestCase; /** @@ -48,6 +51,9 @@ class CleanupTest extends TestCase { /** @var \PHPUnit\Framework\MockObject\MockObject | IRootFolder */ protected $rootFolder; + /** @var \PHPUnit\Framework\MockObject\MockObject | VersionsMapper */ + protected $versionMapper; + protected function setUp(): void { parent::setUp(); @@ -55,9 +61,10 @@ class CleanupTest extends TestCase { ->disableOriginalConstructor()->getMock(); $this->userManager = $this->getMockBuilder('OC\User\Manager') ->disableOriginalConstructor()->getMock(); + $this->versionMapper = $this->getMockBuilder('OCA\Files_Versions\Db\VersionsMapper') + ->disableOriginalConstructor()->getMock(); - - $this->cleanup = new CleanUp($this->rootFolder, $this->userManager); + $this->cleanup = new CleanUp($this->rootFolder, $this->userManager, $this->versionMapper); } /** @@ -70,6 +77,21 @@ class CleanupTest extends TestCase { ->with('/testUser/files_versions') ->willReturn($nodeExists); + $userFolder = $this->createMock(Folder::class); + $userHomeStorage = $this->createMock(IStorage::class); + $userHomeStorageCache = $this->createMock(ICache::class); + $this->rootFolder->expects($this->once()) + ->method('getUserFolder') + ->willReturn($userFolder); + $userFolder->expects($this->once()) + ->method('getStorage') + ->willReturn($userHomeStorage); + $userHomeStorage->expects($this->once()) + ->method('getCache') + ->willReturn($userHomeStorageCache); + $userHomeStorageCache->expects($this->once()) + ->method('getNumericStorageId') + ->willReturn(1); if ($nodeExists) { $this->rootFolder->expects($this->once()) @@ -104,7 +126,7 @@ class CleanupTest extends TestCase { $instance = $this->getMockBuilder('OCA\Files_Versions\Command\CleanUp') ->setMethods(['deleteVersions']) - ->setConstructorArgs([$this->rootFolder, $this->userManager]) + ->setConstructorArgs([$this->rootFolder, $this->userManager, $this->versionMapper]) ->getMock(); $instance->expects($this->exactly(count($userIds))) ->method('deleteVersions') @@ -136,7 +158,7 @@ class CleanupTest extends TestCase { $instance = $this->getMockBuilder('OCA\Files_Versions\Command\CleanUp') ->setMethods(['deleteVersions']) - ->setConstructorArgs([$this->rootFolder, $this->userManager]) + ->setConstructorArgs([$this->rootFolder, $this->userManager, $this->versionMapper]) ->getMock(); $backend = $this->getMockBuilder(\OCP\UserInterface::class) diff --git a/tests/Core/Command/TwoFactorAuth/CleanupTest.php b/tests/Core/Command/TwoFactorAuth/CleanupTest.php index 23461ebd784..096f7dee9f8 100644 --- a/tests/Core/Command/TwoFactorAuth/CleanupTest.php +++ b/tests/Core/Command/TwoFactorAuth/CleanupTest.php @@ -27,6 +27,7 @@ declare(strict_types=1); namespace Core\Command\TwoFactorAuth; use OC\Core\Command\TwoFactorAuth\Cleanup; +use OCA\Files_Versions\Db\VersionsMapper; use OCP\Authentication\TwoFactorAuth\IRegistry; use OCP\IUserManager; use PHPUnit\Framework\MockObject\MockObject; @@ -40,6 +41,9 @@ class CleanupTest extends TestCase { /** @var IUserManager|MockObject */ private $userManager; + /** @var VersionsMapper|MockObject */ + private $versionMapper; + /** @var CommandTester */ private $cmd; @@ -48,8 +52,9 @@ class CleanupTest extends TestCase { $this->registry = $this->createMock(IRegistry::class); $this->userManager = $this->createMock(IUserManager::class); + $this->versionMapper = $this->createMock(VersionsMapper::class); - $cmd = new Cleanup($this->registry, $this->userManager); + $cmd = new Cleanup($this->registry, $this->userManager, $this->versionMapper); $this->cmd = new CommandTester($cmd); } |