Clean up tags of deleted users

This commit is contained in:
Joas Schilling 2016-06-14 12:30:22 +02:00
parent ce676c4eb6
commit 123bf78ca8
No known key found for this signature in database
GPG key ID: 70A0B324C41C0946
3 changed files with 82 additions and 5 deletions

View file

@ -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()),

View file

@ -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,11 +64,58 @@ 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
*/

View file

@ -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),
])