diff --git a/lib/Command/Tag.php b/lib/Command/Tag.php index 88b9746..7f83837 100644 --- a/lib/Command/Tag.php +++ b/lib/Command/Tag.php @@ -10,8 +10,12 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use OCA\GroupfolderTags\Service\TagService; + class Tag extends Base { - public function __construct() { + public function __construct( + private TagService $service, + ) { parent::__construct(); } @@ -26,13 +30,13 @@ class Tag extends Base { 'Add or update tag of the given groupfolder id' ) ->addOption( - 'tag_key', + 'key', null, InputOption::VALUE_REQUIRED, 'Set tag key to given value' ) ->addOption( - 'tag_value', + 'value', null, InputOption::VALUE_OPTIONAL, 'Set tag value to given value' @@ -40,11 +44,28 @@ class Tag extends Base { } protected function execute(InputInterface $input, OutputInterface $output): int { + $errors = []; + $groupFolderId = $input->getOption('groupfolder_id'); - $tagKey = $input->getOption('tag_key'); - $tagValue = $input->getOption('tag_value'); + $tagKey = $input->getOption('key'); + $tagValue = $input->getOption('value'); - $output->writeln($groupFolderId . " " . $tagKey . " " . $tagValue); - return 0; + if(!is_numeric($groupFolderId)) { + $errors[] = "no group folder id provided"; + } + + if(is_null($tagKey) || $tagKey === "") { + $errors[] = "no tag key provided"; + } + + if(empty($errors)) { + $output->writeln($groupFolderId . " " . $tagKey . " " . $tagValue); + $output->writeln(json_encode($this->service->update((int)$groupFolderId, $tagKey, $tagValue))); + return 0; + } else { + $output->writeln("Error: \n" . implode("\n", $errors)); + return 1; + } + } } \ No newline at end of file diff --git a/lib/Db/TagMapper.php b/lib/Db/TagMapper.php index d8561bd..7b0604e 100644 --- a/lib/Db/TagMapper.php +++ b/lib/Db/TagMapper.php @@ -10,6 +10,7 @@ use OCP\IDBConnection; class TagMapper extends QBMapper { public const TABLENAME = 'groupfolder_tags'; + public const GROUP_FOLDERS_TABLENAME = "group_folders"; public function __construct(IDBConnection $db) { parent::__construct($db, self::TABLENAME, Tag::class); @@ -34,8 +35,29 @@ class TagMapper extends QBMapper { } /** + * @param int $groupFolderId * @param string $tagKey - * @param string|null $tagValue + * @return Entity|Tag + * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException + * @throws DoesNotExistException + */ + public function findIncludingGroupfolder(int $groupFolderId, string $tagKey): Tag { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from(self::TABLENAME, "t") + ->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'), + )); + + return $this->findOneQuery($qb); + } + + /** + * @param string $tagKey + * @param string|null $tagValue * @return array */ public function findAll(string $tagKey, ?string $tagValue): array { @@ -45,9 +67,9 @@ class TagMapper extends QBMapper { ->from(self::TABLENAME) ->where($qb->expr()->eq('tag_key', $qb->createNamedParameter($tagKey))); - if(isset($tagValue)) { - $qb->andWhere($qb->expr()->eq('tag_value', $qb->createNamedParameter($tagValue))); - } + if(isset($tagValue)) { + $qb->andWhere($qb->expr()->eq('tag_value', $qb->createNamedParameter($tagValue))); + } return $this->findEntities($qb); } diff --git a/lib/Migration/Version000000Date20240731110600.php b/lib/Migration/Version000000Date20240731110600.php index 5d2a48a..55a8807 100644 --- a/lib/Migration/Version000000Date20240731110600.php +++ b/lib/Migration/Version000000Date20240731110600.php @@ -26,6 +26,10 @@ class Version000000Date20240731110600 extends SimpleMigrationStep { if (!$schema->hasTable(self::GROUP_FOLDER_TAGS_TABLE)) { $table = $schema->createTable(self::GROUP_FOLDER_TAGS_TABLE); + $table->addColumn('id', Types::INTEGER, [ + 'autoincrement' => true, + 'notnull' => true, + ]); $table->addColumn('group_folder_id', Types::BIGINT, [ 'notnull' => true, 'length' => 20, @@ -35,14 +39,14 @@ class Version000000Date20240731110600 extends SimpleMigrationStep { 'length' => 50, ]); $table->addColumn('tag_value', Types::STRING, [ - 'notnull' => true, + 'notnull' => false, 'length' => 200, ]); $table->addColumn('last_updated_timestamp', Types::BIGINT, [ 'notnull' => true, ]); - - $table->setPrimaryKey(['group_folder_id', 'tag_key']); + $table->setPrimaryKey(['id']); + $table->addUniqueIndex(['group_folder_id', 'tag_key'], "groupfolder_tags_group_folder_id_tag_key_index"); $table->addIndex(['group_folder_id'], 'groupfolder_tags_group_folder_id_index'); $table->addForeignKeyConstraint( $schema->getTable(self::GROUP_FOLDERS_TABLE), diff --git a/lib/Service/TagService.php b/lib/Service/TagService.php new file mode 100644 index 0000000..1127b90 --- /dev/null +++ b/lib/Service/TagService.php @@ -0,0 +1,73 @@ +mapper->findAll($tagKey, $tagValue); + } + + private function handleException(Exception $e): void { + if ($e instanceof DoesNotExistException || + $e instanceof MultipleObjectsReturnedException) { + throw new TagNotFound($e->getMessage()); + } else { + throw $e; + } + } + + public function find(int $groupFolderId, string $tagKey): Tag { + try { + return $this->mapper->find($groupFolderId, $tagKey); + } catch (Exception $e) { + $this->handleException($e); + } + } + + public function update(int $groupFolderId, string $key, ?string $value): Tag { + try { + $tag = $this->find($groupFolderId, $key); + $tagExists = True; + } catch(TagNotFound $error) { + $tag = new Tag(); + $tag->setGroupFolderId($groupFolderId); + $tag->setTagKey($key); + $tagExists = False; + } + + $tag->setTagValue($value); + + $tag->setLastUpdatedTimestamp(time()); + + if($tagExists) { + return $this->mapper->update($tag); + } else { + return $this->mapper->insert($tag); + } + } + + public function delete(int $groupFolderId, string $key): Tag { + try { + $tag = $this->mapper->find($groupFolderId, $key); + $this->mapper->delete($tag); + return $tag; + } catch (Exception $e) { + $this->handleException($e); + } + } +} \ No newline at end of file