Skip to content

Commit

Permalink
Merge pull request #392 from nextras/alias_fix_v31
Browse files Browse the repository at this point in the history
collection/dbal: fix creating alias for repeated joinTable in M:M relationship
  • Loading branch information
hrach authored Mar 26, 2020
2 parents f1aae33 + 8f5c09a commit 84ca3f3
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 9 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ env:
matrix:
fast_finish: true

services:
- postgresql
- mysql

cache:
directories:
- $HOME/.composer/cache
Expand Down
23 changes: 16 additions & 7 deletions src/Mapper/Dbal/QueryBuilderHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,17 @@ class QueryBuilderHelper
private $mapper;


public static function getAlias(string $name): string
public static function getAlias(string $name, array $levels = []): string
{
static $counter = 1;
if (preg_match('#^([a-z0-9_]+\.){0,2}+([a-z0-9_]+?)$#i', $name, $m)) {
return $m[2];
$name = $m[2];
}

return '_join' . $counter++;
if (count($levels) === 0) {
return $name;
} else {
return implode('_', $levels) . '_' . $name;
}
}


Expand Down Expand Up @@ -174,17 +177,23 @@ private function normalizeAndAddJoins(array $levels, $sourceEntity, QueryBuilder
[$joinTable, [$outColumn, $inColumn]] = $targetMapper->getManyHasManyParameters($sourceProperty, $sourceMapper);
}

$builder->leftJoin($sourceAlias, "[$joinTable]", self::getAlias($joinTable), "[$sourceAlias.$sourceColumn] = [$joinTable.$inColumn]");
$joinAlias = self::getAlias($joinTable, array_slice($levels, 0, $levelIndex));
$builder->leftJoin(
$sourceAlias,
"[$joinTable]",
$joinAlias,
"[$sourceAlias.$sourceColumn] = [$joinAlias.$inColumn]"
);

$sourceAlias = $joinTable;
$sourceAlias = $joinAlias;
$sourceColumn = $outColumn;
} else {
$targetColumn = $targetReflection->getStoragePrimaryKey()[0];
$sourceColumn = $sourceReflection->convertEntityToStorageKey($level);
}

$targetTable = $targetMapper->getTableName();
$targetAlias = implode('_', array_slice($levels, 0, $levelIndex + 1));
$targetAlias = self::getAlias($levels[$levelIndex], array_slice($levels, 0, $levelIndex));

$builder->leftJoin($sourceAlias, "[$targetTable]", $targetAlias, "[$sourceAlias.$sourceColumn] = [$targetAlias.$targetColumn]");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,19 @@ class RelationshipManyHasManyTest extends DataTestCase
$books = $this->orm->books->findBy(['this->tags->name' => 'Tag 2']);
Assert::same(2, $books->countStored());
}


public function testJoinAcrossDifferentPaths()
{
$books = $this->orm->books->findBy(
[
ICollection::OR,
'this->tags->name' => 'Tag 1',
'this->nextPart->tags->name' => 'Tag 3',
]
)->orderBy('id');
Assert::same([1, 4], $books->fetchPairs(null, 'id'));
}
}


Expand Down
4 changes: 2 additions & 2 deletions tests/cases/unit/Mapper/Dbal/QueryBuilderHelperTest.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ class QueryBuilderHelperTest extends TestCase
$this->reflection->shouldReceive('getStoragePrimaryKey')->twice()->andReturn(['id']);

$this->queryBuilder->shouldReceive('leftJoin')->once()->with('authors', '[books]', 'translatedBooks', '[authors.id] = [translatedBooks.translator_id]');
$this->queryBuilder->shouldReceive('leftJoin')->once()->with('translatedBooks', '[books_x_tags]', 'books_x_tags', '[translatedBooks.id] = [books_x_tags.book_id]');
$this->queryBuilder->shouldReceive('leftJoin')->once()->with('books_x_tags', '[tags]', 'translatedBooks_tags', '[books_x_tags.tag_id] = [translatedBooks_tags.id]');
$this->queryBuilder->shouldReceive('leftJoin')->once()->with('translatedBooks', '[books_x_tags]', 'translatedBooks_books_x_tags', '[translatedBooks.id] = [translatedBooks_books_x_tags.book_id]');
$this->queryBuilder->shouldReceive('leftJoin')->once()->with('translatedBooks_books_x_tags', '[tags]', 'translatedBooks_tags', '[translatedBooks_books_x_tags.tag_id] = [translatedBooks_tags.id]');
$this->queryBuilder->shouldReceive('getFromAlias')->twice()->andReturn('authors');
$this->queryBuilder->shouldReceive('groupBy')->twice()->with('%column[]', ['authors.id']);

Expand Down

0 comments on commit 84ca3f3

Please sign in to comment.