Implement join for builder

This commit is contained in:
Dennis Eichhorn 2018-08-25 18:37:08 +02:00
parent 11c78afbbe
commit 17740d864f
3 changed files with 190 additions and 23 deletions

View File

@ -115,6 +115,14 @@ final class Builder extends BuilderAbstract
*/ */
public $joins = []; public $joins = [];
/**
* Ons of joins.
*
* @var array
* @since 1.0.0
*/
public $ons = [];
/** /**
* Where. * Where.
* *
@ -1067,64 +1075,147 @@ final class Builder extends BuilderAbstract
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function join($table1, $table2, $column1, $opperator, $column2) : Builder public function join($column, string $type = JoinType::JOIN) : Builder
{ {
if (\is_string($column) || $column instanceof \Closure) {
$this->joins[] = ['type' => $type, 'column' => $column];
} else {
throw new \InvalidArgumentException();
}
return $this; return $this;
} }
/** /**
* Join where. * Join.
* *
* @return void * @return Builder
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function joinWhere() public function leftJoin($column) : Builder
{ {
return $this->join($column, JoinType::LEFT_JOIN);
} }
/** /**
* Left join. * Join.
* *
* @return void * @return Builder
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function leftJoin() public function leftOuterJoin($column) : Builder
{ {
return $this->join($column, JoinType::LEFT_OUTER_JOIN);
} }
/** /**
* Left join where. * Join.
* *
* @return void * @return Builder
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function leftJoinWhere() public function leftInnerJoin($column) : Builder
{ {
return $this->join($column, JoinType::LEFT_INNER_JOIN);
} }
/** /**
* Right join. * Join.
* *
* @return void * @return Builder
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function rightJoin() public function rightJoin($column) : Builder
{ {
return $this->join($column, JoinType::RIGHT_JOIN);
} }
/** /**
* Right join where. * Join.
* *
* @return void * @return Builder
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function rightJoinWhere() public function rightOuterJoin($column) : Builder
{ {
return $this->join($column, JoinType::RIGHT_OUTER_JOIN);
}
/**
* Join.
*
* @return Builder
*
* @since 1.0.0
*/
public function rightInnerJoin($column) : Builder
{
return $this->join($column, JoinType::RIGHT_INNER_JOIN);
}
/**
* Join.
*
* @return Builder
*
* @since 1.0.0
*/
public function outerJoin($column) : Builder
{
return $this->join($column, JoinType::OUTER_JOIN);
}
/**
* Join.
*
* @return Builder
*
* @since 1.0.0
*/
public function innerJoin($column) : Builder
{
return $this->join($column, JoinType::INNER_JOIN);
}
/**
* Join.
*
* @return Builder
*
* @since 1.0.0
*/
public function crossJoin($column) : Builder
{
return $this->join($column, JoinType::CROSS_JOIN);
}
/**
* Join.
*
* @return Builder
*
* @since 1.0.0
*/
public function fullJoin($column) : Builder
{
return $this->join($column, JoinType::FULL_JOIN);
}
/**
* Join.
*
* @return Builder
*
* @since 1.0.0
*/
public function fullOuterJoin($column) : Builder
{
return $this->join($column, JoinType::FULL_OUTER_JOIN);
} }
/** /**
@ -1134,7 +1225,7 @@ final class Builder extends BuilderAbstract
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function rollback() public function rollback() : Builder
{ {
return $this; return $this;
} }
@ -1142,13 +1233,42 @@ final class Builder extends BuilderAbstract
/** /**
* On. * On.
* *
* @return void * @return Builder
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function on() public function on($columns, $operator = null, $values = null, $boolean = 'and') : Builder
{ {
if ($operator !== null && !\is_array($operator) && !\in_array(\strtolower($operator), self::OPERATORS)) {
throw new \InvalidArgumentException('Unknown operator.');
}
if (!\is_array($columns)) {
$columns = [$columns];
$operator = [$operator];
$values = [$values];
$boolean = [$boolean];
}
$joinCount = \count($this->joins);
$i = 0;
foreach ($columns as $key => $column) {
if (isset($operator[$i]) && !\in_array(\strtolower($operator[$i]), self::OPERATORS)) {
throw new \InvalidArgumentException('Unknown operator.');
}
$this->ons[$joinCount][] = [
'column' => $column,
'operator' => $operator[$i],
'value' => $values[$i],
'boolean' => $boolean[$i],
];
$i++;
}
return $this;
} }
/** /**
@ -1194,13 +1314,13 @@ final class Builder extends BuilderAbstract
* *
* @param mixed $value Value to bind * @param mixed $value Value to bind
* *
* @return mixed * @return int
* *
* @throws \Exception * @throws \Exception
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public static function getBindParamType($value) public static function getBindParamType($value) : int
{ {
if (\is_int($value)) { if (\is_int($value)) {
return \PDO::PARAM_INT; return \PDO::PARAM_INT;

View File

@ -393,9 +393,55 @@ class Grammar extends GrammarAbstract
return 'OFFSET ' . $offset; return 'OFFSET ' . $offset;
} }
private function compileJoins() /**
* Compile joins.
*
* @param Builder $query Builder
* @param array $joins Joins
*
* @return string
*
* @since 1.0.0
*/
private function compileJoins(Builder $query, array $joins) : string
{ {
return ''; $expression = '';
foreach ($joins as $key => $join) {
$expression .= $join['type'] . ' ';
$expression .= $this->compileSystem($join, $prefix);
$expression .= $this->compileOn($query, $query->ons[$key]);
}
$expression = \rtrim($expression, ', ');
return $expression;
}
/**
* Compile on.
*
* @param Builder $query Builder
* @param array $joins Joins
*
* @return string
*
* @since 1.0.0
*/
private function compileOn(Builder $query, array $ons, bool $first = true) : string
{
$expression = '';
foreach ($ons as $key => $on) {
$expression .= $this->compileWhereElement($on, $query, $first);
$first = false;
}
if ($expression === '') {
return '';
}
return 'ON ' . $expression;
} }
/** /**

View File

@ -36,5 +36,6 @@ abstract class JoinType extends Enum
public const OUTER_JOIN = 'OUTER JOIN'; public const OUTER_JOIN = 'OUTER JOIN';
public const INNER_JOIN = 'INNER JOIN'; public const INNER_JOIN = 'INNER JOIN';
public const CROSS_JOIN = 'CROSS JOIN'; public const CROSS_JOIN = 'CROSS JOIN';
public const FULL_JOIN = 'FULL JOIN';
public const FULL_OUTER_JOIN = 'FULL OUTER JOIN'; public const FULL_OUTER_JOIN = 'FULL OUTER JOIN';
} }