Skip to content

Commit f38fb20

Browse files
committed
Cleanup tags component
- Port to LoggerInterface - Use IDBConnection and IQueryBuilder instead of raw SQL and OC_DB - Use IEventListener instead of hooks Todos: - [ ] Finish IQueryBuilder port - [ ] Remove OC_DB as this is the only thing that still use that Signed-off-by: Carl Schwan <[email protected]>
1 parent 0824f44 commit f38fb20

4 files changed

Lines changed: 222 additions & 248 deletions

File tree

core/Application.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@
4949
use OC\DB\MissingPrimaryKeyInformation;
5050
use OC\DB\SchemaWrapper;
5151
use OC\Metadata\FileEventListener;
52+
use OC\TagManager;
5253
use OCP\AppFramework\App;
54+
use OCP\AppFramework\Bootstrap\IBootContext;
55+
use OCP\AppFramework\Bootstrap\IBootstrap;
56+
use OCP\AppFramework\Bootstrap\IRegistrationContext;
5357
use OCP\EventDispatcher\IEventDispatcher;
5458
use OCP\Files\Events\Node\NodeDeletedEvent;
5559
use OCP\Files\Events\Node\NodeWrittenEvent;
@@ -307,14 +311,20 @@ function (GenericEvent $event) use ($container) {
307311
$eventDispatcher->addServiceListener(UserDeletedEvent::class, UserDeletedFilesCleanupListener::class);
308312
$eventDispatcher->addServiceListener(UserDeletedEvent::class, UserDeletedWebAuthnCleanupListener::class);
309313

314+
/** @var IEventDispatcher $eventDispatcher */
315+
$newEventDispatcher = \OC::$server->get(IEventDispatcher::class);
316+
310317
// Metadata
311318
/** @var IConfig $config */
312319
$config = $container->get(IConfig::class);
313320
if ($config->getSystemValueBool('enable_file_metadata', true)) {
314-
$eventDispatcher = \OC::$server->get(IEventDispatcher::class);
315-
$eventDispatcher->addServiceListener(NodeDeletedEvent::class, FileEventListener::class);
316-
$eventDispatcher->addServiceListener(NodeRemovedFromCache::class, FileEventListener::class);
317-
$eventDispatcher->addServiceListener(NodeWrittenEvent::class, FileEventListener::class);
321+
$newEventDispatcher->addServiceListener(NodeDeletedEvent::class, FileEventListener::class);
322+
$newEventDispatcher->addServiceListener(NodeRemovedFromCache::class, FileEventListener::class);
323+
$newEventDispatcher->addServiceListener(NodeWrittenEvent::class, FileEventListener::class);
318324
}
325+
326+
// Tags
327+
$newEventDispatcher->addServiceListener(UserDeletedEvent::class, TagManager::class);
328+
319329
}
320330
}

lib/private/TagManager.php

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,27 @@
2828

2929
use OC\Tagging\TagMapper;
3030
use OCP\DB\QueryBuilder\IQueryBuilder;
31+
use OCP\EventDispatcher\Event;
32+
use OCP\EventDispatcher\IEventListener;
3133
use OCP\IDBConnection;
3234
use OCP\ITagManager;
3335
use OCP\ITags;
3436
use OCP\IUserSession;
37+
use OCP\User\Events\UserDeletedEvent;
38+
use OCP\Db\Exception as DBException;
39+
use Psr\Log\LoggerInterface;
3540

36-
class TagManager implements ITagManager {
41+
class TagManager implements ITagManager, IEventListener {
42+
private TagMapper $mapper;
43+
private IUserSession $userSession;
44+
private IDBConnection $connection;
45+
private LoggerInterface $logger;
3746

38-
/** @var TagMapper */
39-
private $mapper;
40-
41-
/** @var IUserSession */
42-
private $userSession;
43-
44-
/** @var IDBConnection */
45-
private $connection;
46-
47-
public function __construct(TagMapper $mapper, IUserSession $userSession, IDBConnection $connection) {
47+
public function __construct(TagMapper $mapper, IUserSession $userSession, IDBConnection $connection, LoggerInterface $logger) {
4848
$this->mapper = $mapper;
4949
$this->userSession = $userSession;
5050
$this->connection = $connection;
51+
$this->logger = $logger;
5152
}
5253

5354
/**
@@ -72,7 +73,7 @@ public function load($type, $defaultTags = [], $includeShared = false, $userId =
7273
}
7374
$userId = $this->userSession->getUser()->getUId();
7475
}
75-
return new Tags($this->mapper, $userId, $type, $defaultTags);
76+
return new Tags($this->mapper, $userId, $type, $this->logger, $this->connection, $defaultTags);
7677
}
7778

7879
/**
@@ -97,4 +98,68 @@ public function getUsersFavoritingObject(string $objectType, int $objectId): arr
9798

9899
return $users;
99100
}
101+
102+
public function handle(Event $event): void {
103+
if (!($event instanceof UserDeletedEvent)) {
104+
return;
105+
}
106+
107+
// Find all objectid/tagId pairs.
108+
$user = $event->getUser();
109+
$qb = $this->connection->getQueryBuilder();
110+
$qb->select('id')
111+
->from('vcategory')
112+
->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())));
113+
try {
114+
$result = $qb->executeQuery();
115+
} catch (DBException $e) {
116+
$this->logger->error($e->getMessage(), [
117+
'app' => 'core',
118+
'exception' => $e,
119+
]);
120+
}
121+
122+
$tagsIds = array_map(fn(array $row) => (int)$row['id'], $result->fetchAll());
123+
$result->closeCursor();
124+
125+
if (count($tagsIds) === 0) {
126+
return;
127+
}
128+
129+
// Clean vcategory_to_object table
130+
$qb = $this->connection->getQueryBuilder();
131+
$qb = $qb->delete('vcategory_to_object')
132+
->where($qb->expr()->in('categoryid', $qb->createParameter('chunk')));
133+
134+
// Clean vcategory
135+
$qb1 = $this->connection->getQueryBuilder();
136+
$qb1 = $qb1->delete('vcategory')
137+
->where($qb1->expr()->in('uid', $qb1->createParameter('chunk')));
138+
139+
foreach (array_chunk($tagsIds, 1000) as $tagChunk) {
140+
$qb->setParameter('chunk', $tagChunk, IQueryBuilder::PARAM_INT_ARRAY);
141+
$qb1->setParameter('chunk', $tagChunk, IQueryBuilder::PARAM_INT_ARRAY);
142+
try {
143+
$qb->executeStatement();
144+
$qb1->executeStatement();
145+
} catch (DBException $e) {
146+
$this->logger->error($e->getMessage(), [
147+
'app' => 'core',
148+
'exception' => $e,
149+
]);
150+
}
151+
}
152+
153+
foreach (array_chunk($tagsIds, 1000) as $tagChunk) {
154+
$qb->setParameter('chunk', $tagChunk, IQueryBuilder::PARAM_INT_ARRAY);
155+
try {
156+
$qb->executeStatement();
157+
} catch (DBException $e) {
158+
$this->logger->error($e->getMessage(), [
159+
'app' => 'core',
160+
'exception' => $e,
161+
]);
162+
}
163+
}
164+
}
100165
}

0 commit comments

Comments
 (0)