Skip to content

Commit

Permalink
Add Nested Joins to Query Builder
Browse files Browse the repository at this point in the history
Add $nestedJoins vairable to compileJoins function
Add tests testJoinsWithNestedJoins, testJoinsWithMultipleNestedJoins, testJoinsWithNestedJoinWithAdvancedSubqueryCondition to DatabaseQueryBuilderTest
  • Loading branch information
dariusj18 committed Feb 7, 2018
1 parent 56a58e0 commit 83c2ec7
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/Illuminate/Database/Query/Grammars/Grammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,11 @@ protected function compileFrom(Builder $query, $table)
*/
protected function compileJoins(Builder $query, $joins)
{
return collect($joins)->map(function ($join) {
return collect($joins)->map(function ($join) use ($query) {
$table = $this->wrapTable($join->table);
$nestedJoins = is_null($join->joins) ? '' : ' '.$this->compileJoins($query, $join->joins);

return trim("{$join->type} join {$table} {$this->compileWheres($join)}");
return trim("{$join->type} join {$table}{$nestedJoins} {$this->compileWheres($join)}");
})->implode(' ');
}

Expand Down
48 changes: 48 additions & 0 deletions tests/Database/DatabaseQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,54 @@ public function testJoinsWithAdvancedSubqueryCondition()
$this->assertEquals(['1', true], $builder->getBindings());
}

public function testJoinsWithNestedJoins()
{
$builder = $this->getBuilder();
$builder->select('users.id', 'contacts.id', 'contact_types.id')->from('users')->leftJoin('contacts', function ($j) {
$j->on('users.id', 'contacts.id')->join('contact_types', 'contacts.contact_type_id', '=', 'contact_types.id');
});
$this->assertEquals('select "users"."id", "contacts"."id", "contact_types"."id" from "users" left join "contacts" inner join "contact_types" on "contacts"."contact_type_id" = "contact_types"."id" on "users"."id" = "contacts"."id"', $builder->toSql());
}

public function testJoinsWithMultipleNestedJoins()
{
$builder = $this->getBuilder();
$builder->select('users.id', 'contacts.id', 'contact_types.id', 'countrys.id', 'planets.id')->from('users')->leftJoin('contacts', function ($j) {
$j->on('users.id', 'contacts.id')
->join('contact_types', 'contacts.contact_type_id', '=', 'contact_types.id')
->leftJoin('countrys', function ($q) {
$q->on('contacts.country', '=', 'countrys.country')
->join('planets', function ($q) {
$q->on('countrys.planet_id', '=', 'planet.id')
->where('planet.is_settled', '=', 1)
->where('planet.population', '>=', 10000);
});
});
});
$this->assertEquals('select "users"."id", "contacts"."id", "contact_types"."id", "countrys"."id", "planets"."id" from "users" left join "contacts" inner join "contact_types" on "contacts"."contact_type_id" = "contact_types"."id" left join "countrys" inner join "planets" on "countrys"."planet_id" = "planet"."id" and "planet"."is_settled" = ? and "planet"."population" >= ? on "contacts"."country" = "countrys"."country" on "users"."id" = "contacts"."id"', $builder->toSql());
$this->assertEquals(['1', 10000], $builder->getBindings());
}

public function testJoinsWithNestedJoinWithAdvancedSubqueryCondition()
{
$builder = $this->getBuilder();
$builder->select('users.id', 'contacts.id', 'contact_types.id')->from('users')->leftJoin('contacts', function ($j) {
$j->on('users.id', 'contacts.id')
->join('contact_types', 'contacts.contact_type_id', '=', 'contact_types.id')
->whereExists(function ($q) {
$q->select('*')->from('countrys')
->whereColumn('contacts.country', '=', 'countrys.country')
->join('planets', function ($q) {
$q->on('countrys.planet_id', '=', 'planet.id')
->where('planet.is_settled', '=', 1);
})
->where('planet.population', '>=', 10000);
});
});
$this->assertEquals('select "users"."id", "contacts"."id", "contact_types"."id" from "users" left join "contacts" inner join "contact_types" on "contacts"."contact_type_id" = "contact_types"."id" on "users"."id" = "contacts"."id" and exists (select * from "countrys" inner join "planets" on "countrys"."planet_id" = "planet"."id" and "planet"."is_settled" = ? where "contacts"."country" = "countrys"."country" and "planet"."population" >= ?)', $builder->toSql());
$this->assertEquals(['1', 10000], $builder->getBindings());
}

public function testRawExpressionsInSelect()
{
$builder = $this->getBuilder();
Expand Down

0 comments on commit 83c2ec7

Please sign in to comment.