Skip to content

Commit

Permalink
ClosureHydrator now will try to load relation from Heap; also it wi…
Browse files Browse the repository at this point in the history
…ll write Reference into `mixed` property instead of relation loading (#429)
  • Loading branch information
msmakouz authored Aug 4, 2023
1 parent a3c072f commit c201f0a
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 14 deletions.
11 changes: 5 additions & 6 deletions src/Mapper/Proxy/Hydrator/ClosureHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,21 +109,20 @@ private function setRelationProperties(array $properties, RelationMap $relMap, o
? $prop->getType()->getTypes()
: [$prop->getType()];

$relation = $relMap->getRelations()[$property];
foreach ($types as $type) {
$c = $type->getName();
if ($c === 'object' || $value instanceof $c) {
if ($c === 'object' || $c === 'mixed' || $value instanceof $c) {
$value = $relation->collect($relation->resolve($value, false)) ?? $value;

$object->{$property} = $value;
unset($data[$property]);

// go to next property
continue 2;
}
}

$relation = $relMap->getRelations()[$property] ?? null;
if ($relation !== null) {
$value = $relation->collect($relation->resolve($value, true));
}
$value = $relation->collect($relation->resolve($value, true));
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Mapper/Proxy/ProxyEntityFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function create(
): object {
$class = \array_key_exists($sourceClass, $this->classMap)
? $this->classMap[$sourceClass]
: $this->defineClass($relMap, $sourceClass);
: $this->defineClass($sourceClass);

$proxy = $this->instantiator->instantiate($class);
$proxy->__cycle_orm_rel_map = $relMap;
Expand Down Expand Up @@ -137,7 +137,7 @@ private function entityToArray(object $entity): array
return $result;
}

private function defineClass(RelationMap $relMap, string $class): string
private function defineClass(string $class): string
{
if (!class_exists($class, true)) {
throw new \RuntimeException(sprintf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function setUp(): void
{
parent::setUp();

$this->makeTable('user', ['id' => 'primary', 'email' => 'string']);
$this->makeTable('user', ['id' => 'primary', 'email' => 'string', 'friend_id' => 'integer,nullable']);
$this->makeTable('profile', ['id' => 'primary', 'name' => 'string', 'user_id' => 'integer']);
$this->makeTable('tag', ['id' => 'primary', 'name' => 'string',]);
$this->makeTable('tag_user', ['user_id' => 'integer', 'tag_id' => 'integer',]);
Expand Down Expand Up @@ -210,10 +210,38 @@ public function setUp(): void
],
],
],
EntityWithMixedTypeRelation::class => [
Schema::ROLE => 'mixed_type',
Schema::MAPPER => Mapper::class,
Schema::DATABASE => 'default',
Schema::TABLE => 'user',
Schema::PRIMARY_KEY => 'id',
Schema::COLUMNS => [
'id' => 'id',
'email' => 'email',
'friend_id' => 'friend_id',
],
Schema::TYPECAST => ['id' => 'int', 'friend_id' => 'int'],
Schema::SCHEMA => [],
Schema::RELATIONS => [
'friend' => [
Relation::TYPE => Relation::BELONGS_TO,
Relation::TARGET => EntityWithMixedTypeRelation::class,
Relation::LOAD => Relation::LOAD_PROMISE,

Relation::SCHEMA => [
Relation::NULLABLE => false,
Relation::CASCADE => true,
Relation::OUTER_KEY => 'id',
Relation::INNER_KEY => 'friend_id',
],
],
],
],
]));
}

public function testPrivateBelongsToRelationPropertyWithoutProxyShouldBeFilled()
public function testPrivateBelongsToRelationPropertyWithoutProxyShouldBeFilled(): void
{
$profile = new EntityWithRelationHydrationProfile('test');
$profile->user_id = 1;
Expand All @@ -224,7 +252,30 @@ public function testPrivateBelongsToRelationPropertyWithoutProxyShouldBeFilled()
// $this->assertInstanceOf(ReferenceInterface::class, $profile->getRefersUser());
}

public function testPrivateHasManyRelationPropertyWithoutProxyShouldBeFilled()
public function testRelationWithMixedTypeShouldBeFilledAsReference(): void
{
$user = new EntityWithMixedTypeRelation();
$user->email = '[email protected]';
$user->friend_id = 1;

$this->save($user);

$this->assertInstanceOf(ReferenceInterface::class, $user->friend);
}

public function testRelationExistedInHeapMustFilledAsEntity(): void
{
$user = new EntityWithMixedTypeRelation();
$user->email = '[email protected]';
$user->friend_id = 1;

$this->orm->getRepository(EntityWithMixedTypeRelation::class)->findByPK(1);

$this->save($user);
$this->assertInstanceOf(EntityWithMixedTypeRelation::class, $user->friend);
}

public function testPrivateHasManyRelationPropertyWithoutProxyShouldBeFilled(): void
{
$profile = new EntityWithRelationHydrationProfile('test');
$user = new EntityWithRelationHydrationUser('[email protected]');
Expand All @@ -235,7 +286,7 @@ public function testPrivateHasManyRelationPropertyWithoutProxyShouldBeFilled()
$this->assertSame($user, $profile->getUser());
}

public function testPrivateManyToManyRelationPropertyWithoutProxyShouldBeFilled()
public function testPrivateManyToManyRelationPropertyWithoutProxyShouldBeFilled(): void
{
$tagContext = new EntityWithRelationHydrationTagContext();
$tagContext->user_id = 1;
Expand All @@ -250,7 +301,7 @@ public function testPrivateManyToManyRelationPropertyWithoutProxyShouldBeFilled(
/**
* TODO: error with shadow belongs to
*/
public function testPrivatMorphBelongsToRelationPropertyWithoutProxyShouldBeFilled()
public function testPrivateMorphBelongsToRelationPropertyWithoutProxyShouldBeFilled(): void
{
$profile = new EntityWithRelationHydrationProfile('test');
$profile->user_id = 1;
Expand Down Expand Up @@ -307,7 +358,7 @@ public function testChangeLazyOverloadedArray(): void
$this->assertContains('test-value', $user->profiles);
}

public function testGetLinkValueFromLazyOverloadedRelation()
public function testGetLinkValueFromLazyOverloadedRelation(): void
{
$user = (new Select($this->orm, EntityWithRelationHydrationUser::class))
->fetchOne();
Expand Down Expand Up @@ -433,3 +484,11 @@ public function setParent($parent): void
$this->parent = $parent;
}
}

class EntityWithMixedTypeRelation
{
public int $id;
public string $email;
public ?int $friend_id = null;
public mixed $friend;
}

0 comments on commit c201f0a

Please sign in to comment.