use term in DB query instead of filtering in php

Signed-off-by: Julien Veyssier <eneiluj@posteo.net>
This commit is contained in:
Julien Veyssier
2021-10-04 18:23:16 +02:00
parent 7425d00ba5
commit dd0a22ba04
3 changed files with 33 additions and 18 deletions

View File

@@ -94,15 +94,16 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
return $board; return $board;
} }
public function findAllForUser(string $userId, ?int $since = null, bool $includeArchived = true, ?int $before = null): array { public function findAllForUser(string $userId, ?int $since = null, bool $includeArchived = true, ?int $before = null,
$useCache = ($since === -1 && $includeArchived === true && $before === null); ?string $term = null): array {
$useCache = ($since === -1 && $includeArchived === true && $before === null && $term === null);
if (!isset($this->userBoardCache[$userId]) || !$useCache) { if (!isset($this->userBoardCache[$userId]) || !$useCache) {
$groups = $this->groupManager->getUserGroupIds( $groups = $this->groupManager->getUserGroupIds(
$this->userManager->get($userId) $this->userManager->get($userId)
); );
$userBoards = $this->findAllByUser($userId, null, null, $since, $includeArchived, $before); $userBoards = $this->findAllByUser($userId, null, null, $since, $includeArchived, $before, $term);
$groupBoards = $this->findAllByGroups($userId, $groups, null, null, $since, $includeArchived, $before); $groupBoards = $this->findAllByGroups($userId, $groups, null, null, $since, $includeArchived, $before, $term);
$circleBoards = $this->findAllByCircles($userId, null, null, $since, $includeArchived, $before); $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));
if ($useCache) { if ($useCache) {
$this->userBoardCache[$userId] = $allBoards; $this->userBoardCache[$userId] = $allBoards;
@@ -121,7 +122,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
* @return array * @return array
*/ */
public function findAllByUser(string $userId, ?int $limit = null, ?int $offset = null, ?int $since = null, public function findAllByUser(string $userId, ?int $limit = null, ?int $offset = null, ?int $since = null,
bool $includeArchived = true, ?int $before = null) { bool $includeArchived = true, ?int $before = null, ?string $term = null) {
// FIXME: One moving to QBMapper we should allow filtering the boards probably by method chaining for additional where clauses // FIXME: One moving to QBMapper we should allow filtering the boards probably by method chaining for additional where clauses
$sql = 'SELECT id, title, owner, color, archived, deleted_at, 0 as shared, last_modified FROM `*PREFIX*deck_boards` WHERE owner = ?'; $sql = 'SELECT id, title, owner, color, archived, deleted_at, 0 as shared, last_modified FROM `*PREFIX*deck_boards` WHERE owner = ?';
$params = [$userId]; $params = [$userId];
@@ -136,6 +137,10 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
$sql .= ' AND last_modified < ?'; $sql .= ' AND last_modified < ?';
$params[] = $before; $params[] = $before;
} }
if ($term !== null) {
$sql .= ' AND lower(title) LIKE ?';
$params[] = '%' . $term . '%';
}
$sql .= ' UNION ' . $sql .= ' UNION ' .
'SELECT boards.id, title, owner, color, archived, deleted_at, 1 as shared, last_modified FROM `*PREFIX*deck_boards` as boards ' . 'SELECT boards.id, title, owner, color, archived, deleted_at, 1 as shared, last_modified FROM `*PREFIX*deck_boards` as boards ' .
'JOIN `*PREFIX*deck_board_acl` as acl ON boards.id=acl.board_id WHERE acl.participant=? AND acl.type=? AND boards.owner != ?'; 'JOIN `*PREFIX*deck_board_acl` as acl ON boards.id=acl.board_id WHERE acl.participant=? AND acl.type=? AND boards.owner != ?';
@@ -151,6 +156,10 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
$sql .= ' AND last_modified < ?'; $sql .= ' AND last_modified < ?';
$params[] = $before; $params[] = $before;
} }
if ($term !== null) {
$sql .= ' AND lower(title) LIKE ?';
$params[] = '%' . $term . '%';
}
$entries = $this->findEntities($sql, $params, $limit, $offset); $entries = $this->findEntities($sql, $params, $limit, $offset);
/* @var Board $entry */ /* @var Board $entry */
foreach ($entries as $entry) { foreach ($entries as $entry) {
@@ -175,7 +184,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
* @return array * @return array
*/ */
public function findAllByGroups(string $userId, array $groups, ?int $limit = null, ?int $offset = null, ?int $since = null, public function findAllByGroups(string $userId, array $groups, ?int $limit = null, ?int $offset = null, ?int $since = null,
bool $includeArchived = true, ?int $before = null) { bool $includeArchived = true, ?int $before = null, ?string $term = null) {
if (count($groups) <= 0) { if (count($groups) <= 0) {
return []; return [];
} }
@@ -201,6 +210,10 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
$sql .= ' AND last_modified < ?'; $sql .= ' AND last_modified < ?';
$params[] = $before; $params[] = $before;
} }
if ($term !== null) {
$sql .= ' AND lower(title) LIKE ?';
$params[] = '%' . $term . '%';
}
$entries = $this->findEntities($sql, $params, $limit, $offset); $entries = $this->findEntities($sql, $params, $limit, $offset);
/* @var Board $entry */ /* @var Board $entry */
foreach ($entries as $entry) { foreach ($entries as $entry) {
@@ -211,7 +224,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
} }
public function findAllByCircles(string $userId, ?int $limit = null, ?int $offset = null, ?int $since = null, public function findAllByCircles(string $userId, ?int $limit = null, ?int $offset = null, ?int $since = null,
bool $includeArchived = true, ?int $before = null) { bool $includeArchived = true, ?int $before = null, ?string $term = null) {
if (!$this->circlesEnabled) { if (!$this->circlesEnabled) {
return []; return [];
} }
@@ -244,6 +257,10 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
$sql .= ' AND last_modified < ?'; $sql .= ' AND last_modified < ?';
$params[] = $before; $params[] = $before;
} }
if ($term !== null) {
$sql .= ' AND lower(title) LIKE ?';
$params[] = '%' . $term . '%';
}
$entries = $this->findEntities($sql, $params, $limit, $offset); $entries = $this->findEntities($sql, $params, $limit, $offset);
/* @var Board $entry */ /* @var Board $entry */
foreach ($entries as $entry) { foreach ($entries as $entry) {

View File

@@ -118,8 +118,9 @@ class BoardService {
/** /**
* Get all boards that are shared with a user, their groups or circles * Get all boards that are shared with a user, their groups or circles
*/ */
public function getUserBoards(?int $since = null, bool $includeArchived = true, ?int $before = null): array { public function getUserBoards(?int $since = null, bool $includeArchived = true, ?int $before = null,
return $this->boardMapper->findAllForUser($this->userId, $since, $includeArchived, $before); ?string $term = null): array {
return $this->boardMapper->findAllForUser($this->userId, $since, $includeArchived, $before, $term);
} }
/** /**

View File

@@ -90,22 +90,19 @@ class SearchService {
} }
public function searchBoards(string $term, ?int $limit, ?int $cursor): array { public function searchBoards(string $term, ?int $limit, ?int $cursor): array {
$boards = $this->boardService->getUserBoards(null, true, $cursor); $boards = $this->boardService->getUserBoards(null, true, $cursor, mb_strtolower($term));
// get boards that have a lastmodified date which is lower than the cursor
// and which match the search term
$filteredBoards = array_filter($boards, static function (Board $board) use ($term, $cursor) {
return mb_stripos(mb_strtolower($board->getTitle()), mb_strtolower($term)) > -1;
});
// sort the boards, recently modified first // sort the boards, recently modified first
usort($filteredBoards, function ($boardA, $boardB) { usort($boards, function ($boardA, $boardB) {
$ta = $boardA->getLastModified(); $ta = $boardA->getLastModified();
$tb = $boardB->getLastModified(); $tb = $boardB->getLastModified();
return $ta === $tb return $ta === $tb
? 0 ? 0
: ($ta > $tb ? -1 : 1); : ($ta > $tb ? -1 : 1);
}); });
// limit the number of results // limit the number of results
return array_slice($filteredBoards, 0, $limit); return array_slice($boards, 0, $limit);
} }
public function searchComments(string $term, ?int $limit = null, ?int $cursor = null): array { public function searchComments(string $term, ?int $limit = null, ?int $cursor = null): array {