From dbb4dbc671e545d6b4e1b34950adc5e313d07f8a Mon Sep 17 00:00:00 2001 From: Jonathan Treffler Date: Thu, 17 Oct 2024 13:15:38 +0200 Subject: [PATCH] added resource mapper --- lib/Db/ResourceMapper.php | 201 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 lib/Db/ResourceMapper.php diff --git a/lib/Db/ResourceMapper.php b/lib/Db/ResourceMapper.php new file mode 100644 index 0000000..af49321 --- /dev/null +++ b/lib/Db/ResourceMapper.php @@ -0,0 +1,201 @@ +db->getQueryBuilder(); + + $qb->select('resource.*', 'folder.members_acl_permission', 'folder.managers_acl_permission', 'folder.inherited_acl_permission') + ->from(self::RESOURCES_TABLE, "resource") + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))); + + $qb->leftJoin('resource', self::FOLDER_RESOURCES_TABLE, 'folder', $qb->expr()->eq('resource.id', 'folder.resource_id'),); + + return $this->findEntity($qb); + } + + /** + * @param int $groupfolderId + * @param int $parentResourceId + * @return array + */ + public function findAll(int $groupfolderId, ?int $parentResourceId = null): array { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + + $qb->select('resource.*', 'folder.members_acl_permission', 'folder.managers_acl_permission', 'folder.inherited_acl_permission') + ->from(self::RESOURCES_TABLE, "resource") + ->where($qb->expr()->eq('group_folder_id', $qb->createNamedParameter($groupfolderId, IQueryBuilder::PARAM_INT))); + + if(is_null($parentResourceId)) { + $qb->andWhere($qb->expr()->isNull('parent_resource')); + } else { + $qb->andWhere($qb->expr()->eq('parent_resource', $qb->createNamedParameter($parentResourceId, IQueryBuilder::PARAM_INT))); + } + + $qb->leftJoin('resource', self::FOLDER_RESOURCES_TABLE, 'folder', $qb->expr()->eq('resource.id', 'folder.resource_id'),); + + return $this->findEntities($qb); + } + + /** + * Creates a new entry in the db from an entity + * + * @param Resource $entity the entity that should be created + * @psalm-param Resource $entity the entity that should be created + * @return Resource the saved entity with the set id + * @psalm-return Resource the saved entity with the set id + * @throws Exception + * @since 14.0.0 + */ + public function insert(Entity $entity): Entity { + $setProperties = array_keys($entity->getUpdatedFields()); + $setResourceProperties = array_intersect(["id", ...self::updateableResourceProperties], $setProperties); + + if($entity->getType() === "folder") { + $typeSpecificTable = self::FOLDER_RESOURCES_TABLE; + $setTypeSpecificProperties = array_intersect(self::updateableFolderResourceProperties, $setProperties); + } else { + throw new InvalidResourceType($entity->getType()); + } + + + $setProperties = function ($qb, $properties) use ($entity) { + foreach ($properties as $property) { + $column = $entity->propertyToColumn($property); + $getter = 'get' . ucfirst($property); + $value = $entity->$getter(); + + $type = $this->getParameterTypeForProperty($entity, $property); + $qb->setValue($column, $qb->createNamedParameter($value, $type)); + } + }; + + $this->atomic(function () use ($setProperties, $setResourceProperties, $entity, $typeSpecificTable, $setTypeSpecificProperties) { + // insert into resource table + $qb = $this->db->getQueryBuilder(); + $qb->insert(self::RESOURCES_TABLE); + + $setProperties($qb, $setResourceProperties); + + $qb->executeStatement(); + + if ($entity->id === null) { + // When autoincrement is used id is always an int + $entity->setId($qb->getLastInsertId()); + } + + // insert into the type specific table + $qb = $this->db->getQueryBuilder(); + $qb->insert($typeSpecificTable); + + $setProperties($qb, $setTypeSpecificProperties); + $qb->setValue("resource_id", $qb->createNamedParameter($entity->getId(), IQueryBuilder::PARAM_INT)); + + $qb->executeStatement(); + }, $this->db); + + return $entity; + } + + /** + * Updates an entry in the db from an entity + * + * @param Resource $entity the entity that should be created + * @psalm-param Resource $entity the entity that should be created + * @return Resource the saved entity with the set id + * @psalm-return Resource the saved entity with the set id + * @throws \Exception + * @throws \InvalidArgumentException if entity has no id + * @since 14.0.0 + */ + public function update(Entity $entity): Entity { + // entity needs an id + $id = $entity->getId(); + if ($id === null) { + throw new \InvalidArgumentException( + 'Entity which should be updated has no id'); + } + + $updatedProperties = array_keys($entity->getUpdatedFields()); + $updatedResourceProperties = array_intersect(self::updateableResourceProperties, $updatedProperties); + + if($entity->getType() === "folder") { + $typeSpecificTable = self::FOLDER_RESOURCES_TABLE; + $updatedTypeSpecificProperties = array_intersect(self::updateableFolderResourceProperties, $updatedProperties); + } else { + throw new InvalidResourceType($entity->getType()); + } + + $updatePropertiesInTables = function($table, $properties, $idColumn) use ($entity, $id) { + // update resource properties if any changed + if (\count($properties) === 0) { + return; + } + + $qb = $this->db->getQueryBuilder(); + $qb->update($table); + + foreach ($properties as $property) { + $column = $entity->propertyToColumn($property); + $getter = 'get' . ucfirst($property); + $value = $entity->$getter(); + + $type = $this->getParameterTypeForProperty($entity, $property); + $qb->set($column, $qb->createNamedParameter($value, $type)); + } + + $idType = $this->getParameterTypeForProperty($entity, 'id'); + + $qb->where( + $qb->expr()->eq($idColumn, $qb->createNamedParameter($id, $idType)) + ); + + $qb->executeStatement(); + }; + + $this->atomic(function () use ($updatePropertiesInTables, $updatedResourceProperties, $typeSpecificTable, $updatedTypeSpecificProperties) { + $updatePropertiesInTables(self::RESOURCES_TABLE, $updatedResourceProperties, "id"); + $updatePropertiesInTables($typeSpecificTable, $updatedTypeSpecificProperties, "resource_id"); + }, $this->db); + + return $entity; + } +} \ No newline at end of file