Class Yiisoft\Db\QueryBuilder\Condition\Builder\InBuilder
| Inheritance | Yiisoft\Db\QueryBuilder\Condition\Builder\InBuilder |
|---|---|
| Implements | Yiisoft\Db\Expression\ExpressionBuilderInterface |
Build an object of {@see In} or {@see NotIn} into SQL expressions.
Protected Properties
| Property | Type | Description | Defined By |
|---|---|---|---|
| $queryBuilder | Yiisoft\Db\QueryBuilder\QueryBuilderInterface | Yiisoft\Db\QueryBuilder\Condition\Builder\InBuilder |
Public Methods
| Method | Description | Defined By |
|---|---|---|
| __construct() | Yiisoft\Db\QueryBuilder\Condition\Builder\InBuilder | |
| build() | Build SQL for {@see In} or {@see NotIn}. | Yiisoft\Db\QueryBuilder\Condition\Builder\InBuilder |
Protected Methods
| Method | Description | Defined By |
|---|---|---|
| buildCompositeInCondition() | Builds an SQL statement for checking the existence of rows with the specified composite column values. | Yiisoft\Db\QueryBuilder\Condition\Builder\InBuilder |
| buildSubqueryInCondition() | Build SQL for composite IN condition. |
Yiisoft\Db\QueryBuilder\Condition\Builder\InBuilder |
| buildValues() | Builds $values to use in condition. |
Yiisoft\Db\QueryBuilder\Condition\Builder\InBuilder |
| getNullCondition() | The Builds are null/is not null condition for column based on the operator. |
Yiisoft\Db\QueryBuilder\Condition\Builder\InBuilder |
| getRawValuesFromTraversableObject() | Yiisoft\Db\QueryBuilder\Condition\Builder\InBuilder |
Property Details
Method Details
| public mixed __construct ( Yiisoft\Db\QueryBuilder\QueryBuilderInterface $queryBuilder ) | ||
| $queryBuilder | Yiisoft\Db\QueryBuilder\QueryBuilderInterface | |
public function __construct(protected QueryBuilderInterface $queryBuilder) {}
Build SQL for {@see In} or {@see NotIn}.
| public string build ( Yiisoft\Db\QueryBuilder\Condition\In|Yiisoft\Db\QueryBuilder\Condition\NotIn $expression, array &$params = [] ) | ||
| $expression | Yiisoft\Db\QueryBuilder\Condition\In|Yiisoft\Db\QueryBuilder\Condition\NotIn | |
| $params | array | |
| throws | InvalidArgumentException | |
|---|---|---|
| throws | Yiisoft\Db\Exception\NotSupportedException | |
public function build(ExpressionInterface $expression, array &$params = []): string
{
$column = $expression->column instanceof Traversable
? iterator_to_array($expression->column)
: $expression->column;
$operator = match ($expression::class) {
In::class => 'IN',
NotIn::class => 'NOT IN',
};
$values = $expression->values;
if ($column === []) {
/** no columns to test against */
return $operator === 'IN' ? '0=1' : '';
}
if ($column instanceof ExpressionInterface) {
$column = $this->queryBuilder->buildExpression($column);
}
if ($values instanceof QueryInterface) {
return $this->buildSubqueryInCondition($operator, $column, $values, $params);
}
if (is_array($column)) {
if (count($column) > 1) {
return $this->buildCompositeInCondition($operator, $column, $values, $params);
}
$column = reset($column);
if ($column instanceof ExpressionInterface) {
$column = $this->queryBuilder->buildExpression($column);
}
}
$rawValues = is_array($values)
? $values
: $this->getRawValuesFromTraversableObject($values);
$nullCondition = null;
$nullConditionOperator = null;
if (in_array(null, $rawValues, true)) {
$nullCondition = $this->getNullCondition($operator, $column);
$nullConditionOperator = $operator === 'IN' ? 'OR' : 'AND';
}
$sqlValues = $this->buildValues($column, $values, $params);
if (empty($sqlValues)) {
return $nullCondition ?? ($operator === 'IN' ? '0=1' : '');
}
$column = $this->queryBuilder->getQuoter()->quoteColumnName($column);
if (count($sqlValues) > 1) {
$sql = "$column $operator (" . implode(', ', $sqlValues) . ')';
} else {
$operator = $operator === 'IN' ? '=' : '<>';
$sql = $column . $operator . reset($sqlValues);
}
return $nullCondition !== null && $nullConditionOperator !== null
? sprintf('%s %s %s', $sql, $nullConditionOperator, $nullCondition)
: $sql;
}
Builds an SQL statement for checking the existence of rows with the specified composite column values.
| protected string buildCompositeInCondition ( string|null $operator, array $columns, iterable|Iterator $values, array &$params = [] ) | ||
| $operator | string|null | |
| $columns | array | |
| $values | iterable|Iterator | |
| $params | array | |
| throws | InvalidArgumentException | |
|---|---|---|
| throws | Yiisoft\Db\Exception\NotSupportedException | |
protected function buildCompositeInCondition(
?string $operator,
array $columns,
iterable|Iterator $values,
array &$params = [],
): string {
$vss = [];
/** @var string[][] $values */
foreach ($values as $value) {
$vs = [];
foreach ($columns as $column) {
if ($column instanceof ExpressionInterface) {
$column = $this->queryBuilder->buildExpression($column);
}
$vs[] = isset($value[$column])
? $this->queryBuilder->buildValue($value[$column], $params)
: 'NULL';
}
$vss[] = '(' . implode(', ', $vs) . ')';
}
if (empty($vss)) {
return $operator === 'IN' ? '0=1' : '';
}
$sqlColumns = [];
foreach ($columns as $column) {
if ($column instanceof ExpressionInterface) {
$sqlColumns[] = $this->queryBuilder->buildExpression($column);
continue;
}
$sqlColumns[] = !str_contains($column, '(')
? $this->queryBuilder->getQuoter()->quoteColumnName($column) : $column;
}
return '(' . implode(', ', $sqlColumns) . ") $operator (" . implode(', ', $vss) . ')';
}
Build SQL for composite IN condition.
| protected string buildSubqueryInCondition ( string $operator, array|string $columns, Yiisoft\Db\Expression\ExpressionInterface $values, array &$params = [] ) | ||
| $operator | string | |
| $columns | array|string | |
| $values | Yiisoft\Db\Expression\ExpressionInterface | |
| $params | array | |
| throws | Yiisoft\Db\Exception\NotSupportedException | |
|---|---|---|
protected function buildSubqueryInCondition(
string $operator,
array|string $columns,
ExpressionInterface $values,
array &$params = [],
): string {
$query = '';
$sql = $this->queryBuilder->buildExpression($values, $params);
if (is_array($columns)) {
$preparedColumns = [];
foreach ($columns as $column) {
if ($column instanceof ExpressionInterface) {
$preparedColumns[] = $this->queryBuilder->buildExpression($column);
continue;
}
$preparedColumns[] = $this->queryBuilder->getQuoter()->quoteColumnName($column);
}
return '(' . implode(', ', $preparedColumns) . ") $operator $sql";
}
if (str_contains($columns, '(')) {
return $query;
}
$columns = $this->queryBuilder->getQuoter()->quoteColumnName($columns);
return "$columns $operator $sql";
}
Builds $values to use in condition.
| protected array buildValues ( string $column, iterable $values, array &$params = [] ) | ||
| $column | string | |
| $values | iterable | |
| $params | array | |
| throws | InvalidArgumentException | |
|---|---|---|
protected function buildValues(string $column, iterable $values, array &$params = []): array
{
$sqlValues = [];
foreach ($values as $value) {
if (is_array($value) || $value instanceof ArrayAccess) {
$value = $value[$column] ?? null;
}
if ($value === null) {
continue;
}
$sqlValues[] = $this->queryBuilder->buildValue($value, $params);
}
return $sqlValues;
}
The Builds are null/is not null condition for column based on the operator.
| protected string getNullCondition ( string $operator, string $column ) | ||
| $operator | string | |
| $column | string | |
protected function getNullCondition(string $operator, string $column): string
{
$column = $this->queryBuilder->getQuoter()->quoteColumnName($column);
if ($operator === 'IN') {
return sprintf('%s IS NULL', $column);
}
return sprintf('%s IS NOT NULL', $column);
}
| protected array getRawValuesFromTraversableObject ( Traversable $traversableObject ) | ||
| $traversableObject | Traversable | |
protected function getRawValuesFromTraversableObject(Traversable $traversableObject): array
{
$rawValues = [];
foreach ($traversableObject as $value) {
if (is_array($value)) {
$values = array_values($value);
$rawValues = array_merge($rawValues, $values);
} else {
$rawValues[] = $value;
}
}
return $rawValues;
}
Signup or Login in order to comment.