mirror of https://github.com/nextcloud/bookmarks
Enhance bookmark queries (#1182)
Don't query tags per bookmark separately
This commit is contained in:
parent
6cf7ffccf3
commit
41e91392f7
|
@ -158,7 +158,9 @@ class BookmarkController extends ApiController {
|
|||
$array['folders'] = array_map(function (Folder $folder) {
|
||||
return $this->toExternalFolderId($folder->getId());
|
||||
}, $array['folders']);
|
||||
$array['tags'] = $this->tagMapper->findByBookmark($bookmark->getId());
|
||||
if (!isset($array['tags'])) {
|
||||
$array['tags'] = $this->tagMapper->findByBookmark($bookmark->getId());
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,21 @@ class BookmarkMapper extends QBMapper {
|
|||
$this->tagMapper = $tagMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic to use BookmarkWithTags if possible
|
||||
* @param array $row
|
||||
* @return Entity
|
||||
*/
|
||||
protected function mapRowToEntity(array $row): Entity {
|
||||
$hasTags = array_first($row, function ($field) {
|
||||
return preg_match('#tag#i', $field, $matches) !== false;
|
||||
}, false);
|
||||
if ($hasTags !== false) {
|
||||
return BookmarkWithTags::fromRow($row);
|
||||
}
|
||||
return \call_user_func($this->entityClass .'::fromRow', $row);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find a specific bookmark by Id
|
||||
|
@ -188,14 +203,18 @@ class BookmarkMapper extends QBMapper {
|
|||
if ($params->getConjunction() === 'or') {
|
||||
$connectWord = 'OR';
|
||||
}
|
||||
if (count($filters) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// select tags
|
||||
if ($dbType === 'pgsql') {
|
||||
$tags = $qb->createFunction('array_to_string(array_agg(' . $qb->getColumnName('t.tag') . "), ',')");
|
||||
} else {
|
||||
$tags = $qb->createFunction('GROUP_CONCAT(' . $qb->getColumnName('t.tag') . ')');
|
||||
}
|
||||
$qb->selectAlias($tags, 'tags');
|
||||
|
||||
if (count($filters) === 0) {
|
||||
return;
|
||||
}
|
||||
$filterExpressions = [];
|
||||
$otherColumns = ['b.url', 'b.title', 'b.description'];
|
||||
foreach ($filters as $filter) {
|
||||
|
@ -217,6 +236,20 @@ class BookmarkMapper extends QBMapper {
|
|||
$qb->having($filterExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $qb
|
||||
*/
|
||||
private function _selectTags($qb): void {
|
||||
$dbType = $this->config->getSystemValue('dbtype', 'sqlite');
|
||||
$qb->leftJoin('b', 'bookmarks_tags', 't', $qb->expr()->eq('t.bookmark_id', 'b.id'));
|
||||
if ($dbType === 'pgsql') {
|
||||
$tags = $qb->createFunction('array_to_string(array_agg(' . $qb->getColumnName('t.tag') . "), ',')");
|
||||
} else {
|
||||
$tags = $qb->createFunction('GROUP_CONCAT(' . $qb->getColumnName('t.tag') . ')');
|
||||
}
|
||||
$qb->selectAlias($tags, 'tags');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $userId
|
||||
* @param QueryParameters $params
|
||||
|
@ -238,6 +271,7 @@ class BookmarkMapper extends QBMapper {
|
|||
))
|
||||
->andWhere($qb->expr()->eq('b.available', $qb->createPositionalParameter(false, IQueryBuilder::PARAM_BOOL)));
|
||||
|
||||
$this->_selectTags($qb);
|
||||
$this->_queryBuilderSortAndPaginate($qb, $params);
|
||||
|
||||
return $this->findEntities($qb);
|
||||
|
@ -260,6 +294,7 @@ class BookmarkMapper extends QBMapper {
|
|||
->where($qb->expr()->eq('tr.parent_folder', $qb->createPositionalParameter($folderId, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->eq('tr.type', $qb->createPositionalParameter(TreeMapper::TYPE_BOOKMARK)));
|
||||
|
||||
$this->_selectTags($qb);
|
||||
$this->_queryBuilderSortAndPaginate($qb, $params);
|
||||
|
||||
return $this->findEntities($qb);
|
||||
|
@ -288,6 +323,14 @@ class BookmarkMapper extends QBMapper {
|
|||
))
|
||||
->andWhere($qb->expr()->eq('t.tag', $qb->createPositionalParameter($tag)));
|
||||
|
||||
$dbType = $this->config->getSystemValue('dbtype', 'sqlite');
|
||||
if ($dbType === 'pgsql') {
|
||||
$tags = $qb->createFunction('array_to_string(array_agg(' . $qb->getColumnName('t.tag') . "), ',')");
|
||||
} else {
|
||||
$tags = $qb->createFunction('GROUP_CONCAT(' . $qb->getColumnName('t.tag') . ')');
|
||||
}
|
||||
$qb->selectAlias($tags, 'tags');
|
||||
|
||||
$this->_queryBuilderSortAndPaginate($qb, $params);
|
||||
|
||||
return $this->findEntities($qb);
|
||||
|
@ -309,6 +352,14 @@ class BookmarkMapper extends QBMapper {
|
|||
$qb->expr()->eq('sf.user_id', $qb->createPositionalParameter($userId))
|
||||
));
|
||||
|
||||
$dbType = $this->config->getSystemValue('dbtype', 'sqlite');
|
||||
if ($dbType === 'pgsql') {
|
||||
$tags = $qb->createFunction('array_to_string(array_agg(' . $qb->getColumnName('t.tag') . "), ',')");
|
||||
} else {
|
||||
$tags = $qb->createFunction('GROUP_CONCAT(' . $qb->getColumnName('t.tag') . ')');
|
||||
}
|
||||
$qb->selectAlias($tags, 'tags');
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\Bookmarks\Db;
|
||||
|
||||
/**
|
||||
* Class Bookmark
|
||||
*
|
||||
* @package OCA\Bookmarks\Db
|
||||
* @method getTags
|
||||
*/
|
||||
class BookmarkWithTags extends Bookmark {
|
||||
protected $tags;
|
||||
|
||||
public static $columns = ['id', 'url', 'title', 'description', 'lastmodified', 'added', 'clickcount', 'last_preview', 'available', 'archived_file', 'user_id', 'tags'];
|
||||
public static $fields = ['id', 'url', 'title', 'description', 'lastmodified', 'added', 'clickcount', 'lastPreview', 'available', 'archivedFile', 'userId', 'tags'];
|
||||
|
||||
public static function fromArray($props) {
|
||||
$bookmark = new Bookmark();
|
||||
foreach ($props as $prop => $val) {
|
||||
$bookmark->{'set' . $prop}($val);
|
||||
}
|
||||
return $bookmark;
|
||||
}
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function toArray(): array {
|
||||
$array = [];
|
||||
foreach (self::$fields as $field) {
|
||||
if ($field === 'tags') {
|
||||
$array[$field] = $this->{$field} === ''? [] : explode(',',$this->{$field});
|
||||
continue;
|
||||
}
|
||||
$array[$field] = $this->{$field};
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue