Skip to content

Commit

Permalink
collection: add toMemoryCollection() (BC break!)
Browse files Browse the repository at this point in the history
BC breaks - ICollection interface has changed
  • Loading branch information
hrach committed Aug 14, 2021
1 parent 57d7de9 commit 0857ea5
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 3 deletions.
9 changes: 8 additions & 1 deletion src/Collection/ArrayCollection.php
Expand Up @@ -21,8 +21,9 @@
/**
* @template E of IEntity
* @implements ICollection<E>
* @implements MemoryCollection<E>
*/
class ArrayCollection implements ICollection
class ArrayCollection implements ICollection, MemoryCollection
{
/**
* @var callable[]
Expand Down Expand Up @@ -246,6 +247,12 @@ public function countStored(): int
}


public function toMemoryCollection(): MemoryCollection
{
return clone $this;
}


public function setRelationshipMapper(IRelationshipMapper $mapper = null, IEntity $parent = null): ICollection
{
$this->relationshipMapper = $mapper;
Expand Down
8 changes: 8 additions & 0 deletions src/Collection/DbalCollection.php
Expand Up @@ -266,6 +266,14 @@ public function countStored(): int
}


public function toMemoryCollection(): MemoryCollection
{
$collection = clone $this;
$entities = $collection->fetchAll();
return new ArrayCollection($entities, $this->mapper->getRepository());
}


public function setRelationshipMapper(IRelationshipMapper $mapper = null, IEntity $parent = null): ICollection
{
$this->relationshipMapper = $mapper;
Expand Down
9 changes: 8 additions & 1 deletion src/Collection/EmptyCollection.php
Expand Up @@ -13,8 +13,9 @@
/**
* @template E of IEntity
* @implements ICollection<E>
* @implements MemoryCollection<E>
*/
final class EmptyCollection implements ICollection
final class EmptyCollection implements ICollection, MemoryCollection
{
/** @var IRelationshipMapper|null */
private $relationshipMapper;
Expand Down Expand Up @@ -126,6 +127,12 @@ public function count(): int
}


public function toMemoryCollection(): MemoryCollection
{
return clone $this;
}


public function subscribeOnEntityFetch(callable $callback): void
{
}
Expand Down
12 changes: 12 additions & 0 deletions src/Collection/HasManyCollection.php
Expand Up @@ -30,6 +30,9 @@ class HasManyCollection implements ICollection
*/
public $onEntityFetch = [];

/** @var IRepository<E> */
private $repository;

/**
* @var ICollection<IEntity>
* @phpstan-var ICollection<E>
Expand Down Expand Up @@ -63,6 +66,7 @@ public function __construct(
callable $diffCallback
)
{
$this->repository = $repository;
$this->storageCollection = $innerCollection;
$this->diffCallback = $diffCallback;
$this->inMemoryCollection = new MutableArrayCollection([], $repository); // @phpstan-ignore-line
Expand Down Expand Up @@ -213,6 +217,14 @@ public function countStored(): int
}


public function toMemoryCollection(): MemoryCollection
{
$collection = clone $this;
$entities = $collection->fetchAll();
return new ArrayCollection($entities, $this->repository);
}


public function setRelationshipMapper(IRelationshipMapper $mapper = null): ICollection
{
$this->storageCollection->setRelationshipMapper($mapper);
Expand Down
7 changes: 7 additions & 0 deletions src/Collection/ICollection.php
Expand Up @@ -193,6 +193,13 @@ public function fetchPairs(?string $key = null, ?string $value = null): array;
public function getIterator();


/**
* Fetches requested data and returns MemoryCollection instance with the fetched entities.
* @return MemoryCollection<E>
*/
public function toMemoryCollection(): MemoryCollection;


/**
* Sets relationship mapping over the collection.
* @return static
Expand Down
15 changes: 15 additions & 0 deletions src/Collection/MemoryCollection.php
@@ -0,0 +1,15 @@
<?php declare(strict_types = 1);

namespace Nextras\Orm\Collection;


/**
* This kind of collection promises in-memory processing of data.
*
* @template E of \Nextras\Orm\Entity\IEntity
* @extends ICollection<E>
*/
interface MemoryCollection extends ICollection
{
}

2 changes: 1 addition & 1 deletion src/Relationships/IRelationshipCollection.php
Expand Up @@ -52,7 +52,7 @@ public function toCollection(): ICollection;


/**
* Returns true if colletion was loaded.
* Returns true if collection was loaded.
*/
public function isLoaded(): bool;

Expand Down
39 changes: 39 additions & 0 deletions tests/cases/integration/Collection/collection.phpt
Expand Up @@ -8,8 +8,13 @@
namespace NextrasTests\Orm\Integration\Collection;


use Nextras\Orm\Collection\ArrayCollection;
use Nextras\Orm\Collection\DbalCollection;
use Nextras\Orm\Collection\EmptyCollection;
use Nextras\Orm\Collection\HasManyCollection;
use Nextras\Orm\Collection\ICollection;
use Nextras\Orm\Exception\NoResultException;
use NextrasTests\Orm\Author;
use NextrasTests\Orm\Book;
use NextrasTests\Orm\DataTestCase;
use NextrasTests\Orm\Ean;
Expand Down Expand Up @@ -309,6 +314,40 @@ class CollectionTest extends DataTestCase
$books = $this->orm->tagFollowers->findBy(['tag->books->id' => 1]);
Assert::count(2, $books);
}


public function testToArrayCollection(): void
{
$c1 = $this->orm->authors->findAll();
$c2 = $c1->toMemoryCollection();
Assert::type(ArrayCollection::class, $c2);
Assert::same($c2->count(), $c1->countStored());

$author = $this->orm->authors->getByIdChecked(1);
$c3 = $author->books->toCollection();
$c4 = $c3->toMemoryCollection();
if ($this->section === Helper::SECTION_ARRAY) {
Assert::type(ArrayCollection::class, $c3);
} else {
Assert::type(DbalCollection::class, $c3);
}
Assert::type(ArrayCollection::class, $c4);
Assert::same($c4->count(), $c3->countStored());

$author->books->add(new Book());
$c5 = $author->books->toCollection();
$c6 = $c5->toMemoryCollection();
Assert::type(HasManyCollection::class, $c5);
Assert::type(ArrayCollection::class, $c6);
Assert::same($c6->count(), $c5->countStored());

$author = new Author();
$c7 = $author->tagFollowers->toCollection();
$c8 = $c7->toMemoryCollection();
Assert::type(EmptyCollection::class, $c7);
Assert::type(EmptyCollection::class, $c8);
Assert::same($c8->count(), $c7->countStored());
}
}


Expand Down

0 comments on commit 0857ea5

Please sign in to comment.