orm refactoring

This commit is contained in:
Yuri Kuznetsov
2021-04-22 17:58:06 +03:00
parent 811e5479f4
commit a6f3c879a5
5 changed files with 153 additions and 58 deletions
+26 -21
View File
@@ -53,7 +53,7 @@ use RuntimeException;
/**
* Abstraction for DB. Mapping of Entity to DB. Supposed to be used only internally. Use repositories instead.
*/
class BaseMapper implements Mapper
class BaseMapper implements RDBMapper
{
const ATTRIBUTE_DELETED = 'deleted';
@@ -218,7 +218,7 @@ class BaseMapper implements Mapper
/**
* Select related entities from DB.
*
* @return ?SthCollection|Entity
* @return Collection|Entity|null
*/
public function selectRelated(Entity $entity, string $relationName, ?Select $select = null)
{
@@ -441,17 +441,22 @@ class BaseMapper implements Mapper
/**
* Relate an entity with another entity.
*/
public function relate(Entity $entity, string $relationName, Entity $foreignEntity, ?array $columnData = null): bool
{
public function relate(
Entity $entity,
string $relationName,
Entity $foreignEntity,
?array $columnData = null
): bool {
return $this->addRelation($entity, $relationName, null, $foreignEntity, $columnData);
}
/**
* Unrelate an entity from another entity.
*/
public function unrelate(Entity $entity, string $relationName, Entity $foreignEntity): bool
public function unrelate(Entity $entity, string $relationName, Entity $foreignEntity): void
{
return $this->removeRelation($entity, $relationName, null, false, $foreignEntity);
$this->removeRelation($entity, $relationName, null, false, $foreignEntity);
}
/**
@@ -465,35 +470,35 @@ class BaseMapper implements Mapper
/**
* Unrelate an entity from another entity by a given ID.
*/
public function unrelateById(Entity $entity, string $relationName, string $id): bool
public function unrelateById(Entity $entity, string $relationName, string $id): void
{
return $this->removeRelation($entity, $relationName, $id);
$this->removeRelation($entity, $relationName, $id);
}
/**
* Unrelate all related entities.
*/
public function unrelateAll(Entity $entity, string $relationName): bool
public function unrelateAll(Entity $entity, string $relationName): void
{
return $this->removeRelation($entity, $relationName, null, true);
$this->removeRelation($entity, $relationName, null, true);
}
/**
* Update relationship columns.
*/
public function updateRelationColumns(
BaseEntity $entity,
Entity $entity,
string $relationName,
?string $id = null,
string $id,
array $columnData
): bool {
): void {
if (empty($id) || empty($relationName)) {
throw new RuntimeException("Can't update relation, empty ID or relation name.");
}
if (empty($columnData)) {
return false;
return;
}
$keySet = $this->helper->getRelationKeys($entity, $relationName);
@@ -515,7 +520,7 @@ class BaseMapper implements Mapper
}
if (empty($update)) {
return true;
return;
}
$where = [
@@ -540,7 +545,7 @@ class BaseMapper implements Mapper
$this->executeSql($sql, true);
return true;
return;
}
throw new LogicException("Relation type '{$relType}' is not supported.");
@@ -624,7 +629,7 @@ class BaseMapper implements Mapper
/**
* Mass relate.
*/
public function massRelate(BaseEntity $entity, string $relationName, Select $select): void
public function massRelate(Entity $entity, string $relationName, Select $select): void
{
$params = $select->getRaw();
@@ -1010,7 +1015,7 @@ class BaseMapper implements Mapper
?string $id = null,
bool $all = false,
?Entity $relEntity = null
): bool {
): void {
if ($relEntity) {
$id = $relEntity->id;
@@ -1098,7 +1103,7 @@ class BaseMapper implements Mapper
$this->executeSql($sql, true);
return true;
return;
case Entity::HAS_ONE:
case Entity::HAS_MANY:
@@ -1135,7 +1140,7 @@ class BaseMapper implements Mapper
$this->executeSql($sql, true);
return true;
return;
case Entity::MANY_MANY:
$nearKey = $keySet['nearKey'];
@@ -1173,7 +1178,7 @@ class BaseMapper implements Mapper
$this->executeSql($sql, true);
return true;
return;
}
throw new LogicException("Relation type '{$relType}' is not supported for unrelating.");
+98
View File
@@ -0,0 +1,98 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\ORM\Mapper;
use Espo\ORM\{
Entity,
Collection,
QueryParams\Select,
};
interface RDBMapper extends Mapper
{
/**
* Relate an entity with another entity.
*/
public function relate(Entity $entity, string $relationName, Entity $foreignEntity, ?array $columnData): bool;
/**
* Unrelate an entity from another entity.
*/
public function unrelate(Entity $entity, string $relationName, Entity $foreignEntity): void;
/**
* Unrelate an entity from another entity by a given ID.
*/
public function relateById(Entity $entity, string $relationName, string $id, ?array $columnData = null): bool;
/**
* Unrelate an entity from another entity by a given ID.
*/
public function unrelateById(Entity $entity, string $relationName, string $id): void;
/**
* Mass relate.
*/
public function massRelate(Entity $entity, string $relationName, Select $select): void;
/**
* Update relationship columns.
*/
public function updateRelationColumns(
Entity $entity,
string $relationName,
string $id,
array $columnData
): void;
/**
* Get a relationship column value.
*
* @return string|int|float|bool|null A relationship column value.
*/
public function getRelationColumn(
Entity $entity,
string $relationName,
string $id,
string $column
);
/**
* Select related entities from DB.
*
* @return Collection|Entity|null
*/
public function selectRelated(Entity $entity, string $relationName, ?Select $select = null);
/**
* Get a number of related entities in DB.
*/
public function countRelated(Entity $entity, string $relationName, ?Select $select = null): int;
}
@@ -34,7 +34,7 @@ use Espo\ORM\{
Entity,
EntityManager,
QueryParams\Select,
Mapper\Mapper,
Mapper\RDBMapper,
Repository\RDBRelationSelectBuilder as Builder,
};
@@ -124,7 +124,7 @@ class RDBRelation
return $this->relationType === Entity::BELONGS_TO_PARENT;
}
protected function getMapper(): Mapper
protected function getMapper(): RDBMapper
{
return $this->entityManager->getMapper();
}
@@ -245,7 +245,7 @@ class RDBRelation
* @see Espo\ORM\QueryParams\SelectBuilder::order()
*
* @param string|int|array $orderBy
* @param bool|string $direction
* @param bool|string $direction
*/
public function order($orderBy, $direction = 'ASC'): Builder
{
@@ -380,6 +380,7 @@ class RDBRelation
}
$seed = $this->entityManager->getEntityFactory()->create($this->foreignEntityType);
$seed->set('id', $id);
$this->relate($seed, $columnData, $options);
@@ -399,6 +400,7 @@ class RDBRelation
}
$seed = $this->entityManager->getEntityFactory()->create($this->foreignEntityType);
$seed->set('id', $id);
$this->unrelate($seed, $options);
@@ -450,11 +452,7 @@ class RDBRelation
$this->beforeUnrelate($entity, $options);
$result = $this->getMapper()->unrelate($this->entity, $this->relationName, $entity);
if (!$result) {
return;
}
$this->getMapper()->unrelate($this->entity, $this->relationName, $entity);
$this->afterUnrelate($entity, $options);
}
@@ -487,7 +485,7 @@ class RDBRelation
throw new RuntimeException("Can't update not many-to-many relation.");
}
$this->getMapper()->updateRelationColumns($this->entity, $this->relationName, $entity->id, $columnData);
$this->getMapper()->updateRelationColumns($this->entity, $this->relationName, $entity->getId(), $columnData);
}
/**
@@ -503,7 +501,7 @@ class RDBRelation
throw new RuntimeException("Can't get a column of not many-to-many relation.");
}
return $this->getMapper()->getRelationColumn($this->entity, $this->relationName, $entity->id, $column);
return $this->getMapper()->getRelationColumn($this->entity, $this->relationName, $entity->getId(), $column);
}
protected function beforeRelate(Entity $entity, ?array $columnData, array $options): void
@@ -35,7 +35,7 @@ use Espo\ORM\{
Collection,
SthCollection,
Entity,
Mapper\Mapper,
Mapper\RDBMapper,
QueryParams\Select,
};
@@ -57,18 +57,14 @@ class RDBRepository extends Repository
EntityFactory $entityFactory,
?HookMediator $hookMediator = null
) {
$this->entityType = $entityType;
$this->entityManager = $entityManager;
$this->entityFactory = $entityFactory;
$this->seed = $this->entityFactory->create($entityType);
parent::__construct($entityType, $entityManager, $entityFactory);
$this->hookMediator = $hookMediator ?? (new EmptyHookMediator());
$this->transactionManager = new RDBTransactionManager($entityManager->getTransactionManager());
}
protected function getMapper(): Mapper
protected function getMapper(): RDBMapper
{
return $this->entityManager->getMapper();
}
@@ -345,12 +341,10 @@ class RDBRepository extends Repository
];
}
$select = $this->entityManager->getQueryBuilder()
return $this->entityManager->getQueryBuilder()
->clone($select)
->select($selectItemList)
->build();
return $select;
}
protected function applyRelationAdditionalColumnsConditions(
@@ -506,6 +500,7 @@ class RDBRepository extends Repository
$this->beforeUnrelate($entity, $relationName, $foreign, $options);
$beforeMethodName = 'beforeUnrelate' . ucfirst($relationName);
if (method_exists($this, $beforeMethodName)) {
$this->$beforeMethodName($entity, $foreign, $options);
}
@@ -515,23 +510,25 @@ class RDBRepository extends Repository
$methodName = 'unrelate' . ucfirst($relationName);
if (method_exists($this, $methodName)) {
$result = $this->$methodName($entity, $foreign);
} else {
$this->$methodName($entity, $foreign);
}
else {
if ($foreign instanceof Entity) {
$result = $this->getMapper()->unrelate($entity, $relationName, $foreign);
} else {
$this->getMapper()->unrelate($entity, $relationName, $foreign);
}
else {
$id = $foreign;
$result = $this->getMapper()->unrelateById($entity, $relationName, $id);
$this->getMapper()->unrelateById($entity, $relationName, $id);
}
}
if ($result) {
$this->afterUnrelate($entity, $relationName, $foreign, $options);
$this->afterUnrelate($entity, $relationName, $foreign, $options);
$afterMethodName = 'afterUnrelate' . ucfirst($relationName);
if (method_exists($this, $afterMethodName)) {
$this->$afterMethodName($entity, $foreign, $options);
}
$afterMethodName = 'afterUnrelate' . ucfirst($relationName);
if (method_exists($this, $afterMethodName)) {
$this->$afterMethodName($entity, $foreign, $options);
}
return $result;
@@ -596,7 +593,9 @@ class RDBRepository extends Repository
throw new RuntimeException("Bad foreign value.");
}
return $this->getMapper()->updateRelationColumns($entity, $relationName, $id, $columnData);
$this->getMapper()->updateRelationColumns($entity, $relationName, $id, $columnData);
return true;
}
/**
@@ -44,18 +44,13 @@ abstract class Repository
protected $entityManager;
protected $seed;
protected $entityType;
public function __construct(string $entityType, EntityManager $entityManager, EntityFactory $entityFactory)
{
$this->entityType = $entityType;
$this->entityFactory = $entityFactory;
$this->entityManager = $entityManager;
$this->seed = $this->entityFactory->create($entityType);
}
protected function getEntityFactory(): EntityFactory