perf: Group queries for fetching overview cards

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl
2023-02-16 11:32:42 +01:00
parent 96d1e14390
commit 8ec8a91cab
3 changed files with 24 additions and 32 deletions

View File

@@ -254,13 +254,13 @@ class CardMapper extends QBMapper implements IPermissionMapper {
return $this->findEntities($qb); return $this->findEntities($qb);
} }
public function findAllWithDue($boardId) { public function findAllWithDue(array $boardIds) {
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->select('c.*') $qb->select('c.*')
->from('deck_cards', 'c') ->from('deck_cards', 'c')
->innerJoin('c', 'deck_stacks', 's', 's.id = c.stack_id') ->innerJoin('c', 'deck_stacks', 's', 's.id = c.stack_id')
->innerJoin('s', 'deck_boards', 'b', 'b.id = s.board_id') ->innerJoin('s', 'deck_boards', 'b', 'b.id = s.board_id')
->where($qb->expr()->eq('s.board_id', $qb->createNamedParameter($boardId, IQueryBuilder::PARAM_INT))) ->where($qb->expr()->in('s.board_id', $qb->createNamedParameter($boardIds, IQueryBuilder::PARAM_INT_ARRAY)))
->andWhere($qb->expr()->isNotNull('c.duedate')) ->andWhere($qb->expr()->isNotNull('c.duedate'))
->andWhere($qb->expr()->eq('c.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL))) ->andWhere($qb->expr()->eq('c.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
->andWhere($qb->expr()->eq('c.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))) ->andWhere($qb->expr()->eq('c.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
@@ -270,14 +270,14 @@ class CardMapper extends QBMapper implements IPermissionMapper {
return $this->findEntities($qb); return $this->findEntities($qb);
} }
public function findToMeOrNotAssignedCards($boardId, $username) { public function findToMeOrNotAssignedCards(array $boardIds, string $username) {
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->select('c.*') $qb->select('c.*')
->from('deck_cards', 'c') ->from('deck_cards', 'c')
->innerJoin('c', 'deck_stacks', 's', 's.id = c.stack_id') ->innerJoin('c', 'deck_stacks', 's', 's.id = c.stack_id')
->innerJoin('s', 'deck_boards', 'b', 'b.id = s.board_id') ->innerJoin('s', 'deck_boards', 'b', 'b.id = s.board_id')
->leftJoin('c', 'deck_assigned_users', 'u', 'c.id = u.card_id') ->leftJoin('c', 'deck_assigned_users', 'u', 'c.id = u.card_id')
->where($qb->expr()->eq('s.board_id', $qb->createNamedParameter($boardId, IQueryBuilder::PARAM_INT))) ->where($qb->expr()->in('s.board_id', $qb->createNamedParameter($boardIds, IQueryBuilder::PARAM_INT_ARRAY)))
->andWhere($qb->expr()->orX( ->andWhere($qb->expr()->orX(
$qb->expr()->eq('u.participant', $qb->createNamedParameter($username, IQueryBuilder::PARAM_STR)), $qb->expr()->eq('u.participant', $qb->createNamedParameter($username, IQueryBuilder::PARAM_STR)),
$qb->expr()->isNull('u.participant')) $qb->expr()->isNull('u.participant'))

View File

@@ -145,12 +145,12 @@ class CardService {
$assignedUsers = $this->assignedUsersMapper->findIn($cardIds); $assignedUsers = $this->assignedUsersMapper->findIn($cardIds);
foreach ($cards as $card) { foreach ($cards as $card) {
$cardLabels = array_filter($assignedLabels, function (Label $label) use ($card) { $cardLabels = array_values(array_filter($assignedLabels, function (Label $label) use ($card) {
return $label->getCardId() === $card->getId(); return $label->getCardId() === $card->getId();
}); }));
$cardAssignedUsers = array_filter($assignedUsers, function (Assignment $assignment) use ($card) { $cardAssignedUsers = array_values(array_filter($assignedUsers, function (Assignment $assignment) use ($card) {
return $assignment->getCardId() === $card->getId(); return $assignment->getCardId() === $card->getId();
}); }));
$card->setLabels($cardLabels); $card->setLabels($cardLabels);
$card->setAssignedUsers($cardAssignedUsers); $card->setAssignedUsers($cardAssignedUsers);
} }

View File

@@ -28,6 +28,7 @@ declare(strict_types=1);
namespace OCA\Deck\Service; namespace OCA\Deck\Service;
use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\AssignmentMapper;
use OCA\Deck\Db\Board;
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;
@@ -65,34 +66,25 @@ class OverviewService {
$this->attachmentService = $attachmentService; $this->attachmentService = $attachmentService;
} }
public function findAllWithDue(string $userId): array {
$userBoards = $this->boardMapper->findAllForUser($userId);
$allDueCards = [];
foreach ($userBoards as $userBoard) {
$allDueCards[] = array_map(function ($card) use ($userBoard, $userId) {
return (new CardDetails($card, $userBoard))->jsonSerialize();
}, $this->cardMapper->findAllWithDue($userBoard->getId()));
}
return $this->cardService->enrichCards(array_merge(...$allDueCards));
}
public function findUpcomingCards(string $userId): array { public function findUpcomingCards(string $userId): array {
$userBoards = $this->boardMapper->findAllForUser($userId); $userBoards = $this->boardMapper->findAllForUser($userId);
$overview = [];
foreach ($userBoards as $userBoard) { $boardOwnerIds = array_filter(array_map(function (Board $board) {
if (count($userBoard->getAcl()) === 0) { return count($board->getAcl()) === 0 ? $board->getId() : null;
}, $userBoards));
$boardSharedIds = array_filter(array_map(function (Board $board) {
return count($board->getAcl()) > 0 ? $board->getId() : null;
}, $userBoards));
$foundCards = array_merge(
// private board: get cards with due date // private board: get cards with due date
$cards = $this->cardMapper->findAllWithDue($userBoard->getId()); $this->cardMapper->findAllWithDue($boardOwnerIds),
} else {
// shared board: get all my assigned or unassigned cards // shared board: get all my assigned or unassigned cards
$cards = $this->cardMapper->findToMeOrNotAssignedCards($userBoard->getId(), $userId); $this->cardMapper->findToMeOrNotAssignedCards($boardSharedIds, $userId)
} );
$foundCards[] = $cards;
}
$foundCards = array_merge(...$foundCards);
$this->cardService->enrichCards($foundCards); $this->cardService->enrichCards($foundCards);
$overview = [];
foreach ($foundCards as $card) { foreach ($foundCards as $card) {
$diffDays = $card->getDaysUntilDue(); $diffDays = $card->getDaysUntilDue();
@@ -109,7 +101,7 @@ class OverviewService {
$key = 'nextSevenDays'; $key = 'nextSevenDays';
} }
$card = (new CardDetails($card, $userBoard)); $card = (new CardDetails($card, $card->getRelatedBoard()));
$overview[$key][] = $card->jsonSerialize(); $overview[$key][] = $card->jsonSerialize();
} }
return $overview; return $overview;