diff --git a/lib/Db/TagMapper.php b/lib/Db/TagMapper.php index d4096c1..4e65e4e 100644 --- a/lib/Db/TagMapper.php +++ b/lib/Db/TagMapper.php @@ -42,7 +42,7 @@ class TagMapper extends QBMapper { * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException * @throws DoesNotExistException */ - public function findIncludingGroupfolder(int $groupFolderId, string $tagKey): Tag { + public function findIncludingGroupfolder(int $groupFolderId, string $tagKey): array { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); $qb->select('*') @@ -50,7 +50,7 @@ class TagMapper extends QBMapper { ->where($qb->expr()->eq('group_folder_id', $qb->createNamedParameter($groupFolderId, IQueryBuilder::PARAM_INT))) ->andWhere($qb->expr()->eq('tag_key', $qb->createNamedParameter($tagKey))) ->leftJoin('t', self::GROUP_FOLDERS_TABLENAME, 'g', $qb->expr()->andX( - $qb->expr()->eq('t.group_folder_id', 'g.id'), + $qb->expr()->eq('t.group_folder_id', 'g.folder_id'), )); return $this->findOneQuery($qb); @@ -75,6 +75,105 @@ class TagMapper extends QBMapper { return $this->findEntities($qb); } + /** + * @param string $tagKey + * @param string|null $tagValue + * @return array + */ + public function findAllIncludingGroupfolder(string $tagKey, ?string $tagValue = null): array { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from(self::TABLENAME, alias: "t") + ->where($qb->expr()->eq('tag_key', $qb->createNamedParameter($tagKey))); + + if(isset($tagValue)) { + $qb->andWhere($qb->expr()->eq('tag_value', $qb->createNamedParameter($tagValue))); + } + + $qb->leftJoin('t', self::GROUP_FOLDERS_TABLENAME, 'g', $qb->expr()->andX( + $qb->expr()->eq('t.group_folder_id', 'g.folder_id'), + )); + + return $qb->executeQuery()->fetchAll(); + } + + /** + * @param array $filters + * @param array|null $additionalReturnTags + * @return array + */ + private function findGroupfoldersWithTagsQueryBuilder(array $filters, array $additionalReturnTags = []): IQueryBuilder { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $qb->select('g.mount_point', 'g.quota', 'g.acl') + ->selectAlias('g.folder_id', 'id') + ->from(self::GROUP_FOLDERS_TABLENAME, alias: "g"); + + $index = 0; + foreach($filters as $filter) { + $alias = 'filter_' . $index; + $joinConditions = [ + $qb->expr()->eq($alias . '.group_folder_id', 'g.folder_id'), + $qb->expr()->eq($alias . '.tag_key', $qb->createNamedParameter($filter["key"])) + ]; + + if(isset($filter["value"])) { + $joinConditions[] = $qb->expr()->eq($alias . '.tag_value', $qb->createNamedParameter($filter["value"])); + } + + $qb->innerJoin('g', self::TABLENAME, $alias, $qb->expr()->andX(...$joinConditions)); + + if(isset($filter["includeInOutput"]) && $filter["includeInOutput"] === true) { + $qb->selectAlias($alias . '.tag_value', $filter["key"]); + } + + $index++; + } + + $index = 0; + foreach($additionalReturnTags as $additionalReturnTag) { + $alias = 'additional_' . $index; + + $qb->leftJoin('g', self::TABLENAME, $alias, $qb->expr()->andX( + $qb->expr()->eq($alias . '.group_folder_id', 'g.folder_id'), + $qb->expr()->eq($alias . '.tag_key', $qb->createNamedParameter($additionalReturnTag)) + )); + + $qb->selectAlias($alias . '.tag_value', $additionalReturnTag); + + $index++; + } + + return $qb; + } + + /** + * @param array $filters [key: string, (value: string), (includeInOutput: bool)] filter pairs, result is only included if + * @param array|null $additionalReturnTags array of tags to return (if set, otherwise NULL) + * @return array + */ + public function findGroupfoldersWithTags(array $filters, array $additionalReturnTags = []): array { + return $this->findGroupfoldersWithTagsQueryBuilder($filters, $additionalReturnTags)->executeQuery()->fetchAll(); + } + + /** + * @param array $filters [key: string, (value: string), (includeInOutput: bool)] filter pairs, result is only included if + * @param array|null $additionalReturnTags array of tags to return (if set, otherwise NULL) + * @return array + */ + public function findGroupfoldersWithTagsGenerator(array $filters, array $additionalReturnTags = []): \Generator { + $result = $this->findGroupfoldersWithTagsQueryBuilder($filters, $additionalReturnTags)->executeQuery(); + + try { + while ($row = $result->fetch()) { + yield $row; + } + } finally { + $result->closeCursor(); + } + } + /** * @return Tag[] * @throws Exception diff --git a/lib/Service/TagService.php b/lib/Service/TagService.php index 0cbbb25..1885488 100644 --- a/lib/Service/TagService.php +++ b/lib/Service/TagService.php @@ -22,6 +22,18 @@ class TagService { return $this->mapper->findAll($tagKey, $tagValue); } + public function findAllIncludingGroupfolder(string $tagKey, ?string $tagValue = null): array { + return $this->mapper->findAllIncludingGroupfolder($tagKey, $tagValue); + } + + public function findGroupfoldersWithTags(array $filters, array $additionalReturnTags = []): array { + return $this->mapper->findGroupfoldersWithTags($filters, $additionalReturnTags); + } + + public function findGroupfoldersWithTagsGenerator(array $filters, array $additionalReturnTags = []): \Generator { + return $this->mapper->findGroupfoldersWithTagsGenerator($filters, $additionalReturnTags); + } + private function handleException(Exception $e, int $groupFolderId, string $tagKey): void { if ($e instanceof DoesNotExistException || $e instanceof MultipleObjectsReturnedException) {