From 2c2b3abe514111a92c0286c279b326fec9907dc2 Mon Sep 17 00:00:00 2001 From: Nathan Dentzau Date: Tue, 14 Aug 2018 22:48:46 -0400 Subject: [PATCH] Allow custom self column in join The current `JoinQuery::addJoin()` method does not allow for a custom `Column`. Below is an example of the use case for this change: ```php $query = new Select(); $query ->setTable('company') ->setColumns([ 'company_id' => 'id', 'name' => 'name', ]) ->join( 'field_company_code', 'id', 'entity_id', ) ->join( 'company_codes', new Column('target_id', 'field_company_code'), new Column('id', 'company_codes'), ['code' => 'code'] ); ``` This query structure is common in Drupal when selecting values from fields on entities that reference other entities through the Field and Entity API. --- src/Manipulation/JoinQuery.php | 41 +++++++++++++---------- tests/Builder/Syntax/SelectWriterTest.php | 32 ++++++++++++++++-- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/src/Manipulation/JoinQuery.php b/src/Manipulation/JoinQuery.php index e478027..8ddbbd2 100644 --- a/src/Manipulation/JoinQuery.php +++ b/src/Manipulation/JoinQuery.php @@ -10,8 +10,9 @@ namespace NilPortugues\Sql\QueryBuilder\Manipulation; -use NilPortugues\Sql\QueryBuilder\Syntax\SyntaxFactory; use NilPortugues\Sql\QueryBuilder\Syntax\Where; +use NilPortugues\Sql\QueryBuilder\Syntax\Column; +use NilPortugues\Sql\QueryBuilder\Syntax\SyntaxFactory; /** * Class JoinQuery. @@ -70,8 +71,8 @@ public function setTable($table) /** * @param string $table - * @param string $selfColumn - * @param string $refColumn + * @param mixed $selfColumn + * @param mixed $refColumn * @param string[] $columns * * @return Select @@ -83,8 +84,8 @@ public function leftJoin($table, $selfColumn = null, $refColumn = null, $columns /** * @param string $table - * @param string $selfColumn - * @param string $refColumn + * @param mixed $selfColumn + * @param mixed $refColumn * @param string[] $columns * @param string $joinType * @@ -110,8 +111,8 @@ public function join( /** * @param Select $select - * @param string $selfColumn - * @param string $refColumn + * @param mixed $selfColumn + * @param mixed $refColumn * * @return Select */ @@ -121,11 +122,15 @@ public function addJoin(Select $select, $selfColumn, $refColumn) $table = $select->getTable()->getName(); if (!isset($this->joins[$table])) { - $newColumn = array($selfColumn); - $select->joinCondition()->equals( - $refColumn, - SyntaxFactory::createColumn($newColumn, $this->select->getTable()) - ); + if (!$selfColumn instanceof Column) { + $newColumn = array($selfColumn); + $selfColumn = SyntaxFactory::createColumn( + $newColumn, + $this->select->getTable() + ); + } + + $select->joinCondition()->equals($refColumn, $selfColumn); $this->joins[$table] = $select; } @@ -148,8 +153,8 @@ public function setJoin($isJoin = true) /** * @param string $table - * @param string $selfColumn - * @param string $refColumn + * @param mixed $selfColumn + * @param mixed $refColumn * @param string[] $columns * * @internal param null $selectClass @@ -163,8 +168,8 @@ public function rightJoin($table, $selfColumn = null, $refColumn = null, $column /** * @param string $table - * @param string $selfColumn - * @param string $refColumn + * @param mixed $selfColumn + * @param mixed $refColumn * @param string[] $columns * * @return Select @@ -176,8 +181,8 @@ public function crossJoin($table, $selfColumn = null, $refColumn = null, $column /** * @param string $table - * @param string $selfColumn - * @param string $refColumn + * @param mixed $selfColumn + * @param mixed $refColumn * @param string[] $columns * * @return Select diff --git a/tests/Builder/Syntax/SelectWriterTest.php b/tests/Builder/Syntax/SelectWriterTest.php index 45b8562..834e065 100644 --- a/tests/Builder/Syntax/SelectWriterTest.php +++ b/tests/Builder/Syntax/SelectWriterTest.php @@ -10,9 +10,10 @@ namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax; -use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder; -use NilPortugues\Sql\QueryBuilder\Manipulation\Select; +use NilPortugues\Sql\QueryBuilder\Syntax\Column; use NilPortugues\Sql\QueryBuilder\Syntax\OrderBy; +use NilPortugues\Sql\QueryBuilder\Manipulation\Select; +use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder; /** * Class SelectWriterTest. @@ -356,6 +357,33 @@ public function itShouldBeAbleToDoAJoinWithOrderByOnJoinedTable() $this->assertSame($expected, $this->writer->write($this->query)); } + /** + * @test + */ + public function itShouldBeAbleToDoAJoinWithCustomColumns() + { + $this->query + ->setTable('user') + ->setColumns( + array( + 'userId' => 'user_id', + 'username' => 'name', + 'email' => 'email', + 'created_at', + ) + ) + ->orderBy('user_id', OrderBy::DESC) + ->join('news', 'user_id', 'author_id', array('title', 'body', 'created_at', 'updated_at')) + ->orderBy('created_at', OrderBy::DESC) + ->join('articles', new Column('news_id', 'article'), new Column('id', 'news')); + + $expected = 'SELECT user.user_id AS "userId", user.name AS "username", user.email AS "email", user.created_at,'. + ' news.title, news.body, news.created_at, news.updated_at FROM user JOIN news ON (news.author_id ='. + ' user.user_id) JOIN articles ON (news.id = article.news_id) ORDER BY user.user_id DESC, news.created_at DESC'; + + $this->assertSame($expected, $this->writer->write($this->query)); + } + /** * @test */