perf: Enrich calls in combined sql queries

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl
2023-02-15 09:36:51 +01:00
parent 23813b7a03
commit 7bfbbee6e8
4 changed files with 72 additions and 64 deletions

View File

@@ -28,11 +28,13 @@ namespace OCA\Deck\Service;
use OCA\Deck\Activity\ActivityManager;
use OCA\Deck\Activity\ChangeSet;
use OCA\Deck\Db\Assignment;
use OCA\Deck\Db\AssignmentMapper;
use OCA\Deck\Db\Card;
use OCA\Deck\Db\CardMapper;
use OCA\Deck\Db\Acl;
use OCA\Deck\Db\ChangeHelper;
use OCA\Deck\Db\Label;
use OCA\Deck\Db\StackMapper;
use OCA\Deck\Event\CardCreatedEvent;
use OCA\Deck\Event\CardDeletedEvent;
@@ -114,32 +116,52 @@ class CardService {
$this->cardServiceValidator = $cardServiceValidator;
}
public function enrich($card) {
$cardId = $card->getId();
$this->cardMapper->mapOwner($card);
$card->setAssignedUsers($this->assignedUsersMapper->findAll($cardId));
$card->setLabels($this->labelMapper->findAssignedLabelsForCard($cardId));
$card->setAttachmentCount($this->attachmentService->count($cardId));
public function enrichCards($cards) {
$user = $this->userManager->get($this->currentUser);
$lastRead = $this->commentsManager->getReadMark('deckCard', (string)$card->getId(), $user);
$countUnreadComments = $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId(), $lastRead);
$countComments = $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId());
$card->setCommentsUnread($countUnreadComments);
$card->setCommentsCount($countComments);
$stack = $this->stackMapper->find($card->getStackId());
$board = $this->boardService->find($stack->getBoardId());
$card->setRelatedStack($stack);
$card->setRelatedBoard($board);
$cardIds = array_map(function (Card $card) {
// Everything done in here might be heavy as it is executed for every card
$cardId = $card->getId();
$this->cardMapper->mapOwner($card);
$card->setAttachmentCount($this->attachmentService->count($cardId));
// TODO We should find a better way just to get the comment count so we can save 1-3 queries per card here
$countComments = $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId());
$lastRead = $countComments > 0 ? $this->commentsManager->getReadMark('deckCard', (string)$card->getId(), $user) : null;
$countUnreadComments = $lastRead ? $this->commentsManager->getNumberOfCommentsForObject('deckCard', (string)$card->getId(), $lastRead) : 0;
$card->setCommentsUnread($countUnreadComments);
$card->setCommentsCount($countComments);
$stack = $this->stackMapper->find($card->getStackId());
$board = $this->boardService->find($stack->getBoardId(), false);
$card->setRelatedStack($stack);
$card->setRelatedBoard($board);
return $card->getId();
}, $cards);
$assignedLabels = $this->labelMapper->findAssignedLabelsForCards($cardIds);
$assignedUsers = $this->assignedUsersMapper->findIn($cardIds);
foreach ($cards as $card) {
$cardLabels = array_filter($assignedLabels, function (Label $label) use ($card) {
return $label->getCardId() === $card->getId();
});
$cardAssignedUsers = array_filter($assignedUsers, function (Assignment $label) use ($card) {
return $label->getCardId() === $card->getId();
});
$card->setLabels($cardLabels);
$card->setAssignedUsers($cardAssignedUsers);
}
return $cards;
}
public function fetchDeleted($boardId) {
$this->cardServiceValidator->check(compact('boardId'));
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
$cards = $this->cardMapper->findDeleted($boardId);
foreach ($cards as $card) {
$this->enrich($card);
}
$this->enrichCards($cards);
return $cards;
}
@@ -162,7 +184,7 @@ class CardService {
}
$card->setAssignedUsers($assignedUsers);
$card->setAttachments($attachments);
$this->enrich($card);
$this->enrichCards([$card]);
return $card;
}
@@ -174,9 +196,7 @@ class CardService {
return [];
}
$cards = $this->cardMapper->findCalendarEntries($boardId);
foreach ($cards as $card) {
$this->enrich($card);
}
$this->enrichCards($cards);
return $cards;
}