Merge pull request #3983 from nextcloud/perf/sharing

Simpify query for getting shared files
This commit is contained in:
Julius Härtl
2022-08-29 11:02:09 +02:00
committed by GitHub
4 changed files with 56 additions and 50 deletions

View File

@@ -62,7 +62,7 @@ jobs:
auth_header="$(git config --local --get http.https://github.com/.extraheader)" auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
cd build/integration && composer require --dev phpunit/phpunit:~8 cd build/integration && composer require --dev phpunit/phpunit:~9
- name: Checkout app - name: Checkout app
uses: actions/checkout@v3 uses: actions/checkout@v3

View File

@@ -107,6 +107,47 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
return $this->boardCache[$id]; return $this->boardCache[$id];
} }
public function findBoardIds(string $userId): array {
$qb = $this->db->getQueryBuilder();
$qb->selectDistinct('b.id')
->from($this->getTableName(), 'b')
->leftJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id'));
// Owned by the user
$qb->where($qb->expr()->andX(
$qb->expr()->eq('owner', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)),
));
// Shared to the user
$qb->orWhere($qb->expr()->andX(
$qb->expr()->eq('acl.participant', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)),
$qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_USER, IQueryBuilder::PARAM_INT)),
));
// Shared to user groups of the user
$groupIds = $this->groupManager->getUserGroupIds($this->userManager->get($userId));
if (count($groupIds) !== 0) {
$qb->orWhere($qb->expr()->andX(
$qb->expr()->in('acl.participant', $qb->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY)),
$qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_GROUP, IQueryBuilder::PARAM_INT)),
));
}
// Shared to circles of the user
$circles = $this->circlesService->getUserCircles($userId);
if (count($circles) !== 0) {
$qb->orWhere($qb->expr()->andX(
$qb->expr()->in('acl.participant', $qb->createNamedParameter($circles, IQueryBuilder::PARAM_STR_ARRAY)),
$qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_CIRCLE, IQueryBuilder::PARAM_INT)),
));
}
$result = $qb->executeQuery();
return array_map(function (string $id) {
return (int)$id;
}, $result->fetchAll(\PDO::FETCH_COLUMN));
}
public function findAllForUser(string $userId, ?int $since = null, bool $includeArchived = true, ?int $before = null, public function findAllForUser(string $userId, ?int $since = null, bool $includeArchived = true, ?int $before = null,
?string $term = null): array { ?string $term = null): array {
$useCache = ($since === -1 && $includeArchived === true && $before === null && $term === null); $useCache = ($since === -1 && $includeArchived === true && $before === null && $term === null);

View File

@@ -32,29 +32,18 @@ use OCA\Deck\Db\Card;
use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\CardMapper;
use OCA\Deck\Model\CardDetails; use OCA\Deck\Model\CardDetails;
use OCP\Comments\ICommentsManager; use OCP\Comments\ICommentsManager;
use OCP\IGroupManager;
use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\BoardMapper;
use OCA\Deck\Db\LabelMapper; use OCA\Deck\Db\LabelMapper;
use OCP\IUserManager; use OCP\IUserManager;
class OverviewService { class OverviewService {
private BoardMapper $boardMapper;
/** @var BoardMapper */ private LabelMapper $labelMapper;
private $boardMapper; private CardMapper $cardMapper;
/** @var LabelMapper */ private AssignmentMapper $assignedUsersMapper;
private $labelMapper; private IUserManager $userManager;
/** @var CardMapper */ private ICommentsManager $commentsManager;
private $cardMapper; private AttachmentService $attachmentService;
/** @var AssignmentMapper */
private $assignedUsersMapper;
/** @var IUserManager */
private $userManager;
/** @var IGroupManager */
private $groupManager;
/** @var ICommentsManager */
private $commentsManager;
/** @var AttachmentService */
private $attachmentService;
public function __construct( public function __construct(
BoardMapper $boardMapper, BoardMapper $boardMapper,
@@ -62,7 +51,6 @@ class OverviewService {
CardMapper $cardMapper, CardMapper $cardMapper,
AssignmentMapper $assignedUsersMapper, AssignmentMapper $assignedUsersMapper,
IUserManager $userManager, IUserManager $userManager,
IGroupManager $groupManager,
ICommentsManager $commentsManager, ICommentsManager $commentsManager,
AttachmentService $attachmentService AttachmentService $attachmentService
) { ) {
@@ -71,7 +59,6 @@ class OverviewService {
$this->cardMapper = $cardMapper; $this->cardMapper = $cardMapper;
$this->assignedUsersMapper = $assignedUsersMapper; $this->assignedUsersMapper = $assignedUsersMapper;
$this->userManager = $userManager; $this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->commentsManager = $commentsManager; $this->commentsManager = $commentsManager;
$this->attachmentService = $attachmentService; $this->attachmentService = $attachmentService;
} }
@@ -93,7 +80,7 @@ class OverviewService {
} }
public function findAllWithDue(string $userId): array { public function findAllWithDue(string $userId): array {
$userBoards = $this->findAllBoardsFromUser($userId); $userBoards = $this->boardMapper->findAllForUser($userId);
$allDueCards = []; $allDueCards = [];
foreach ($userBoards as $userBoard) { foreach ($userBoards as $userBoard) {
$allDueCards[] = array_map(function ($card) use ($userBoard, $userId) { $allDueCards[] = array_map(function ($card) use ($userBoard, $userId) {
@@ -105,7 +92,7 @@ class OverviewService {
} }
public function findUpcomingCards(string $userId): array { public function findUpcomingCards(string $userId): array {
$userBoards = $this->findAllBoardsFromUser($userId); $userBoards = $this->boardMapper->findAllForUser($userId);
$foundCards = []; $foundCards = [];
foreach ($userBoards as $userBoard) { foreach ($userBoards as $userBoard) {
if (count($userBoard->getAcl()) === 0) { if (count($userBoard->getAcl()) === 0) {
@@ -126,22 +113,4 @@ class OverviewService {
} }
return array_merge(...$foundCards); return array_merge(...$foundCards);
} }
// FIXME: This is duplicate code with the board service
private function findAllBoardsFromUser(string $userId): array {
$userInfo = $this->getBoardPrerequisites($userId);
$userBoards = $this->boardMapper->findAllByUser($userInfo['user'], null, null);
$groupBoards = $this->boardMapper->findAllByGroups($userInfo['user'], $userInfo['groups'], null, null);
$circleBoards = $this->boardMapper->findAllByCircles($userInfo['user'], null, null);
return array_unique(array_merge($userBoards, $groupBoards, $circleBoards));
}
private function getBoardPrerequisites($userId): array {
$user = $this->userManager->get($userId);
$groups = $user !== null ? $this->groupManager->getUserGroupIds($user) : [];
return [
'user' => $userId,
'groups' => $groups
];
}
} }

View File

@@ -634,8 +634,8 @@ class DeckShareProvider implements \OCP\Share\IShareProvider {
$start = 0; $start = 0;
while (true) { while (true) {
/** @var IShare[] $shareSlice */ /** @var IShare[] $shareSlice */
$shareSlice = array_slice($shares, $start, 100); $shareSlice = array_slice($shares, $start, 1000);
$start += 100; $start += 1000;
if ($shareSlice === []) { if ($shareSlice === []) {
break; break;
@@ -714,15 +714,15 @@ class DeckShareProvider implements \OCP\Share\IShareProvider {
* @return IShare[] * @return IShare[]
*/ */
public function getSharedWith($userId, $shareType, $node, $limit, $offset): array { public function getSharedWith($userId, $shareType, $node, $limit, $offset): array {
$allBoards = $this->boardMapper->findAllForUser($userId); $allBoards = $this->boardMapper->findBoardIds($userId);
/** @var IShare[] $shares */ /** @var IShare[] $shares */
$shares = []; $shares = [];
$start = 0; $start = 0;
while (true) { while (true) {
$boards = array_slice($allBoards, $start, 100); $boards = array_slice($allBoards, $start, 1000);
$start += 100; $start += 1000;
if ($boards === []) { if ($boards === []) {
break; break;
@@ -752,10 +752,6 @@ class DeckShareProvider implements \OCP\Share\IShareProvider {
$qb->andWhere($qb->expr()->eq('s.file_source', $qb->createNamedParameter($node->getId()))); $qb->andWhere($qb->expr()->eq('s.file_source', $qb->createNamedParameter($node->getId())));
} }
$boards = array_map(function (Board $board) {
return $board->getId();
}, $boards);
$qb->andWhere($qb->expr()->eq('s.share_type', $qb->createNamedParameter(IShare::TYPE_DECK))) $qb->andWhere($qb->expr()->eq('s.share_type', $qb->createNamedParameter(IShare::TYPE_DECK)))
->andWhere($qb->expr()->in('db.id', $qb->createNamedParameter( ->andWhere($qb->expr()->in('db.id', $qb->createNamedParameter(
$boards, $boards,