From 914c10054bcd1eaaa57d6896eba94412b6d473d3 Mon Sep 17 00:00:00 2001 From: Jonas Date: Mon, 17 Jun 2024 11:40:45 +0200 Subject: [PATCH] fix(resetSessions): Truncate tables and rename documents folder This is way more performant than iterating over all existing sessions. Signed-off-by: Jonas --- lib/Command/ResetDocument.php | 6 ++++++ lib/Db/DocumentMapper.php | 6 ++++++ lib/Db/SessionMapper.php | 6 ++++++ lib/Db/StepMapper.php | 6 ++++++ lib/Migration/ResetSessionsBeforeYjs.php | 9 +------- lib/Service/DocumentService.php | 25 +++++++++++++++++++++- tests/unit/Service/DocumentServiceTest.php | 3 +++ 7 files changed, 52 insertions(+), 9 deletions(-) diff --git a/lib/Command/ResetDocument.php b/lib/Command/ResetDocument.php index e9588409c..c45b67a89 100644 --- a/lib/Command/ResetDocument.php +++ b/lib/Command/ResetDocument.php @@ -77,6 +77,12 @@ class ResetDocument extends Command { return 1; } + if ($all && $fullReset) { + // Truncate tables and clear document directory + $this->documentService->clearAll(); + return 0; + } + if ($all) { $fileIds = []; foreach ($this->documentService->getAll() as $document) { diff --git a/lib/Db/DocumentMapper.php b/lib/Db/DocumentMapper.php index 81099deb9..097300ea0 100644 --- a/lib/Db/DocumentMapper.php +++ b/lib/Db/DocumentMapper.php @@ -79,4 +79,10 @@ class DocumentMapper extends QBMapper { $result->closeCursor(); return $count; } + + public function clearAll(): void { + $qb = $this->db->getQueryBuilder(); + $qb->delete($this->getTableName()) + ->executeStatement(); + } } diff --git a/lib/Db/SessionMapper.php b/lib/Db/SessionMapper.php index cdd48b2fb..df85a3fe4 100644 --- a/lib/Db/SessionMapper.php +++ b/lib/Db/SessionMapper.php @@ -165,6 +165,12 @@ class SessionMapper extends QBMapper { return $qb->executeStatement(); } + public function clearAll(): void { + $qb = $this->db->getQueryBuilder(); + $qb->delete($this->getTableName()) + ->executeStatement(); + } + public function isUserInDocument(int $documentId, string $userId): bool { $qb = $this->db->getQueryBuilder(); $result = $qb->select('*') diff --git a/lib/Db/StepMapper.php b/lib/Db/StepMapper.php index 8279f7d04..e1be47469 100644 --- a/lib/Db/StepMapper.php +++ b/lib/Db/StepMapper.php @@ -76,6 +76,12 @@ class StepMapper extends QBMapper { ->executeStatement(); } + public function clearAll(): void { + $qb = $this->db->getQueryBuilder(); + $qb->delete($this->getTableName()) + ->executeStatement(); + } + // not in use right now public function deleteBeforeVersion(int $documentId, int $version): int { $qb = $this->db->getQueryBuilder(); diff --git a/lib/Migration/ResetSessionsBeforeYjs.php b/lib/Migration/ResetSessionsBeforeYjs.php index 36107628e..32133e475 100644 --- a/lib/Migration/ResetSessionsBeforeYjs.php +++ b/lib/Migration/ResetSessionsBeforeYjs.php @@ -26,13 +26,6 @@ class ResetSessionsBeforeYjs implements IRepairStep { return; } - $output->startProgress($this->documentService->countAll()); - foreach ($this->documentService->getAll() as $document) { - $fileId = $document->getId(); - $this->documentService->unlock($fileId); - $this->documentService->resetDocument($fileId, true); - $output->advance(); - } - $output->finishProgress(); + $this->documentService->clearAll(); } } diff --git a/lib/Service/DocumentService.php b/lib/Service/DocumentService.php index 21a7a1020..32c953ae1 100644 --- a/lib/Service/DocumentService.php +++ b/lib/Service/DocumentService.php @@ -59,6 +59,7 @@ use OCP\Files\NotPermittedException; use OCP\Files\SimpleFS\ISimpleFile; use OCP\ICache; use OCP\ICacheFactory; +use OCP\IConfig; use OCP\IRequest; use OCP\Lock\LockedException; use OCP\PreConditionNotMetException; @@ -87,8 +88,9 @@ class DocumentService { private IAppData $appData; private ILockManager $lockManager; private IUserMountCache $userMountCache; + private IConfig $config; - public function __construct(DocumentMapper $documentMapper, StepMapper $stepMapper, SessionMapper $sessionMapper, IAppData $appData, ?string $userId, IRootFolder $rootFolder, ICacheFactory $cacheFactory, LoggerInterface $logger, ShareManager $shareManager, IRequest $request, IManager $directManager, ILockManager $lockManager, IUserMountCache $userMountCache) { + public function __construct(DocumentMapper $documentMapper, StepMapper $stepMapper, SessionMapper $sessionMapper, IAppData $appData, ?string $userId, IRootFolder $rootFolder, ICacheFactory $cacheFactory, LoggerInterface $logger, ShareManager $shareManager, IRequest $request, IManager $directManager, ILockManager $lockManager, IUserMountCache $userMountCache, IConfig $config) { $this->documentMapper = $documentMapper; $this->stepMapper = $stepMapper; $this->sessionMapper = $sessionMapper; @@ -100,6 +102,7 @@ class DocumentService { $this->shareManager = $shareManager; $this->lockManager = $lockManager; $this->userMountCache = $userMountCache; + $this->config = $config; $token = $request->getParam('token'); if ($this->userId === null && $token !== null) { try { @@ -662,4 +665,24 @@ class DocumentService { public function countAll(): int { return $this->documentMapper->countAll(); } + + private function getFullAppFolder(): Folder { + $appFolder = $this->rootFolder->get('appdata_' . $this->config->getSystemValueString('instanceid', '') . '/text'); + if (!$appFolder instanceof Folder) { + throw new NotFoundException('Folder not found'); + } + return $appFolder; + } + + public function clearAll(): void { + $this->stepMapper->clearAll(); + $this->sessionMapper->clearAll(); + $this->documentMapper->clearAll(); + try { + $appFolder = $this->getFullAppFolder(); + $appFolder->get('documents')->move($appFolder->getPath() . '/documents_old_' . time()); + } catch (NotFoundException) { + } + $this->ensureDocumentsFolder(); + } } diff --git a/tests/unit/Service/DocumentServiceTest.php b/tests/unit/Service/DocumentServiceTest.php index 7b886ebd4..8d091f256 100644 --- a/tests/unit/Service/DocumentServiceTest.php +++ b/tests/unit/Service/DocumentServiceTest.php @@ -14,6 +14,7 @@ use OCP\Files\IRootFolder; use OCP\Files\Lock\ILockManager; use OCP\Files\NotPermittedException; use OCP\ICacheFactory; +use OCP\IConfig; use OCP\IRequest; use OCP\Share\IManager; use Psr\Log\LoggerInterface; @@ -49,6 +50,7 @@ class DocumentServiceTest extends \PHPUnit\Framework\TestCase { $this->directManager = $this->createMock(\OCP\DirectEditing\IManager::class); $this->lockManager = $this->createMock(ILockManager::class); $this->userMountCache = $this->createMock(IUserMountCache::class); + $config = $this->createMock(IConfig::class); $this->documentService = new DocumentService( $this->documentMapper, @@ -64,6 +66,7 @@ class DocumentServiceTest extends \PHPUnit\Framework\TestCase { $this->directManager, $this->lockManager, $this->userMountCache, + $config, ); }