Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

collection: add toMemoryCollection() (BC break!) #533

Merged
merged 1 commit into from
Aug 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/Collection/ArrayCollection.php
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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