Skip to content

Commit 4e9ca5f

Browse files
authored
Merge pull request #5918 from nextcloud/fix/reset_sessions
Truncate tables and rename documents folder on reset
2 parents a18637b + cd83e36 commit 4e9ca5f

File tree

9 files changed

+111
-27
lines changed

9 files changed

+111
-27
lines changed

lib/Command/ResetDocument.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
6060
return 1;
6161
}
6262

63+
if ($all && $fullReset) {
64+
// Truncate tables and clear document directory
65+
$this->documentService->clearAll();
66+
return 0;
67+
}
68+
6369
if ($all) {
64-
$fileIds = array_map(static function (Document $document) {
65-
return $document->getId();
66-
}, $this->documentService->getAll());
70+
$fileIds = [];
71+
foreach ($this->documentService->getAll() as $document) {
72+
$fileIds[] = $document->getId();
73+
}
6774
} else {
6875
$fileIds = [$fileId];
6976
}

lib/Cron/Cleanup.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,8 @@ public function __construct(ITimeFactory $time,
3939
*/
4040
protected function run($argument): void {
4141
$this->logger->debug('Run cleanup job for text documents');
42-
$documents = $this->documentService->getAll();
43-
foreach ($documents as $document) {
44-
$allSessions = $this->sessionService->getAllSessions($document->getId());
45-
if (count($allSessions) > 0) {
42+
foreach ($this->documentService->getAll() as $document) {
43+
if ($this->sessionService->countAllSessions($document->getId()) > 0) {
4644
// Do not reset if there are any sessions left
4745
// Inactive sessions will get removed further down and will trigger a reset next time
4846
continue;
@@ -57,5 +55,8 @@ protected function run($argument): void {
5755
$this->logger->debug('Run cleanup job for text sessions');
5856
$removedSessions = $this->sessionService->removeInactiveSessionsWithoutSteps(null);
5957
$this->logger->debug('Removed ' . $removedSessions . ' inactive sessions');
58+
59+
$this->logger->debug('Run cleanup job for obsolete documents folders');
60+
$this->documentService->cleanupOldDocumentsFolders();
6061
}
6162
}

lib/Db/DocumentMapper.php

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace OCA\Text\Db;
88

9+
use Generator;
910
use OCP\AppFramework\Db\DoesNotExistException;
1011
use OCP\AppFramework\Db\QBMapper;
1112
use OCP\DB\QueryBuilder\IQueryBuilder;
@@ -38,12 +39,33 @@ public function find(int $documentId): Document {
3839
return Document::fromRow($data);
3940
}
4041

41-
public function findAll(): array {
42+
public function findAll(): Generator {
4243
$qb = $this->db->getQueryBuilder();
4344
$result = $qb->select('*')
4445
->from($this->getTableName())
4546
->executeQuery();
47+
try {
48+
while ($row = $result->fetch()) {
49+
yield $this->mapRowToEntity($row);
50+
}
51+
} finally {
52+
$result->closeCursor();
53+
}
54+
}
4655

47-
return $this->findEntities($qb);
56+
public function countAll(): int {
57+
$qb = $this->db->getQueryBuilder();
58+
$qb->select($qb->func()->count('id'))
59+
->from($this->getTableName());
60+
$result = $qb->executeQuery();
61+
$count = (int)$result->fetchOne();
62+
$result->closeCursor();
63+
return $count;
64+
}
65+
66+
public function clearAll(): void {
67+
$qb = $this->db->getQueryBuilder();
68+
$qb->delete($this->getTableName())
69+
->executeStatement();
4870
}
4971
}

lib/Db/SessionMapper.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ public function findAll(int $documentId): array {
6868
return $this->findEntities($qb);
6969
}
7070

71+
public function countAll(int $documentId): int {
72+
$qb = $this->db->getQueryBuilder();
73+
$qb->select('id', 'color', 'document_id', 'last_awareness_message', 'last_contact', 'user_id', 'guest_name')
74+
->from($this->getTableName())
75+
->where($qb->expr()->eq('document_id', $qb->createNamedParameter($documentId)));
76+
$result = $qb->executeQuery();
77+
$count = (int)$result->fetchOne();
78+
$result->closeCursor();
79+
return $count;
80+
}
81+
7182
/**
7283
* @return Session[]
7384
*
@@ -137,6 +148,12 @@ public function deleteByDocumentId(int $documentId): int {
137148
return $qb->executeStatement();
138149
}
139150

151+
public function clearAll(): void {
152+
$qb = $this->db->getQueryBuilder();
153+
$qb->delete($this->getTableName())
154+
->executeStatement();
155+
}
156+
140157
public function isUserInDocument(int $documentId, string $userId): bool {
141158
$qb = $this->db->getQueryBuilder();
142159
$result = $qb->select('*')

lib/Db/StepMapper.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ public function deleteAll(int $documentId): void {
6262
->executeStatement();
6363
}
6464

65+
public function clearAll(): void {
66+
$qb = $this->db->getQueryBuilder();
67+
$qb->delete($this->getTableName())
68+
->executeStatement();
69+
}
70+
6571
// not in use right now
6672
public function deleteBeforeVersion(int $documentId, int $version): int {
6773
$qb = $this->db->getQueryBuilder();

lib/Migration/ResetSessionsBeforeYjs.php

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
namespace OCA\Text\Migration;
99

10-
use OCA\Text\Db\Document;
1110
use OCA\Text\Service\DocumentService;
1211
use OCP\IAppConfig;
1312
use OCP\Migration\IOutput;
@@ -32,20 +31,6 @@ public function run(IOutput $output): void {
3231
return;
3332
}
3433

35-
$fileIds = array_map(static function (Document $document) {
36-
return $document->getId();
37-
}, $this->documentService->getAll());
38-
39-
if (!$fileIds) {
40-
return;
41-
}
42-
43-
$output->startProgress(count($fileIds));
44-
foreach ($fileIds as $fileId) {
45-
$this->documentService->unlock($fileId);
46-
$this->documentService->resetDocument($fileId, true);
47-
$output->advance();
48-
}
49-
$output->finishProgress();
34+
$this->documentService->clearAll();
5035
}
5136
}

lib/Service/DocumentService.php

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
use OCP\Files\SimpleFS\ISimpleFile;
4343
use OCP\ICache;
4444
use OCP\ICacheFactory;
45+
use OCP\IConfig;
4546
use OCP\IRequest;
4647
use OCP\Lock\LockedException;
4748
use OCP\PreConditionNotMetException;
@@ -70,8 +71,9 @@ class DocumentService {
7071
private IAppData $appData;
7172
private ILockManager $lockManager;
7273
private IUserMountCache $userMountCache;
74+
private IConfig $config;
7375

74-
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) {
76+
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) {
7577
$this->documentMapper = $documentMapper;
7678
$this->stepMapper = $stepMapper;
7779
$this->sessionMapper = $sessionMapper;
@@ -83,6 +85,7 @@ public function __construct(DocumentMapper $documentMapper, StepMapper $stepMapp
8385
$this->shareManager = $shareManager;
8486
$this->lockManager = $lockManager;
8587
$this->userMountCache = $userMountCache;
88+
$this->config = $config;
8689
$token = $request->getParam('token');
8790
if ($this->userId === null && $token !== null) {
8891
try {
@@ -428,7 +431,7 @@ public function resetDocument(int $documentId, bool $force = false): void {
428431
}
429432
}
430433

431-
public function getAll(): array {
434+
public function getAll(): \Generator {
432435
return $this->documentMapper->findAll();
433436
}
434437

@@ -642,4 +645,40 @@ public function unlock(int $fileId): void {
642645
} catch (NoLockProviderException | PreConditionNotMetException | NotFoundException $e) {
643646
}
644647
}
648+
649+
public function countAll(): int {
650+
return $this->documentMapper->countAll();
651+
}
652+
653+
private function getFullAppFolder(): Folder {
654+
$appFolder = $this->rootFolder->get('appdata_' . $this->config->getSystemValueString('instanceid', '') . '/text');
655+
if (!$appFolder instanceof Folder) {
656+
throw new NotFoundException('Folder not found');
657+
}
658+
return $appFolder;
659+
}
660+
661+
public function clearAll(): void {
662+
$this->stepMapper->clearAll();
663+
$this->sessionMapper->clearAll();
664+
$this->documentMapper->clearAll();
665+
try {
666+
$appFolder = $this->getFullAppFolder();
667+
$appFolder->get('documents')->move($appFolder->getPath() . '/documents_old_' . time());
668+
} catch (NotFoundException) {
669+
}
670+
$this->ensureDocumentsFolder();
671+
}
672+
673+
public function cleanupOldDocumentsFolders(): void {
674+
try {
675+
$appFolder = $this->getFullAppFolder();
676+
foreach ($appFolder->getDirectoryListing() as $node) {
677+
if (str_starts_with($node->getName(), 'documents_old_')) {
678+
$node->delete();
679+
}
680+
}
681+
} catch (NotFoundException) {
682+
}
683+
}
645684
}

lib/Service/SessionService.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ public function getAllSessions(int $documentId): array {
106106
}, $sessions);
107107
}
108108

109+
public function countAllSessions(int $documentId): int {
110+
return $this->sessionMapper->countAll($documentId);
111+
}
112+
109113
public function getActiveSessions(int $documentId): array {
110114
$sessions = $this->sessionMapper->findAllActive($documentId);
111115
return array_map(function (Session $session) {

tests/unit/Service/DocumentServiceTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use OCP\Files\Lock\ILockManager;
1515
use OCP\Files\NotPermittedException;
1616
use OCP\ICacheFactory;
17+
use OCP\IConfig;
1718
use OCP\IRequest;
1819
use OCP\Share\IManager;
1920
use Psr\Log\LoggerInterface;
@@ -49,6 +50,7 @@ public function setUp(): void {
4950
$this->directManager = $this->createMock(\OCP\DirectEditing\IManager::class);
5051
$this->lockManager = $this->createMock(ILockManager::class);
5152
$this->userMountCache = $this->createMock(IUserMountCache::class);
53+
$config = $this->createMock(IConfig::class);
5254

5355
$this->documentService = new DocumentService(
5456
$this->documentMapper,
@@ -64,6 +66,7 @@ public function setUp(): void {
6466
$this->directManager,
6567
$this->lockManager,
6668
$this->userMountCache,
69+
$config,
6770
);
6871
}
6972

0 commit comments

Comments
 (0)