aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_versions
diff options
context:
space:
mode:
authorLouis Chemineau <louis@chmn.me>2024-03-06 16:44:18 +0100
committerLouis <louis@chmn.me>2024-03-08 16:08:21 +0000
commit080850d4315bd59e4d3e28b20986d3b92e21d7dc (patch)
treeab207bbf9772c768c49d63b0790522b97f6edc4d /apps/files_versions
parent7c2aac3e6df8a95be3d16e661d0749fa33ace278 (diff)
downloadnextcloud-server-080850d4315bd59e4d3e28b20986d3b92e21d7dc.tar.gz
nextcloud-server-080850d4315bd59e4d3e28b20986d3b92e21d7dc.zip
fix(files_versions): Improve files version listing
Signed-off-by: Louis Chemineau <louis@chmn.me>
Diffstat (limited to 'apps/files_versions')
-rw-r--r--apps/files_versions/lib/Command/CleanUp.php5
-rw-r--r--apps/files_versions/lib/Db/VersionsMapper.php35
-rw-r--r--apps/files_versions/tests/Command/CleanupTest.php30
3 files changed, 66 insertions, 4 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)