Abstract Class Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder
| Inheritance | Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder |
|---|---|
| Implements | Yiisoft\Db\QueryBuilder\DQLQueryBuilderInterface |
It's used to query data from a database.
Protected Properties
| Property | Type | Description | Defined By |
|---|---|---|---|
| $conditionClasses | array | Map of condition aliases to condition classes. | Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder |
| $expressionBuilders | array | Map of expression aliases to expression classes. | Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder |
| $queryBuilder | Yiisoft\Db\QueryBuilder\QueryBuilderInterface | Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder | |
| $separator | string | Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder |
Public Methods
Protected Methods
| Method | Description | Defined By |
|---|---|---|
| defaultConditionClasses() | Has an array of default condition classes. | Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder |
| defaultExpressionBuilders() | Has an array of default expression builders. | Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder |
| extractAlias() | Extracts table alias if there is one or returns false. | Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder |
Property Details
Map of condition aliases to condition classes. For example:
return [
'LIKE' => \Yiisoft\Db\QueryBuilder\Condition\Like::class,
];
This property is used by {@see \Yiisoft\Db\QueryBuilder\createConditionFromArray} method.
See default condition classes list in {@see \Yiisoft\Db\QueryBuilder\defaultConditionClasses()} method.
In case you want to add custom conditions support, use the {@see \Yiisoft\Db\QueryBuilder\setConditionClasses()} method.
See also:
- \Yiisoft\Db\QueryBuilder\setConditonClasses()
- defaultConditionClasses()
Map of expression aliases to expression classes.
For example:
[
Expression::class => ExpressionBuilder::class
]
This property is mainly used by {@see \Yiisoft\Db\QueryBuilder\buildExpression()} to build SQL expressions form expression objects. See default values in {@see \Yiisoft\Db\QueryBuilder\defaultExpressionBuilders()} method.
{@see \Yiisoft\Db\QueryBuilder\setExpressionBuilders()} {@see \Yiisoft\Db\QueryBuilder\defaultExpressionBuilders()}
Method Details
| public mixed __construct ( Yiisoft\Db\QueryBuilder\QueryBuilderInterface $queryBuilder, Yiisoft\Db\Schema\QuoterInterface $quoter ) | ||
| $queryBuilder | Yiisoft\Db\QueryBuilder\QueryBuilderInterface | |
| $quoter | Yiisoft\Db\Schema\QuoterInterface | |
public function __construct(
protected QueryBuilderInterface $queryBuilder,
private QuoterInterface $quoter,
) {
$this->expressionBuilders = $this->defaultExpressionBuilders();
$this->conditionClasses = $this->defaultConditionClasses();
}
| public array build ( Yiisoft\Db\Query\QueryInterface $query, array $params = [] ) | ||
| $query | Yiisoft\Db\Query\QueryInterface | |
| $params | array | |
public function build(QueryInterface $query, array $params = []): array
{
$query = $query->prepare($this->queryBuilder);
$params = empty($params) ? $query->getParams() : array_merge($params, $query->getParams());
$clauses = [
$this->buildSelect($query->getSelect(), $params, $query->getDistinct(), $query->getSelectOption()),
$this->buildFrom($query->getFrom(), $params),
$this->buildJoin($query->getJoins(), $params),
$this->buildWhere($query->getWhere(), $params),
$this->buildGroupBy($query->getGroupBy(), $params),
$this->buildHaving($query->getHaving(), $params),
];
$sql = implode($this->separator, array_filter($clauses));
$sql = $this->buildOrderByAndLimit($sql, $query->getOrderBy(), $query->getLimit(), $query->getOffset(), $params);
$for = $this->buildFor($query->getFor());
if ($for !== '') {
$sql .= $this->separator . $for;
}
$union = $this->buildUnion($query->getUnions(), $params);
if ($union !== '') {
$sql = "($sql)$this->separator$union";
}
$with = $this->buildWithQueries($query->getWithQueries(), $params);
if ($with !== '') {
$sql = "$with$this->separator$sql";
}
return [$sql, $params];
}
| public string buildColumns ( array|string $columns ) | ||
| $columns | array|string | |
public function buildColumns(array|string $columns): string
{
if (!is_array($columns)) {
if (str_contains($columns, '(')) {
return $columns;
}
/** @var list<string> We use valid regular expressions, so the result is always a list of strings */
$columns = preg_split('/\s*,\s*/', $columns, -1, PREG_SPLIT_NO_EMPTY);
}
$columns = array_map(
fn(string|ExpressionInterface $column): string => $column instanceof ExpressionInterface
? $this->buildExpression($column)
: $this->quoter->quoteColumnName($column),
$columns,
);
return implode(', ', $columns);
}
| public string buildCondition ( array|string|Yiisoft\Db\Expression\ExpressionInterface|null $condition, array &$params = [] ) | ||
| $condition | array|string|Yiisoft\Db\Expression\ExpressionInterface|null | |
| $params | array | |
public function buildCondition(array|string|ExpressionInterface|null $condition, array &$params = []): string
{
if (empty($condition)) {
if ($condition === '0') {
return '0';
}
return '';
}
if (is_array($condition)) {
$condition = $this->createConditionFromArray($condition);
} elseif (is_string($condition)) {
$condition = new Expression($condition, $params);
$params = [];
}
return $this->buildExpression($condition, $params);
}
| public string buildExpression ( Yiisoft\Db\Expression\ExpressionInterface $expression, array &$params = [] ) | ||
| $expression | Yiisoft\Db\Expression\ExpressionInterface | |
| $params | array | |
public function buildExpression(ExpressionInterface $expression, array &$params = []): string
{
return $this->queryBuilder
->getExpressionBuilder($expression)
->build($expression, $params);
}
| public string buildFor ( array $values ) | ||
| $values | array | |
public function buildFor(array $values): string
{
if (empty($values)) {
return '';
}
return 'FOR ' . implode($this->separator . 'FOR ', $values);
}
| public string buildFrom ( array $tables, array &$params ) | ||
| $tables | array | |
| $params | array | |
public function buildFrom(array $tables, array &$params): string
{
if (empty($tables)) {
return '';
}
/** @var string[] $tables */
$tables = $this->quoteTableNames($tables, $params);
return 'FROM ' . implode(', ', $tables);
}
| public string buildGroupBy ( array $columns, array &$params = [] ) | ||
| $columns | array | |
| $params | array | |
public function buildGroupBy(array $columns, array &$params = []): string
{
if (empty($columns)) {
return '';
}
/** @psalm-var array<string, ExpressionInterface|string> $columns */
foreach ($columns as $i => $column) {
if ($column instanceof ExpressionInterface) {
$columns[$i] = $this->buildExpression($column, $params);
} elseif (!str_contains($column, '(')) {
$columns[$i] = $this->quoter->quoteColumnName($column);
}
}
/** @psalm-var array<string, Expression|string> $columns */
return 'GROUP BY ' . implode(', ', $columns);
}
| public string buildHaving ( array|Yiisoft\Db\Expression\ExpressionInterface|string|null $condition, array &$params = [] ) | ||
| $condition | array|Yiisoft\Db\Expression\ExpressionInterface|string|null | |
| $params | array | |
public function buildHaving(array|ExpressionInterface|string|null $condition, array &$params = []): string
{
$having = $this->buildCondition($condition, $params);
return ($having === '') ? '' : ('HAVING ' . $having);
}
| public string buildJoin ( array $joins, array &$params ) | ||
| $joins | array | |
| $params | array | |
public function buildJoin(array $joins, array &$params): string
{
if (empty($joins)) {
return '';
}
foreach ($joins as $i => $join) {
/** @psalm-suppress DocblockTypeContradiction */
if (!is_array($join) || !isset($join[0], $join[1])) {
throw new InvalidArgumentException(
'A join clause must be specified as an array of join type, join table, and optionally join condition.',
);
}
[$joinType, $table] = $join;
$tables = $this->quoteTableNames(is_array($table) ? $table : [$table], $params);
$table = reset($tables);
$joins[$i] = "$joinType $table";
if (isset($join[2])) {
if (is_array($join[2]) && !isset($join[2][0])) {
foreach ($join[2] as &$column) {
if (is_string($column)) {
$column = new ColumnName($column);
}
}
unset($column);
}
$condition = $this->buildCondition($join[2], $params);
if ($condition !== '') {
$joins[$i] .= ' ON ' . $condition;
}
}
}
/** @psalm-var array<string> $joins */
return implode($this->separator, $joins);
}
public function buildLimit(ExpressionInterface|int|null $limit, ExpressionInterface|int|null $offset): string
{
$sql = '';
if ($limit !== null) {
$sql = 'LIMIT '
. ($limit instanceof ExpressionInterface ? $this->buildExpression($limit) : (string) $limit);
}
if (!empty($offset)) {
$sql .= ' OFFSET '
. ($offset instanceof ExpressionInterface ? $this->buildExpression($offset) : (string) $offset);
}
return ltrim($sql);
}
| public string buildOrderBy ( array $columns, array &$params = [] ) | ||
| $columns | array | |
| $params | array | |
public function buildOrderBy(array $columns, array &$params = []): string
{
if (empty($columns)) {
return '';
}
$orders = [];
/** @psalm-var array<string, ExpressionInterface|int|string> $columns */
foreach ($columns as $name => $direction) {
if ($direction instanceof ExpressionInterface) {
$orders[] = $this->buildExpression($direction, $params);
} else {
$orders[] = $this->quoter->quoteColumnName($name) . ($direction === SORT_DESC ? ' DESC' : '');
}
}
return 'ORDER BY ' . implode(', ', $orders);
}
| public string buildOrderByAndLimit ( string $sql, array $orderBy, Yiisoft\Db\Expression\ExpressionInterface|integer|null $limit, Yiisoft\Db\Expression\ExpressionInterface|integer|null $offset, array &$params = [] ) | ||
| $sql | string | |
| $orderBy | array | |
| $limit | Yiisoft\Db\Expression\ExpressionInterface|integer|null | |
| $offset | Yiisoft\Db\Expression\ExpressionInterface|integer|null | |
| $params | array | |
public function buildOrderByAndLimit(
string $sql,
array $orderBy,
ExpressionInterface|int|null $limit,
ExpressionInterface|int|null $offset,
array &$params = [],
): string {
$orderBy = $this->buildOrderBy($orderBy, $params);
if ($orderBy !== '') {
$sql .= $this->separator . $orderBy;
}
$limit = $this->buildLimit($limit, $offset);
if ($limit !== '') {
$sql .= $this->separator . $limit;
}
return $sql;
}
| public string buildSelect ( array $columns, array &$params, boolean $distinct = false, string|null $selectOption = null ) | ||
| $columns | array | |
| $params | array | |
| $distinct | boolean | |
| $selectOption | string|null | |
public function buildSelect(
array $columns,
array &$params,
bool $distinct = false,
?string $selectOption = null,
): string {
$select = $distinct ? 'SELECT DISTINCT' : 'SELECT';
if ($selectOption !== null) {
$select .= ' ' . $selectOption;
}
if (empty($columns)) {
return $select . ' *';
}
$quoter = $this->quoter;
foreach ($columns as $i => $column) {
$isIndexString = is_string($i);
if (!is_string($column)) {
$columns[$i] = $this->queryBuilder->buildValue($column, $params);
} elseif (!str_contains($column, '(')) {
if (!$isIndexString
&& preg_match('/^(.*?)(?i:\s+as\s+|\s+)([\w\-_.]+)$/', $column, $matches) === 1
) {
$columns[$i] = $quoter->quoteColumnName($matches[1])
. ' AS ' . $quoter->quoteSimpleColumnName($matches[2]);
continue;
}
$columns[$i] = $quoter->quoteColumnName($column);
}
if ($isIndexString && $i !== $column) {
/**
* @var string $i
* @psalm-var string $columns[$i]
*/
$columns[$i] .= ' AS ' . $quoter->quoteColumnName($i);
}
}
/** @psalm-var array<string, Expression|string> $columns */
return $select . ' ' . implode(', ', $columns);
}
| public string buildUnion ( array $unions, array &$params ) | ||
| $unions | array | |
| $params | array | |
public function buildUnion(array $unions, array &$params): string
{
if (empty($unions)) {
return '';
}
$result = '';
/** @psalm-var array<array{query:string|Query, all:bool}> $unions */
foreach ($unions as $union) {
if ($union['query'] instanceof QueryInterface) {
[$union['query'], $params] = $this->build($union['query'], $params);
}
$result .= 'UNION ' . ($union['all'] ? 'ALL ' : '') . '( ' . $union['query'] . ' ) ';
}
return trim($result);
}
| public string buildWhere ( array|string|Yiisoft\Db\QueryBuilder\Condition\ConditionInterface|Yiisoft\Db\Expression\ExpressionInterface|null $condition, array &$params = [] ) | ||
| $condition | array|string|Yiisoft\Db\QueryBuilder\Condition\ConditionInterface|Yiisoft\Db\Expression\ExpressionInterface|null | |
| $params | array | |
public function buildWhere(
array|string|ConditionInterface|ExpressionInterface|null $condition,
array &$params = [],
): string {
$where = $this->buildCondition($condition, $params);
return ($where === '') ? '' : ('WHERE ' . $where);
}
| public string buildWithQueries ( array $withQueries, array &$params ) | ||
| $withQueries | array | |
| $params | array | |
public function buildWithQueries(array $withQueries, array &$params): string
{
if (empty($withQueries)) {
return '';
}
$recursive = false;
$result = [];
foreach ($withQueries as $withQuery) {
if ($withQuery->recursive) {
$recursive = true;
}
if ($withQuery->query instanceof QueryInterface) {
[$querySql, $params] = $this->build($withQuery->query, $params);
} else {
$querySql = $withQuery->query;
}
$quotedAlias = $this->quoteCteAlias($withQuery->alias);
$result[] = $quotedAlias . ' AS (' . $querySql . ')';
}
return 'WITH ' . ($recursive ? 'RECURSIVE ' : '') . implode(', ', $result);
}
| public Yiisoft\Db\QueryBuilder\Condition\ConditionInterface createConditionFromArray ( array $condition ) | ||
| $condition | array | |
public function createConditionFromArray(array $condition): ConditionInterface
{
/** operator format: operator, operand 1, operand 2, ... */
if (isset($condition[0])) {
$operator = strtoupper((string) array_shift($condition));
$className = $this->conditionClasses[$operator] ?? Simple::class;
return $className::fromArrayDefinition($operator, $condition);
}
$conditions = [];
foreach ($condition as $column => $value) {
if (!is_string($column)) {
throw new InvalidArgumentException('Condition array must have string keys.');
}
if (is_iterable($value) || $value instanceof QueryInterface) {
$conditions[] = new Condition\In($column, $value);
continue;
}
$conditions[] = new Condition\Equals($column, $value);
}
return count($conditions) === 1 ? $conditions[0] : new Condition\AndX(...$conditions);
}
Has an array of default condition classes.
Extend this method if you want to change default condition classes for the query builder.
See {@see \Yiisoft\Db\QueryBuilder\conditionClasses} docs for details.
| protected array defaultConditionClasses ( ) |
protected function defaultConditionClasses(): array
{
return [
'NOT' => Condition\Not::class,
'AND' => Condition\AndX::class,
'OR' => Condition\OrX::class,
'=' => Condition\Equals::class,
'!=' => Condition\NotEquals::class,
'<>' => Condition\NotEquals::class,
'>' => Condition\GreaterThan::class,
'>=' => Condition\GreaterThanOrEqual::class,
'<' => Condition\LessThan::class,
'<=' => Condition\LessThanOrEqual::class,
'BETWEEN' => Condition\Between::class,
'NOT BETWEEN' => Condition\NotBetween::class,
'IN' => Condition\In::class,
'NOT IN' => Condition\NotIn::class,
'LIKE' => Condition\Like::class,
'NOT LIKE' => Condition\NotLike::class,
'EXISTS' => Condition\Exists::class,
'NOT EXISTS' => Condition\NotExists::class,
'ARRAY OVERLAPS' => Condition\ArrayOverlaps::class,
'JSON OVERLAPS' => Condition\JsonOverlaps::class,
];
}
Has an array of default expression builders.
Extend this method and override it if you want to change default expression builders for this query builder.
See {@see \Yiisoft\Db\QueryBuilder\expressionBuilders} docs for details.
| protected array defaultExpressionBuilders ( ) |
protected function defaultExpressionBuilders(): array
{
return [
Query::class => QueryExpressionBuilder::class,
Param::class => ParamBuilder::class,
Expression::class => ExpressionBuilder::class,
CompositeExpression::class => CompositeExpressionBuilder::class,
Condition\Not::class => Condition\Builder\NotBuilder::class,
Condition\AndX::class => Condition\Builder\LogicalBuilder::class,
Condition\OrX::class => Condition\Builder\LogicalBuilder::class,
Condition\Between::class => Condition\Builder\BetweenBuilder::class,
Condition\NotBetween::class => Condition\Builder\BetweenBuilder::class,
Condition\In::class => Condition\Builder\InBuilder::class,
Condition\NotIn::class => Condition\Builder\InBuilder::class,
Condition\Like::class => Condition\Builder\LikeBuilder::class,
Condition\NotLike::class => Condition\Builder\LikeBuilder::class,
Condition\Equals::class => Condition\Builder\CompareBuilder::class,
Condition\NotEquals::class => Condition\Builder\CompareBuilder::class,
Condition\GreaterThan::class => Condition\Builder\CompareBuilder::class,
Condition\GreaterThanOrEqual::class => Condition\Builder\CompareBuilder::class,
Condition\LessThan::class => Condition\Builder\CompareBuilder::class,
Condition\LessThanOrEqual::class => Condition\Builder\CompareBuilder::class,
Condition\Exists::class => Condition\Builder\ExistsBuilder::class,
Condition\NotExists::class => Condition\Builder\ExistsBuilder::class,
Condition\All::class => Condition\Builder\AllBuilder::class,
Condition\None::class => Condition\Builder\NoneBuilder::class,
Simple::class => Condition\Builder\SimpleBuilder::class,
JsonValue::class => JsonValueBuilder::class,
ArrayValue::class => ArrayValueBuilder::class,
StructuredValue::class => StructuredValueBuilder::class,
CaseX::class => CaseXBuilder::class,
ColumnName::class => ColumnNameBuilder::class,
Value::class => ValueBuilder::class,
DateTimeValue::class => DateTimeValueBuilder::class,
Length::class => LengthBuilder::class,
Greatest::class => GreatestBuilder::class,
Least::class => LeastBuilder::class,
Longest::class => LongestBuilder::class,
Shortest::class => ShortestBuilder::class,
];
}
Extracts table alias if there is one or returns false.
| protected array|boolean extractAlias ( string $table ) | ||
| $table | string | |
protected function extractAlias(string $table): array|bool
{
if (preg_match('/^(.*?)(?i:\s+as|)\s+([^ ]+)$/', $table, $matches)) {
return $matches;
}
return false;
}
| public Yiisoft\Db\Expression\ExpressionBuilderInterface getExpressionBuilder ( Yiisoft\Db\Expression\ExpressionInterface $expression ) | ||
| $expression | Yiisoft\Db\Expression\ExpressionInterface | |
public function getExpressionBuilder(ExpressionInterface $expression): ExpressionBuilderInterface
{
$className = $expression::class;
if (!isset($this->expressionBuilders[$className])) {
throw new NotSupportedException(
'Expression of class ' . $className . ' can not be built in ' . static::class,
);
}
return new $this->expressionBuilders[$className]($this->queryBuilder);
}
| public string selectExists ( string $rawSql ) | ||
| $rawSql | string | |
public function selectExists(string $rawSql): string
{
return 'SELECT EXISTS(' . $rawSql . ') AS ' . $this->quoter->quoteSimpleColumnName('0');
}
| public void setConditionClasses ( array $classes ) | ||
| $classes | array | |
public function setConditionClasses(array $classes): void
{
$this->conditionClasses = array_merge($this->conditionClasses, $classes);
}
| public void setExpressionBuilders ( array $builders ) | ||
| $builders | array | |
public function setExpressionBuilders(array $builders): void
{
$this->expressionBuilders = array_merge($this->expressionBuilders, $builders);
}
| public void setSeparator ( string $separator ) | ||
| $separator | string |
The separator between different fragments of an SQL statement. Defaults to an empty space. This is mainly used by {@see \Yiisoft\Db\QueryBuilder\build()} when generating a SQL statement. |
public function setSeparator(string $separator): void
{
$this->separator = $separator;
}
Signup or Login in order to comment.