Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

Commit

Permalink
feat(entity-manager): replace heap with entity manager
Browse files Browse the repository at this point in the history
- EM store entity's data as heap previously do
- EM index entities
- EM create entity by given data or return already created entity by index
- D7 Repository try to get entity by index from EM first
  • Loading branch information
hustlahusky committed Jun 26, 2020
1 parent a2085b9 commit f72abde
Show file tree
Hide file tree
Showing 6 changed files with 441 additions and 106 deletions.
78 changes: 59 additions & 19 deletions src/DataSource/Adapters/Bitrix/AbstractD7Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use spaceonfire\Collection\CollectionInterface;
use spaceonfire\Criteria\Criteria;
use spaceonfire\Criteria\CriteriaInterface;
use spaceonfire\DataSource\Adapters\Bitrix\Heap\Heap;
use spaceonfire\DataSource\Adapters\Bitrix\Query\D7Query;
use spaceonfire\DataSource\EntityInterface;
use spaceonfire\DataSource\Exceptions\NotFoundException;
Expand All @@ -27,16 +26,40 @@
abstract class AbstractD7Repository implements RepositoryInterface
{
/**
* @var Heap
* @var EntityManagerInterface
*/
private static $heap;
private $em;
/**
* @var bool
*/
private $tryFindOneByCriteriaInEntityManagerFirst = false;

private static function getHeap(): Heap
/**
* AbstractD7Repository constructor.
* @param EntityManagerInterface $em
*/
public function __construct(EntityManagerInterface $em)
{
if (self::$heap === null) {
self::$heap = new Heap();
}
return self::$heap;
$em->registerRepository($this, $this->getRole());
$this->em = $em;
}

/**
* Returns entity role
* @return string|null
*/
public function getRole(): ?string
{
return null;
}

/**
* Enable option to try find entity in manager by criteria before making actual request to database in `findOne()`
* @param bool $value
*/
final protected function tryFindOneByCriteriaInEntityManagerFirst(bool $value = true): void
{
$this->tryFindOneByCriteriaInEntityManagerFirst = $value;
}

/**
Expand All @@ -47,7 +70,7 @@ abstract protected function getDataManager(): string;
/**
* @return Entity
*/
protected function getEntity(): Entity
final protected function getD7Entity(): Entity
{
try {
return $this->getDataManager()::getEntity();
Expand All @@ -67,7 +90,7 @@ abstract public function getMapper(): MapperInterface;
final protected function query(): QueryInterface
{
try {
return new D7Query($this->getDataManager()::query(), $this->getMapper(), self::getHeap());
return new D7Query($this->getDataManager()::query(), $this->getMapper(), $this->em);
} catch (SystemException $e) {
throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
}
Expand All @@ -78,10 +101,12 @@ final protected function query(): QueryInterface
*/
public function save($entity): void
{
$oldData = self::getHeap()->get($entity);
$oldData = $this->em->getEntityData($entity);
$data = $this->getMapper()->extract($entity);

$primary = $oldData !== null ? ORMTools::extractPrimary($this->getEntity(), $oldData) : null;
$primary = $oldData !== null ? ORMTools::extractPrimary($this->getD7Entity(), $oldData) : null;

// TODO: detect changes between $oldData and $data update only by diff

ORMTools::wrapTransaction(function () use ($primary, &$data): void {
$result = $primary
Expand All @@ -96,7 +121,7 @@ public function save($entity): void
});

$data = array_merge($oldData ?? [], $data);
self::getHeap()->attach($entity, $data);
$this->em->attachEntity($entity, $data);
$this->getMapper()->hydrate($entity, $data);
}

Expand All @@ -105,12 +130,12 @@ public function save($entity): void
*/
public function remove($entity): void
{
$oldData = self::getHeap()->get($entity);
$oldData = $this->em->getEntityData($entity);
if ($oldData === null) {
return;
}

$primary = ORMTools::extractPrimary($this->getEntity(), $oldData);
$primary = ORMTools::extractPrimary($this->getD7Entity(), $oldData);

ORMTools::wrapTransaction(function () use ($primary): void {
$result = $this->getDataManager()::delete($primary);
Expand All @@ -120,15 +145,15 @@ public function remove($entity): void
}
});

self::getHeap()->detach($entity);
$this->em->detachEntity($entity);
}

/**
* @inheritDoc
*/
public function findByPrimary($primary)
{
$primaryKeys = array_values($this->getEntity()->getPrimaryArray());
$primaryKeys = array_values($this->getD7Entity()->getPrimaryArray());

$primary = is_array($primary) ? $primary : [$primary];

Expand All @@ -138,9 +163,11 @@ public function findByPrimary($primary)

$criteria = new Criteria();
$expr = Criteria::expr();
$mapper = $this->getMapper();
$indexData = [];

foreach ($primaryKeys as $i => $key) {
$domainKey = $this->getMapper()->convertNameToDomain($key);
$domainKey = $mapper->convertNameToDomain($key);

foreach ([$domainKey, $key, $i] as $k) {
if (isset($primary[$k])) {
Expand All @@ -153,7 +180,12 @@ public function findByPrimary($primary)
throw new InvalidArgumentException('Invalid primary');
}

$criteria->andWhere($expr->property($key, $expr->same($val)));
$criteria->andWhere($expr->property($domainKey, $expr->same($val)));
$indexData[$key] = $mapper->convertValueToStorage($domainKey, $val);
}

if (null !== $entity = $this->em->getByIndex($this, $indexData)) {
return $entity;
}

$entity = $this->findOne($criteria);
Expand Down Expand Up @@ -184,6 +216,14 @@ public function findAll(?CriteriaInterface $criteria = null): CollectionInterfac
*/
public function findOne(?CriteriaInterface $criteria = null)
{
if (
$this->tryFindOneByCriteriaInEntityManagerFirst &&
$criteria !== null &&
null !== $entity = $this->em->getByCriteria($this, $criteria)
) {
return $entity;
}

$query = $this->query();

if ($criteria !== null) {
Expand Down
8 changes: 7 additions & 1 deletion src/DataSource/Adapters/Bitrix/AbstractMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ public function __construct()
* @param array<string,mixed> $data
* @return string
*/
abstract protected function resolveClass(array $data): string;
abstract public function resolveClass(array $data): string;

/**
* Returns array of keys which will be used to index entity by them
* @return string[]
*/
abstract public function getUniqueIndexes(): array;

/**
* @inheritDoc
Expand Down
Loading

0 comments on commit f72abde

Please sign in to comment.