summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/private/Repair.php2
-rw-r--r--lib/private/Repair/CleanTags.php57
-rw-r--r--tests/lib/Repair/CleanTagsTest.php28
3 files changed, 82 insertions, 5 deletions
diff --git a/lib/private/Repair.php b/lib/private/Repair.php
index bb2967d7e6e..1fd204fcd84 100644
--- a/lib/private/Repair.php
+++ b/lib/private/Repair.php
@@ -127,7 +127,7 @@ class Repair implements IOutput{
new RepairLegacyStorages(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
new AssetCache(),
new FillETags(\OC::$server->getDatabaseConnection()),
- new CleanTags(\OC::$server->getDatabaseConnection()),
+ new CleanTags(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager()),
new DropOldTables(\OC::$server->getDatabaseConnection()),
new DropOldJobs(\OC::$server->getJobList()),
new RemoveGetETagEntries(\OC::$server->getDatabaseConnection()),
diff --git a/lib/private/Repair/CleanTags.php b/lib/private/Repair/CleanTags.php
index 60ddeff08f3..4241fa6da3a 100644
--- a/lib/private/Repair/CleanTags.php
+++ b/lib/private/Repair/CleanTags.php
@@ -25,6 +25,7 @@ namespace OC\Repair;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
+use OCP\IUserManager;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
@@ -38,11 +39,18 @@ class CleanTags implements IRepairStep {
/** @var IDBConnection */
protected $connection;
+ /** @var IUserManager */
+ protected $userManager;
+
+ protected $deletedTags = 0;
+
/**
* @param IDBConnection $connection
+ * @param IUserManager $userManager
*/
- public function __construct(IDBConnection $connection) {
+ public function __construct(IDBConnection $connection, IUserManager $userManager) {
$this->connection = $connection;
+ $this->userManager = $userManager;
}
/**
@@ -56,12 +64,59 @@ class CleanTags implements IRepairStep {
* Updates the configuration after running an update
*/
public function run(IOutput $output) {
+ $this->deleteOrphanTags($output);
$this->deleteOrphanFileEntries($output);
$this->deleteOrphanTagEntries($output);
$this->deleteOrphanCategoryEntries($output);
}
/**
+ * Delete tags for deleted users
+ */
+ protected function deleteOrphanTags(IOutput $output) {
+ $offset = 0;
+ while ($this->checkTags($offset)) {
+ $offset += 50;
+ }
+
+ $output->info(sprintf('%d tags of deleted users have been removed.', $this->deletedTags));
+ }
+
+ protected function checkTags($offset) {
+ $query = $this->connection->getQueryBuilder();
+ $query->select('uid')
+ ->from('vcategory')
+ ->groupBy('uid')
+ ->orderBy('uid')
+ ->setMaxResults(50)
+ ->setFirstResult($offset);
+ $result = $query->execute();
+
+ $users = [];
+ $hadResults = false;
+ while ($row = $result->fetch()) {
+ $hadResults = true;
+ if (!$this->userManager->userExists($row['uid'])) {
+ $users[] = $row['uid'];
+ }
+ }
+ $result->closeCursor();
+
+ if (!$hadResults) {
+ // No more tags, stop looping
+ return false;
+ }
+
+ if (!empty($users)) {
+ $query = $this->connection->getQueryBuilder();
+ $query->delete('vcategory')
+ ->where($query->expr()->in('uid', $query->createNamedParameter($users, IQueryBuilder::PARAM_STR_ARRAY)));
+ $this->deletedTags += $query->execute();
+ }
+ return true;
+ }
+
+ /**
* Delete tag entries for deleted files
*/
protected function deleteOrphanFileEntries(IOutput $output) {
diff --git a/tests/lib/Repair/CleanTagsTest.php b/tests/lib/Repair/CleanTagsTest.php
index 804fa4f66c9..ac79907c525 100644
--- a/tests/lib/Repair/CleanTagsTest.php
+++ b/tests/lib/Repair/CleanTagsTest.php
@@ -25,6 +25,9 @@ class CleanTagsTest extends \Test\TestCase {
/** @var \OCP\IDBConnection */
protected $connection;
+ /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */
+ protected $userManager;
+
/** @var int */
protected $createdFile;
@@ -38,8 +41,12 @@ class CleanTagsTest extends \Test\TestCase {
->disableOriginalConstructor()
->getMock();
+ $this->userManager = $this->getMockBuilder('\OCP\IUserManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+
$this->connection = \OC::$server->getDatabaseConnection();
- $this->repair = new \OC\Repair\CleanTags($this->connection);
+ $this->repair = new \OC\Repair\CleanTags($this->connection, $this->userManager);
$this->cleanUpTables();
}
@@ -86,6 +93,20 @@ class CleanTagsTest extends \Test\TestCase {
self::invokePrivate($this->repair, 'deleteOrphanCategoryEntries', [$this->outputMock]);
$this->assertEntryCount('vcategory_to_object', 2, 'Assert tag entries count after cleaning category entries');
$this->assertEntryCount('vcategory', 2, 'Assert tag categories count after cleaning category entries');
+
+
+ $this->addTagCategory('TestRepairCleanTags', 'contacts', 'userExists'); // Retained
+ $this->assertEntryCount('vcategory', 3, 'Assert tag categories count before cleaning categories by users');
+
+ $this->userManager->expects($this->exactly(2))
+ ->method('userExists')
+ ->willReturnMap([
+ ['userExists', true],
+ ['TestRepairCleanTags', false],
+ ]);
+
+ self::invokePrivate($this->repair, 'deleteOrphanTags', [$this->outputMock]);
+ $this->assertEntryCount('vcategory', 1, 'Assert tag categories count after cleaning categories by users');
}
/**
@@ -107,13 +128,14 @@ class CleanTagsTest extends \Test\TestCase {
*
* @param string $category
* @param string $type
+ * @param string $user
* @return int
*/
- protected function addTagCategory($category, $type) {
+ protected function addTagCategory($category, $type, $user = 'TestRepairCleanTags') {
$qb = $this->connection->getQueryBuilder();
$qb->insert('vcategory')
->values([
- 'uid' => $qb->createNamedParameter('TestRepairCleanTags'),
+ 'uid' => $qb->createNamedParameter($user),
'category' => $qb->createNamedParameter($category),
'type' => $qb->createNamedParameter($type),
])