Skip to content

Commit

Permalink
- fix MtM skip loading eager loaded relations in promise
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfy-j committed May 11, 2020
1 parent e19e50b commit 961f6cd
Show file tree
Hide file tree
Showing 6 changed files with 458 additions and 12 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# CHANGELOG

v1.2.8 (11.05.2020)
--------------------
- fixed compatibility issues with PHPUnit8 (no more warnings)
- [bugfix] MtM relation did not load eager relations when selected via promise #94
- added more MtM tests

v1.2.7 (26.04.2020)
--------------------
- a number of performance optimizations by @pine3ree
Expand Down
27 changes: 20 additions & 7 deletions src/Relation/Pivoted/PivotedPromise.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ public function __scope(): array
*/
public function __resolve()
{
/*
* This method emulates the selection of MtM nodes by skipping parent relation (as it usually done
* in query) and injecting parent ID instead.
*/

if ($this->orm === null) {
return $this->resolved;
}
Expand All @@ -95,14 +100,16 @@ public function __resolve()
throw new ORMException('PivotedPromise require ORM to implement SourceFactoryInterface');
}

$table = $this->orm->getSource($this->target)->getTable();

// getting scoped query
$root = new Select\RootLoader($this->orm, $this->target);
$query = $root->buildQuery();
$query = (new Select\RootLoader($this->orm, $this->target))->buildQuery();

// responsible for all the scoping
$loader = new ManyToManyLoader($this->orm, $table, $this->target, $this->relationSchema);
$loader = new ManyToManyLoader(
$this->orm,
$this->orm->getSource($this->target)->getTable(),
$this->target,
$this->relationSchema
);

/** @var ManyToManyLoader $loader */
$loader = $loader->withContext($loader, [
Expand All @@ -113,8 +120,11 @@ public function __resolve()

$query = $loader->configureQuery($query, [$this->innerKey]);

// we are going to add pivot node into virtual root node to aggregate the results
$root = new RootNode([$this->relationSchema[Relation::INNER_KEY]], $this->relationSchema[Relation::INNER_KEY]);
// we are going to add pivot node into virtual root node (only ID) to aggregate the results
$root = new RootNode(
[$this->relationSchema[Relation::INNER_KEY]],
$this->relationSchema[Relation::INNER_KEY]
);

$node = $loader->createNode();
$root->linkNode('output', $node);
Expand All @@ -128,6 +138,9 @@ public function __resolve()
}
$iterator->close();

// load all eager relations, forbid loader to re-fetch data (make it think it was joined)
$loader->withContext($loader, ['method' => JoinableLoader::INLOAD])->loadData($node);

$elements = [];
$pivotData = new \SplObjectStorage();
foreach (new Iterator($this->orm, $this->target, $root->getResult()[0]['output']) as $pivot => $entity) {
Expand Down
15 changes: 11 additions & 4 deletions src/Select/AbstractLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,7 @@ public function createNode(): AbstractNode
*/
public function loadData(AbstractNode $node): void
{
// loading data through child loaders
foreach ($this->load as $relation => $loader) {
$loader->loadData($node->getNode($relation));
}
$this->loadChild($node);
}

/**
Expand All @@ -259,6 +256,16 @@ public function loadData(AbstractNode $node): void
*/
abstract public function isLoaded(): bool;

/**
* @param AbstractNode $node
*/
protected function loadChild(AbstractNode $node): void
{
foreach ($this->load as $relation => $loader) {
$loader->loadData($node->getNode($relation));
}
}

/**
* Create input node for the loader.
*
Expand Down
1 change: 0 additions & 1 deletion src/Select/JoinableLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ public function loadData(AbstractNode $node): void
try {
$node->parseRow(0, $row);
} catch (\Throwable $e) {
echo 'x';
throw $e;
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/Select/Loader/ManyToManyLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Cycle\ORM\Select\Traits\WhereTrait;
use Spiral\Database\Injection\Parameter;
use Spiral\Database\Query\SelectQuery;
use Spiral\Database\StatementInterface;

class ManyToManyLoader extends JoinableLoader
{
Expand Down Expand Up @@ -179,6 +180,17 @@ public function createNode(): AbstractNode
return $node;
}

/**
* @param AbstractNode $node
*/
protected function loadChild(AbstractNode $node): void
{
$node = $node->getNode('@');
foreach ($this->load as $relation => $loader) {
$loader->loadData($node->getNode($relation));
}
}

/**
* {@inheritdoc}
*/
Expand Down
Loading

0 comments on commit 961f6cd

Please sign in to comment.