Skip to content
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
13 changes: 3 additions & 10 deletions src/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use Respect\Data\Collections\Collection;
use Respect\Data\Collections\Composite;
use Respect\Data\Collections\Filtered;
use Respect\Data\EntityFactory;
use Respect\Data\Hydrator;
use Respect\Data\Hydrators\PrestyledAssoc;
use SplObjectStorage;
Expand All @@ -34,9 +33,9 @@ final class Mapper extends AbstractMapper
/** @var SplObjectStorage<object, true> */
private SplObjectStorage $persisting;

public function __construct(PDO|Db $db, EntityFactory $entityFactory = new EntityFactory())
public function __construct(PDO|Db $db, Hydrator $hydrator = new PrestyledAssoc())
{
parent::__construct($entityFactory);
parent::__construct($hydrator);

$this->db = $db instanceof PDO ? new Db($db) : $db;
$this->persisting = new SplObjectStorage();
Expand Down Expand Up @@ -128,11 +127,6 @@ public function flush(): void
$conn->commit();
}

protected function defaultHydrator(Collection $collection): Hydrator
{
return new PrestyledAssoc();
}

/** Resolve related entity from relation property or FK field */
private function getRelatedEntity(object $object, string $remoteField): object|null
{
Expand Down Expand Up @@ -571,10 +565,9 @@ private function parseHydrated(SplObjectStorage $hydrated): object
/** @return SplObjectStorage<object, Collection>|false */
private function fetchHydrated(Collection $collection, PDOStatement $statement): SplObjectStorage|false
{
$hydrator = $this->resolveHydrator($collection);
$row = $statement->fetch(PDO::FETCH_ASSOC);

return $hydrator->hydrate($row, $collection, $this->entityFactory);
return $this->hydrator->hydrateAll($row, $collection);
}

private function createStatement(
Expand Down
75 changes: 56 additions & 19 deletions tests/MapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Respect\Data\Collections\Filtered;
use Respect\Data\Collections\Typed;
use Respect\Data\EntityFactory;
use Respect\Data\Hydrators\PrestyledAssoc;
use Respect\Data\Styles;
use Throwable;
use TypeError;
Expand Down Expand Up @@ -141,7 +142,9 @@ protected function setUp(): void
->values([1, 'Alice', 'Alice bio'])
->exec();

$mapper = new Mapper($conn, new EntityFactory(entityNamespace: 'Respect\\Relational\\'));
$mapper = new Mapper($conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: 'Respect\\Relational\\',
)));
$this->mapper = $mapper;
$this->conn = $conn;
}
Expand Down Expand Up @@ -175,7 +178,9 @@ public function testRollingBackTransaction(): void
->will($this->throwException(new Exception()));
$conn->expects($this->once())
->method('rollback');
$mapper = new Mapper($conn, new EntityFactory(entityNamespace: 'Respect\\Relational\\'));
$mapper = new Mapper($conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: 'Respect\\Relational\\',
)));
$obj = new Post();
$mapper->post->persist($obj);
try {
Expand Down Expand Up @@ -226,7 +231,9 @@ public function testIgnoringLastInsertIdErrors(): void
->willReturn(true);
$conn->method('commit')
->willReturn(true);
$mapper = new Mapper($conn, new EntityFactory(entityNamespace: 'Respect\\Relational\\'));
$mapper = new Mapper($conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: 'Respect\\Relational\\',
)));
$obj = new Author();
$obj->name = 'bar';
$mapper->author->persist($obj);
Expand Down Expand Up @@ -513,29 +520,37 @@ public function testRemove(): void

public function testFetchingEntityTyped(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\\',
)));
$comment = $mapper->comment[8]->fetch();
$this->assertInstanceOf('\Respect\Relational\Comment', $comment);
}

public function testFetchingAllEntityTyped(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\\',
)));
$comment = $mapper->comment->fetchAll();
$this->assertInstanceOf('\Respect\Relational\Comment', $comment[1]);
}

public function testFetchingAllEntityTypedNested(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\\',
)));
$comment = $mapper->comment->post->fetchAll();
$this->assertInstanceOf('\Respect\Relational\Comment', $comment[0]);
$this->assertInstanceOf('\Respect\Relational\Post', $comment[0]->post);
}

public function testPersistingEntityTyped(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\\',
)));
$comment = $mapper->comment[8]->fetch();
$comment->text = 'HeyHey';
$mapper->comment->persist($comment);
Expand All @@ -547,7 +562,9 @@ public function testPersistingEntityTyped(): void

