Avoid fetching board details multiple times

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl
2021-11-23 23:34:54 +01:00
parent 80388d1a88
commit 901b8f2506
7 changed files with 52 additions and 24 deletions

View File

@@ -100,6 +100,9 @@ class ResourceProvider implements IProvider {
if ($board->getOwner() === $user->getUID()) { if ($board->getOwner() === $user->getUID()) {
return true; return true;
} }
if ($board->getAcl() === null) {
return false;
}
return $this->permissionService->userCan($board->getAcl(), Acl::PERMISSION_READ, $user->getUID()); return $this->permissionService->userCan($board->getAcl(), Acl::PERMISSION_READ, $user->getUID());
} }

View File

@@ -127,6 +127,9 @@ class ResourceProviderCard implements IProvider {
if ($board->getOwner() === $user->getUID()) { if ($board->getOwner() === $user->getUID()) {
return true; return true;
} }
if ($board->getAcl() === null) {
return false;
}
return $this->permissionService->userCan($board->getAcl(), Acl::PERMISSION_READ, $user->getUID()); return $this->permissionService->userCan($board->getAcl(), Acl::PERMISSION_READ, $user->getUID());
} }

View File

@@ -28,8 +28,10 @@ class Board extends RelationalEntity {
protected $owner; protected $owner;
protected $color; protected $color;
protected $archived = false; protected $archived = false;
protected $labels = []; /** @var Label[]|null */
protected $acl = []; protected $labels = null;
/** @var Acl[]|null */
protected $acl = null;
protected $permissions = []; protected $permissions = [];
protected $users = []; protected $users = [];
protected $shared; protected $shared;
@@ -85,4 +87,14 @@ class Board extends RelationalEntity {
public function getETag() { public function getETag() {
return md5((string)$this->getLastModified()); return md5((string)$this->getLastModified());
} }
/** @returns Acl[]|null */
public function getAcl(): ?array {
return $this->acl;
}
/** @returns Label[]|null */
public function getLabels(): ?array {
return $this->labels;
}
} }

View File

@@ -42,7 +42,10 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
private $circlesEnabled; private $circlesEnabled;
/** @var CappedMemoryCache */
private $userBoardCache; private $userBoardCache;
/** @var CappedMemoryCache */
private $boardCache;
public function __construct( public function __construct(
IDBConnection $db, IDBConnection $db,
@@ -62,7 +65,7 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
$this->logger = $logger; $this->logger = $logger;
$this->userBoardCache = new CappedMemoryCache(); $this->userBoardCache = new CappedMemoryCache();
$this->boardCache = new CappedMemoryCache();
$this->circlesEnabled = \OC::$server->getAppManager()->isEnabledForUser('circles'); $this->circlesEnabled = \OC::$server->getAppManager()->isEnabledForUser('circles');
} }
@@ -77,29 +80,31 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
* @throws DoesNotExistException * @throws DoesNotExistException
*/ */
public function find($id, $withLabels = false, $withAcl = false): Board { public function find($id, $withLabels = false, $withAcl = false): Board {
$qb = $this->db->getQueryBuilder(); if (!isset($this->boardCache[$id])) {
$qb->select('*') $qb = $this->db->getQueryBuilder();
->from('deck_boards') $qb->select('*')
->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))) ->from('deck_boards')
->orderBy('id'); ->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
$board = $this->findEntity($qb); ->orderBy('id');
$this->boardCache[$id] = $this->findEntity($qb);
}
// FIXME is this necessary? it was NOT done with the old mapper // FIXME is this necessary? it was NOT done with the old mapper
// $this->mapOwner($board); // $this->mapOwner($board);
// Add labels // Add labels
if ($withLabels) { if ($withLabels && $this->boardCache[$id]->getLabels() === null) {
$labels = $this->labelMapper->findAll($id); $labels = $this->labelMapper->findAll($id);
$board->setLabels($labels); $this->boardCache[$id]->setLabels($labels);
} }
// Add acl // Add acl
if ($withAcl) { if ($withAcl && $this->boardCache[$id]->getAcl() === null) {
$acl = $this->aclMapper->findAll($id); $acl = $this->aclMapper->findAll($id);
$board->setAcl($acl); $this->boardCache[$id]->setAcl($acl);
} }
return $board; return $this->boardCache[$id];
} }
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,
@@ -113,6 +118,9 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
$groupBoards = $this->findAllByGroups($userId, $groups, null, null, $since, $includeArchived, $before, $term); $groupBoards = $this->findAllByGroups($userId, $groups, null, null, $since, $includeArchived, $before, $term);
$circleBoards = $this->findAllByCircles($userId, null, null, $since, $includeArchived, $before, $term); $circleBoards = $this->findAllByCircles($userId, null, null, $since, $includeArchived, $before, $term);
$allBoards = array_unique(array_merge($userBoards, $groupBoards, $circleBoards)); $allBoards = array_unique(array_merge($userBoards, $groupBoards, $circleBoards));
foreach ($allBoards as $board) {
$this->boardCache[$board->getId()] = $board;
}
if ($useCache) { if ($useCache) {
$this->userBoardCache[$userId] = $allBoards; $this->userBoardCache[$userId] = $allBoards;
} }

