mirror of
https://github.com/nextcloud/server.git
synced 2024-09-02 05:55:17 +02:00
perf: improve performance of resolving group shares
Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
parent
2c29d0e3ed
commit
0e7497296f
@ -829,7 +829,7 @@ class DefaultShareProvider implements IShareProvider {
|
||||
|
||||
// If the recipient is set for a group share resolve to that user
|
||||
if ($recipientId !== null && $share->getShareType() === IShare::TYPE_GROUP) {
|
||||
$share = $this->resolveGroupShares([$share], $recipientId)[0];
|
||||
$share = $this->resolveGroupShares([(int) $share->getId() => $share], $recipientId)[0];
|
||||
}
|
||||
|
||||
return $share;
|
||||
@ -1006,7 +1006,8 @@ class DefaultShareProvider implements IShareProvider {
|
||||
}
|
||||
|
||||
if ($this->isAccessibleResult($data)) {
|
||||
$shares2[] = $this->createShare($data);
|
||||
$share = $this->createShare($data);
|
||||
$shares2[$share->getId()] = $share;
|
||||
}
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
@ -1127,61 +1128,38 @@ class DefaultShareProvider implements IShareProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Share[] $shares
|
||||
* Update the data from group shares with any per-user modifications
|
||||
*
|
||||
* @param array<int, Share> $shareMap shares indexed by share id
|
||||
* @param $userId
|
||||
* @return Share[] The updates shares if no update is found for a share return the original
|
||||
*/
|
||||
private function resolveGroupShares($shares, $userId) {
|
||||
$result = [];
|
||||
private function resolveGroupShares($shareMap, $userId) {
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$query = $qb->select('*')
|
||||
->from('share')
|
||||
->where($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
|
||||
->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
|
||||
->andWhere($qb->expr()->in('item_type', [$qb->createNamedParameter('file'), $qb->createNamedParameter('folder')]));
|
||||
|
||||
$start = 0;
|
||||
while (true) {
|
||||
/** @var Share[] $shareSlice */
|
||||
$shareSlice = array_slice($shares, $start, 100);
|
||||
$start += 100;
|
||||
|
||||
if ($shareSlice === []) {
|
||||
break;
|
||||
}
|
||||
|
||||
/** @var int[] $ids */
|
||||
$ids = [];
|
||||
/** @var Share[] $shareMap */
|
||||
$shareMap = [];
|
||||
|
||||
foreach ($shareSlice as $share) {
|
||||
$ids[] = (int)$share->getId();
|
||||
$shareMap[$share->getId()] = $share;
|
||||
}
|
||||
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
|
||||
$query = $qb->select('*')
|
||||
->from('share')
|
||||
->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
|
||||
->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
|
||||
->andWhere($qb->expr()->orX(
|
||||
$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
|
||||
$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
|
||||
));
|
||||
|
||||
$stmt = $query->execute();
|
||||
|
||||
while ($data = $stmt->fetch()) {
|
||||
$shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
|
||||
$shareMap[$data['parent']]->setStatus((int)$data['accepted']);
|
||||
$shareMap[$data['parent']]->setTarget($data['file_target']);
|
||||
$shareMap[$data['parent']]->setParent($data['parent']);
|
||||
}
|
||||
|
||||
$stmt->closeCursor();
|
||||
|
||||
foreach ($shareMap as $share) {
|
||||
$result[] = $share;
|
||||
}
|
||||
// this is called with either all group shares or one group share.
|
||||
// for all shares it's easier to just only search by share_with,
|
||||
// for a single share it's efficient to filter by parent
|
||||
if (count($shareMap) === 1) {
|
||||
$share = reset($shareMap);
|
||||
$query->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())));
|
||||
}
|
||||
|
||||
return $result;
|
||||
$stmt = $query->execute();
|
||||
|
||||
while ($data = $stmt->fetch()) {
|
||||
$shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
|
||||
$shareMap[$data['parent']]->setStatus((int)$data['accepted']);
|
||||
$shareMap[$data['parent']]->setTarget($data['file_target']);
|
||||
$shareMap[$data['parent']]->setParent($data['parent']);
|
||||
}
|
||||
|
||||
return array_values($shareMap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user