Clean up tags of deleted users
This commit is contained in:
parent
ce676c4eb6
commit
123bf78ca8
|
@ -127,7 +127,7 @@ class Repair implements IOutput{
|
||||||
new RepairLegacyStorages(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
|
new RepairLegacyStorages(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
|
||||||
new AssetCache(),
|
new AssetCache(),
|
||||||
new FillETags(\OC::$server->getDatabaseConnection()),
|
new FillETags(\OC::$server->getDatabaseConnection()),
|
||||||
new CleanTags(\OC::$server->getDatabaseConnection()),
|
new CleanTags(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager()),
|
||||||
new DropOldTables(\OC::$server->getDatabaseConnection()),
|
new DropOldTables(\OC::$server->getDatabaseConnection()),
|
||||||
new DropOldJobs(\OC::$server->getJobList()),
|
new DropOldJobs(\OC::$server->getJobList()),
|
||||||
new RemoveGetETagEntries(\OC::$server->getDatabaseConnection()),
|
new RemoveGetETagEntries(\OC::$server->getDatabaseConnection()),
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace OC\Repair;
|
||||||
|
|
||||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||||
use OCP\IDBConnection;
|
use OCP\IDBConnection;
|
||||||
|
use OCP\IUserManager;
|
||||||
use OCP\Migration\IOutput;
|
use OCP\Migration\IOutput;
|
||||||
use OCP\Migration\IRepairStep;
|
use OCP\Migration\IRepairStep;
|
||||||
|
|
||||||
|
@ -38,11 +39,18 @@ class CleanTags implements IRepairStep {
|
||||||
/** @var IDBConnection */
|
/** @var IDBConnection */
|
||||||
protected $connection;
|
protected $connection;
|
||||||
|
|
||||||
|
/** @var IUserManager */
|
||||||
|
protected $userManager;
|
||||||
|
|
||||||
|
protected $deletedTags = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param IDBConnection $connection
|
* @param IDBConnection $connection
|
||||||
|
* @param IUserManager $userManager
|
||||||
*/
|
*/
|
||||||
public function __construct(IDBConnection $connection) {
|
public function __construct(IDBConnection $connection, IUserManager $userManager) {
|
||||||
$this->connection = $connection;
|
$this->connection = $connection;
|
||||||
|
$this->userManager = $userManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,11 +64,58 @@ class CleanTags implements IRepairStep {
|
||||||
* Updates the configuration after running an update
|
* Updates the configuration after running an update
|
||||||
*/
|
*/
|
||||||
public function run(IOutput $output) {
|
public function run(IOutput $output) {
|
||||||
|
$this->deleteOrphanTags($output);
|
||||||
$this->deleteOrphanFileEntries($output);
|
$this->deleteOrphanFileEntries($output);
|
||||||
$this->deleteOrphanTagEntries($output);
|
$this->deleteOrphanTagEntries($output);
|
||||||
$this->deleteOrphanCategoryEntries($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
|
* Delete tag entries for deleted files
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,6 +25,9 @@ class CleanTagsTest extends \Test\TestCase {
|
||||||
/** @var \OCP\IDBConnection */
|
/** @var \OCP\IDBConnection */
|
||||||
protected $connection;
|
protected $connection;
|
||||||
|
|
||||||
|
/** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
protected $userManager;
|
||||||
|
|
||||||
/** @var int */
|
/** @var int */
|
||||||
protected $createdFile;
|
protected $createdFile;
|
||||||
|
|
||||||
|
@ -38,8 +41,12 @@ class CleanTagsTest extends \Test\TestCase {
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
|
$this->userManager = $this->getMockBuilder('\OCP\IUserManager')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
$this->connection = \OC::$server->getDatabaseConnection();
|
$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();
|
$this->cleanUpTables();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +93,20 @@ class CleanTagsTest extends \Test\TestCase {
|
||||||
self::invokePrivate($this->repair, 'deleteOrphanCategoryEntries', [$this->outputMock]);
|
self::invokePrivate($this->repair, 'deleteOrphanCategoryEntries', [$this->outputMock]);
|
||||||
$this->assertEntryCount('vcategory_to_object', 2, 'Assert tag entries count after cleaning category entries');
|
$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->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 $category
|
||||||
* @param string $type
|
* @param string $type
|
||||||
|
* @param string $user
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
protected function addTagCategory($category, $type) {
|
protected function addTagCategory($category, $type, $user = 'TestRepairCleanTags') {
|
||||||
$qb = $this->connection->getQueryBuilder();
|
$qb = $this->connection->getQueryBuilder();
|
||||||
$qb->insert('vcategory')
|
$qb->insert('vcategory')
|
||||||
->values([
|
->values([
|
||||||
'uid' => $qb->createNamedParameter('TestRepairCleanTags'),
|
'uid' => $qb->createNamedParameter($user),
|
||||||
'category' => $qb->createNamedParameter($category),
|
'category' => $qb->createNamedParameter($category),
|
||||||
'type' => $qb->createNamedParameter($type),
|
'type' => $qb->createNamedParameter($type),
|
||||||
])
|
])
|
||||||
|
|
Loading…
Reference in New Issue