View File

@@ -179,9 +179,11 @@ class BoardService {
/** @var Board $board */ /** @var Board $board */
$board = $this->boardMapper->find($boardId, true, true); $board = $this->boardMapper->find($boardId, true, true);
$this->boardMapper->mapOwner($board); $this->boardMapper->mapOwner($board);
foreach ($board->getAcl() as &$acl) { if ($board->getAcl() !== null) {
if ($acl !== null) { foreach ($board->getAcl() as $acl) {
$this->boardMapper->mapAcl($acl); if ($acl !== null) {
$this->boardMapper->mapAcl($acl);
}
} }
} }
$permissions = $this->permissionService->matchPermissions($board); $permissions = $this->permissionService->matchPermissions($board);

View File

@@ -117,7 +117,7 @@ class PermissionService {
*/ */
public function matchPermissions(Board $board) { public function matchPermissions(Board $board) {
$owner = $this->userIsBoardOwner($board->getId()); $owner = $this->userIsBoardOwner($board->getId());
$acls = $board->getAcl(); $acls = $board->getAcl() ?? [];
return [ return [
Acl::PERMISSION_READ => $owner || $this->userCan($acls, Acl::PERMISSION_READ), Acl::PERMISSION_READ => $owner || $this->userCan($acls, Acl::PERMISSION_READ),
Acl::PERMISSION_EDIT => $owner || $this->userCan($acls, Acl::PERMISSION_EDIT), Acl::PERMISSION_EDIT => $owner || $this->userCan($acls, Acl::PERMISSION_EDIT),
@@ -155,7 +155,7 @@ class PermissionService {
} }
try { try {
$acls = $this->getBoard($boardId)->getAcl(); $acls = $this->getBoard($boardId)->getAcl() ?? [];
$result = $this->userCan($acls, $permission, $userId); $result = $this->userCan($acls, $permission, $userId);
if ($result) { if ($result) {
return true; return true;

View File

@@ -23,12 +23,12 @@ class BoardTest extends TestCase {
'title' => "My Board", 'title' => "My Board",
'owner' => "admin", 'owner' => "admin",
'color' => "000000", 'color' => "000000",
'labels' => [], 'labels' => null,
'permissions' => [], 'permissions' => [],
'stacks' => [], 'stacks' => [],
'deletedAt' => 0, 'deletedAt' => 0,
'lastModified' => 0, 'lastModified' => 0,
'acl' => [], 'acl' => null,
'archived' => false, 'archived' => false,
'users' => ['user1', 'user2'], 'users' => ['user1', 'user2'],
'settings' => [], 'settings' => [],
@@ -49,7 +49,7 @@ class BoardTest extends TestCase {
'stacks' => [], 'stacks' => [],
'deletedAt' => 0, 'deletedAt' => 0,
'lastModified' => 0, 'lastModified' => 0,
'acl' => [], 'acl' => null,
'archived' => false, 'archived' => false,
'users' => [], 'users' => [],
'settings' => [], 'settings' => [],
@@ -72,12 +72,12 @@ class BoardTest extends TestCase {
'title' => "My Board", 'title' => "My Board",
'owner' => "admin", 'owner' => "admin",
'color' => "000000", 'color' => "000000",
'labels' => [], 'labels' => null,
'permissions' => [], 'permissions' => [],
'stacks' => [], 'stacks' => [],
'deletedAt' => 0, 'deletedAt' => 0,
'lastModified' => 0, 'lastModified' => 0,
'acl' => [], 'acl' => null,
'archived' => false, 'archived' => false,
'shared' => 1, 'shared' => 1,
'users' => [], 'users' => [],