public function testPersistingNewEntityTyped(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\\',
)));
$comment = new Comment();
$comment->text = 'HeyHey';
$mapper->comment->persist($comment);
Expand All @@ -559,7 +576,9 @@ public function testPersistingNewEntityTyped(): void

public function testSettersAndGettersDatetimeAsObject(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\\',
)));
$post = new Post();
$post->id = 44;
$post->text = 'Test using datetime setters';
Expand Down Expand Up @@ -590,7 +609,7 @@ public function testStyle(): void
];
foreach ($styles as $style) {
$factory = new EntityFactory(style: $style, entityNamespace: 'Respect\\Relational\\');
$mapper = new Mapper($this->conn, $factory);
$mapper = new Mapper($this->conn, new PrestyledAssoc($factory));
$this->assertEquals($style, $mapper->style);
}
}
Expand Down Expand Up @@ -920,7 +939,9 @@ public function testCompositeColumnOverridesParentOnNameCollision(): void

public function testTyped(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\\',
)));
$mapper->typedIssues = Typed::issues('type');
$issues = $mapper->typedIssues->fetchAll();
$this->assertInstanceOf('\\Respect\Relational\\Bug', $issues[0]);
Expand All @@ -940,7 +961,9 @@ public function testTyped(): void

public function testTypedSingle(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\\',
)));
$mapper->typedIssues = Typed::issues('type');
$issue = $mapper->typedIssues->fetch();
$this->assertInstanceOf('\\Respect\Relational\\Bug', $issue);
Expand Down Expand Up @@ -970,21 +993,27 @@ public function testPersistNewWithArrayobject(): void

public function testFetchingEntityWithoutPublicPropertiesTyped(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\OtherEntity\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\OtherEntity\\',
)));
$post = $mapper->post[5]->fetch();
$this->assertInstanceOf('\Respect\Relational\OtherEntity\Post', $post);
}

public function testFetchingAllEntityWithoutPublicPropertiesTyped(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\OtherEntity\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\OtherEntity\\',
)));
$posts = $mapper->post->fetchAll();
$this->assertInstanceOf('\Respect\Relational\OtherEntity\Post', $posts[0]);
}

public function testFetchingAllEntityWithoutPublicPropertiesTypedNested(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\OtherEntity\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\OtherEntity\\',
)));
$posts = $mapper->post->author->fetchAll();
$this->assertInstanceOf('\Respect\Relational\OtherEntity\Post', $posts[0]);
$this->assertInstanceOf(
Expand All @@ -995,7 +1024,9 @@ public function testFetchingAllEntityWithoutPublicPropertiesTypedNested(): void

public function testPersistingEntityWithoutPublicPropertiesTyped(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\OtherEntity\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\OtherEntity\\',
)));

$post = $mapper->post[5]->fetch();
$post->setText('HeyHey');
Expand All @@ -1009,7 +1040,9 @@ public function testPersistingEntityWithoutPublicPropertiesTyped(): void

public function testPersistingNewEntityWithoutPublicPropertiesTyped(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: '\Respect\Relational\OtherEntity\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: '\Respect\Relational\OtherEntity\\',
)));

$author = new OtherEntity\Author();
$author->setId(1);
Expand All @@ -1028,7 +1061,9 @@ public function testPersistingNewEntityWithoutPublicPropertiesTyped(): void

public function testShouldSkipEntityConstructorByDefault(): void
{
$mapper = new Mapper($this->conn, new EntityFactory(entityNamespace: 'Respect\\Relational\\OtherEntity\\'));
$mapper = new Mapper($this->conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: 'Respect\\Relational\\OtherEntity\\',
)));

// create() uses newInstanceWithoutConstructor, so the constructor is never called
$comment = $mapper->comment->fetch();
Expand Down Expand Up @@ -1058,7 +1093,9 @@ public function testPersistNewEntityWithNoAutoIncrementId(): void
->willReturn(true);
$conn->method('commit')
->willReturn(true);
$mapper = new Mapper($conn, new EntityFactory(entityNamespace: 'Respect\\Relational\\'));
$mapper = new Mapper($conn, new PrestyledAssoc(new EntityFactory(
entityNamespace: 'Respect\\Relational\\',
)));
$obj = new Author();
$obj->name = 'test';
$mapper->author->persist($obj);
Expand Down
Loading