Remove shares where the parent does not exist anymore

This commit is contained in:
Joas Schilling 2015-10-19 15:39:39 +02:00
parent 527ef76dd6
commit ca2fd30073
2 changed files with 110 additions and 0 deletions

View File

@ -70,11 +70,43 @@ class RepairInvalidShares extends BasicEmitter implements \OC\RepairStep {
}
}
/**
* Remove shares where the parent share does not exist anymore
*/
private function removeSharesNonExistingParent() {
$deletedEntries = 0;
$query = $this->connection->getQueryBuilder();
$query->select('s1.parent')
->from('share', 's1')
->where($query->expr()->isNotNull('s1.parent'))
->andWhere($query->expr()->isNull('s2.id'))
->leftJoin('s1', 'share', 's2', $query->expr()->eq('s1.parent', 's2.id'))
->groupBy('s1.parent');
$deleteQuery = $this->connection->getQueryBuilder();
$deleteQuery->delete('share')
->where($query->expr()->eq('parent', $deleteQuery->createParameter('parent')));
$result = $query->execute();
while ($row = $result->fetch()) {
$deletedEntries += $deleteQuery->setParameter('parent', (int) $row['parent'])
->execute();
}
$result->closeCursor();
if ($deletedEntries) {
$this->emit('\OC\Repair', 'info', array('Removed ' . $deletedEntries . ' shares where the parent did not exist'));
}
}
public function run() {
$ocVersionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0');
if (version_compare($ocVersionFromBeforeUpdate, '8.2.0.7', '<')) {
// this situation was only possible before 8.2
$this->removeExpirationDateFromNonLinkShares();
}
$this->removeSharesNonExistingParent();
}
}

View File

@ -119,5 +119,83 @@ class RepairInvalidSharesTest extends TestCase {
$this->assertNull($userShare['expiration'], 'bogus expiration date was removed');
$this->assertNotNull($linkShare['expiration'], 'valid link share expiration date still there');
}
/**
* Test remove shares where the parent share does not exist anymore
*/
public function testSharesNonExistingParent() {
$qb = $this->connection->getQueryBuilder();
$shareValues = [
'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_USER),
'share_with' => $qb->expr()->literal('recipientuser1'),
'uid_owner' => $qb->expr()->literal('user1'),
'item_type' => $qb->expr()->literal('folder'),
'item_source' => $qb->expr()->literal(123),
'item_target' => $qb->expr()->literal('/123'),
'file_source' => $qb->expr()->literal(123),
'file_target' => $qb->expr()->literal('/test'),
'permissions' => $qb->expr()->literal(1),
'stime' => $qb->expr()->literal(time()),
'expiration' => $qb->expr()->literal('2015-09-25 00:00:00')
];
// valid share
$qb = $this->connection->getQueryBuilder();
$qb->insert('share')
->values($shareValues)
->execute();
$parent = $this->getLastShareId();
// share with existing parent
$qb = $this->connection->getQueryBuilder();
$qb->insert('share')
->values(array_merge($shareValues, [
'parent' => $qb->expr()->literal($parent),
]))->execute();
$validChild = $this->getLastShareId();
// share with non-existing parent
$qb = $this->connection->getQueryBuilder();
$qb->insert('share')
->values(array_merge($shareValues, [
'parent' => $qb->expr()->literal($parent + 100),
]))->execute();
$invalidChild = $this->getLastShareId();
$query = $this->connection->getQueryBuilder();
$result = $query->select('id')
->from('share')
->orderBy('id', 'ASC')
->execute();
$rows = $result->fetchAll();
$this->assertSame([['id' => $parent], ['id' => $validChild], ['id' => $invalidChild]], $rows);
$result->closeCursor();
$this->repair->run();
$query = $this->connection->getQueryBuilder();
$result = $query->select('id')
->from('share')
->orderBy('id', 'ASC')
->execute();
$rows = $result->fetchAll();
$this->assertSame([['id' => $parent], ['id' => $validChild]], $rows);
$result->closeCursor();
}
/**
* @return int
*/
protected function getLastShareId() {
// select because lastInsertId does not work with OCI
$query = $this->connection->getQueryBuilder();
$result = $query->select('id')
->from('share')
->orderBy('id', 'DESC')
->execute();
$row = $result->fetch();
$result->closeCursor();
return $row['id'];
}
}