Skip to content

Commit

Permalink
allow join*() before from*(); joins-before-from are added to the firs…
Browse files Browse the repository at this point in the history
…t from. if no from is ever added, the joins will never be built into the statement. refs #69, #90.
  • Loading branch information
Paul M. Jones committed May 19, 2016
1 parent 9f025db commit b61ef8e
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 31 deletions.
31 changes: 16 additions & 15 deletions src/Common/Select.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class Select extends AbstractQuery implements SelectInterface, SubselectInterfac
*/
protected $from_key = -1;

protected $join = array();

/**
*
* GROUP BY these columns.
Expand Down Expand Up @@ -402,9 +404,7 @@ public function fromSubSelect($spec, $name)
$this->addTableRef('FROM (SELECT ...) AS', $name);
$spec = $this->subSelect($spec, ' ');
$name = $this->quoter->quoteName($name);
$this->from[] = array("({$spec} ) AS $name");
$this->from_key ++;
return $this;
return $this->addFrom("({$spec} ) AS $name");
}

/**
Expand Down Expand Up @@ -449,17 +449,12 @@ protected function subSelect($spec, $indent)
*/
public function join($join, $spec, $cond = null, array $bind = array())
{
if (! $this->from) {
throw new Exception('Cannot join() without from() first.');
}

$join = strtoupper(ltrim("$join JOIN"));
$this->addTableRef($join, $spec);

$spec = $this->quoter->quoteName($spec);
$cond = $this->fixJoinCondition($cond, $bind);
$this->from[$this->from_key][] = rtrim("$join $spec $cond");
return $this;
return $this->addJoin(rtrim("$join $spec $cond"));
}

/**
Expand Down Expand Up @@ -557,10 +552,6 @@ public function leftJoin($spec, $cond = null, array $bind = array())
*/
public function joinSubSelect($join, $spec, $name, $cond = null, array $bind = array())
{
if (! $this->from) {
throw new Exception('Cannot join() without from() first.');
}

$join = strtoupper(ltrim("$join JOIN"));
$this->addTableRef("$join (SELECT ...) AS", $name);

Expand All @@ -569,7 +560,13 @@ public function joinSubSelect($join, $spec, $name, $cond = null, array $bind = a
$cond = $this->fixJoinCondition($cond, $bind);

$text = rtrim("$join ($spec ) AS $name $cond");
$this->from[$this->from_key][] = ' ' . $text ;
return $this->addJoin(' ' . $text);
}

protected function addJoin($spec)
{
$from_key = ($this->from_key == -1) ? 0 : $this->from_key;
$this->join[$from_key][] = $spec;
return $this;
}

Expand Down Expand Up @@ -739,6 +736,7 @@ protected function reset()
$this->cols = array();
$this->from = array();
$this->from_key = -1;
$this->join = array();
$this->where = array();
$this->group_by = array();
$this->having = array();
Expand Down Expand Up @@ -812,7 +810,10 @@ protected function buildFrom()
}

$refs = array();
foreach ($this->from as $from) {
foreach ($this->from as $from_key => $from) {
if (isset($this->join[$from_key])) {
$from = array_merge($from, $this->join[$from_key]);
}
$refs[] = implode(PHP_EOL, $from);
}
return PHP_EOL . 'FROM' . $this->indentCsv($refs);
Expand Down
65 changes: 49 additions & 16 deletions tests/Common/SelectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,23 +230,42 @@ public function testJoin()
$this->query->from('t1');
$this->query->join('left', 't2', 't1.id = t2.id');
$this->query->join('inner', 't3 AS a3', 't2.id = a3.id');
$this->query->join('natural', 't4');
$this->query->from('t4');
$this->query->join('natural', 't5');
$expect = '
SELECT
*
FROM
<<t1>>
LEFT JOIN <<t2>> ON <<t1>>.<<id>> = <<t2>>.<<id>>
INNER JOIN <<t3>> AS <<a3>> ON <<t2>>.<<id>> = <<a3>>.<<id>>
NATURAL JOIN <<t4>>
INNER JOIN <<t3>> AS <<a3>> ON <<t2>>.<<id>> = <<a3>>.<<id>>,
<<t4>>
NATURAL JOIN <<t5>>
';
$actual = $this->query->__toString();
$this->assertSameSql($expect, $actual);
}

// try to join without from
$select = $this->newQuery();
$this->setExpectedException('Aura\SqlQuery\Exception');
$select->join('left', 't2', 't1.id = t2.id');
public function testJoinBeforeFrom()
{
$this->query->cols(array('*'));
$this->query->join('left', 't2', 't1.id = t2.id');
$this->query->join('inner', 't3 AS a3', 't2.id = a3.id');
$this->query->from('t1');
$this->query->from('t4');
$this->query->join('natural', 't5');
$expect = '
SELECT
*
FROM
<<t1>>
LEFT JOIN <<t2>> ON <<t1>>.<<id>> = <<t2>>.<<id>>
INNER JOIN <<t3>> AS <<a3>> ON <<t2>>.<<id>> = <<a3>>.<<id>>,
<<t4>>
NATURAL JOIN <<t5>>
';
$actual = $this->query->__toString();
$this->assertSameSql($expect, $actual);
}

public function testDuplicateJoinRef()
Expand Down Expand Up @@ -305,11 +324,6 @@ public function testLeftAndInnerJoin()
';
$actual = $this->query->__toString();
$this->assertSameSql($expect, $actual);

// try to join without from
$select = $this->newQuery();
$this->setExpectedException('Aura\SqlQuery\Exception');
$select->leftJoin('t2', 't1.id = t2.id');
}

public function testLeftAndInnerJoinWithBind()
Expand Down Expand Up @@ -356,11 +370,30 @@ public function testJoinSubSelect()
';
$actual = $this->query->__toString();
$this->assertSameSql($expect, $actual);
}

// try to join without from
$select = $this->newQuery();
$this->setExpectedException('Aura\SqlQuery\Exception');
$select->joinSubSelect('left', $sub1, 'a2', 't2.c1 = a3.c1');
public function testJoinSubSelectBeforeFrom()
{
$sub1 = 'SELECT * FROM t2';
$sub2 = 'SELECT * FROM t3';
$this->query->cols(array('*'));
$this->query->joinSubSelect('left', $sub1, 'a2', 't2.c1 = a3.c1');
$this->query->joinSubSelect('natural', $sub2, 'a3');
$this->query->from('t1');
$expect = '
SELECT
*
FROM
<<t1>>
LEFT JOIN (
SELECT * FROM t2
) AS <<a2>> ON <<t2>>.<<c1>> = <<a3>>.<<c1>>
NATURAL JOIN (
SELECT * FROM t3
) AS <<a3>>
';
$actual = $this->query->__toString();
$this->assertSameSql($expect, $actual);
}

public function testDuplicateJoinSubSelectRef()
Expand Down

0 comments on commit b61ef8e

Please sign in to comment.