0 follower

Abstract Class Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder

InheritanceYiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder
ImplementsYiisoft\Db\QueryBuilder\DMLQueryBuilderInterface

It's used to manipulate data in tables.

This manipulation involves inserting data into database tables, retrieving existing data, deleting data from existing tables and modifying existing data.

Protected Methods

Hide inherited methods

Method Description Defined By
buildSimpleSelect() Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder
extractColumnNames() Extract column names from columns and rows. Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder
getNormalizedColumnNames() Get normalized column names Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder
getQueryColumnNames() Prepare select-subQuery and field names for INSERT INTO ... SELECT SQL statement. Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder
normalizeColumnNames() Normalizes the column names. Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder
prepareBatchInsertValues() Prepare values for batch insert. Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder
prepareInsertValues() Prepare column names and placeholders for INSERT SQL statement. Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder
prepareTraversable() Prepare traversable for batch insert. Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder
prepareUpdateSets() Prepare column names and placeholders for UPDATE SQL statement. Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder
prepareUpsertColumns() Prepare column names and constraints for "upsert" operation. Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder
prepareUpsertSets() Prepare column names and placeholders for upsert SQL statement. Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder

Property Details

Hide inherited properties

$queryBuilder protected property
$quoter protected property
$schema protected property
$typecasting protected property
protected boolean $typecasting true

Method Details

Hide inherited methods

__construct() public method

public mixed __construct ( Yiisoft\Db\QueryBuilder\QueryBuilderInterface $queryBuilder, Yiisoft\Db\Schema\QuoterInterface $quoter, Yiisoft\Db\Schema\SchemaInterface $schema )
$queryBuilder Yiisoft\Db\QueryBuilder\QueryBuilderInterface
$quoter Yiisoft\Db\Schema\QuoterInterface
$schema Yiisoft\Db\Schema\SchemaInterface

                public function __construct(
    protected QueryBuilderInterface $queryBuilder,
    protected QuoterInterface $quoter,
    protected SchemaInterface $schema,
) {}

            
buildSimpleSelect() protected method

protected string buildSimpleSelect ( array $columns )
$columns array

                protected function buildSimpleSelect(array $columns): string
{
    $quoter = $this->quoter;
    foreach ($columns as $name => &$column) {
        $column .= ' AS ' . $quoter->quoteSimpleColumnName($name);
    }
    return 'SELECT ' . implode(', ', $columns);
}

            
delete() public method

public string delete ( string $table, array|string $condition, array &$params )
$table string
$condition array|string
$params array

                public function delete(string $table, array|string $condition, array &$params): string
{
    $sql = 'DELETE FROM ' . $this->quoter->quoteTableName($table);
    $where = $this->queryBuilder->buildWhere($condition, $params);
    return $where === '' ? $sql : $sql . ' ' . $where;
}

            
extractColumnNames() protected method

Extract column names from columns and rows.

protected string[] extractColumnNames ( array[]|Iterator $rows, string[] $columns )
$rows array[]|Iterator

The rows to be batch inserted into the table.

$columns string[]

The column names.

return string[]

The column names.

                protected function extractColumnNames(array|Iterator $rows, array $columns): array
{
    $columns = $this->getNormalizedColumnNames($columns);
    if (!empty($columns)) {
        return $columns;
    }
    if ($rows instanceof Iterator) {
        $row = $rows->current();
    } else {
        $row = reset($rows);
    }
    $row = match (gettype($row)) {
        'array' => $row,
        'object' => $row instanceof Traversable
            ? iterator_to_array($row)
            : get_object_vars($row),
        default => [],
    };
    if (array_key_exists(0, $row)) {
        return [];
    }
    /** @var string[] $columnNames */
    $columnNames = array_keys($row);
    return array_combine($columnNames, $columnNames);
}

            
getNormalizedColumnNames() protected method

Get normalized column names

protected string[] getNormalizedColumnNames ( string[] $columns )
$columns string[]

The column names.

return string[]

Normalized column names.

                protected function getNormalizedColumnNames(array $columns): array
{
    foreach ($columns as &$name) {
        $name = $this->quoter->ensureColumnName($name);
        $name = $this->quoter->unquoteSimpleColumnName($name);
    }
    return $columns;
}

            
getQueryColumnNames() protected method

Prepare select-subQuery and field names for INSERT INTO ... SELECT SQL statement.

protected string[] getQueryColumnNames ( Yiisoft\Db\Query\QueryInterface $query, array &$params = [] )
$query Yiisoft\Db\Query\QueryInterface

Object, which represents a select query.

$params array

The parameters to bind to the generated SQL statement. These parameters will be included in the result, with the more parameters generated during the query building process.

return string[]

Array of column names, values, and params.

throws Yiisoft\Db\Exception\Exception
throws InvalidArgumentException
throws Yiisoft\Db\Exception\InvalidConfigException
throws Yiisoft\Db\Exception\NotSupportedException

                protected function getQueryColumnNames(QueryInterface $query, array &$params = []): array
{
    /** @var string[] $select */
    $select = $query->getSelect();
    if (empty($select) || in_array('*', $select, true)) {
        throw new InvalidArgumentException('Expected select query object with enumerated (named) parameters');
    }
    $names = [];
    foreach ($select as $title => $field) {
        if (is_string($title)) {
            $names[] = $title;
        } else {
            if ($field instanceof ExpressionInterface) {
                $field = $this->queryBuilder->buildExpression($field, $params);
            }
            if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)([\w\-_.]+)$/', $field, $matches)) {
                $names[] = $matches[2];
            } else {
                $names[] = $field;
            }
        }
    }
    return $this->getNormalizedColumnNames($names);
}

            
insert() public method

public string insert ( string $table, array|Yiisoft\Db\Query\QueryInterface $columns, array &$params = [] )
$table string
$columns array|Yiisoft\Db\Query\QueryInterface
$params array

                public function insert(string $table, array|QueryInterface $columns, array &$params = []): string
{
    [$names, $placeholders, $values, $params] = $this->prepareInsertValues($table, $columns, $params);
    $quotedNames = array_map($this->quoter->quoteColumnName(...), $names);
    return 'INSERT INTO ' . $this->quoter->quoteTableName($table)
        . (!empty($quotedNames) ? ' (' . implode(', ', $quotedNames) . ')' : '')
        . (!empty($placeholders) ? ' VALUES (' . implode(', ', $placeholders) . ')' : ' ' . $values);
}

            
insertBatch() public method

public string insertBatch ( string $table, iterable $rows, array $columns = [], array &$params = [] )
$table string
$rows iterable
$columns array
$params array

                public function insertBatch(string $table, iterable $rows, array $columns = [], array &$params = []): string
{
    if (!is_array($rows)) {
        $rows = $this->prepareTraversable($rows);
    }
    if (empty($rows)) {
        return '';
    }
    $columns = $this->extractColumnNames($rows, $columns);
    $values = $this->prepareBatchInsertValues($table, $rows, $columns, $params);
    $query = 'INSERT INTO ' . $this->quoter->quoteTableName($table);
    if (count($columns) > 0) {
        $quotedColumnNames = array_map($this->quoter->quoteColumnName(...), $columns);
        $query .= ' (' . implode(', ', $quotedColumnNames) . ')';
    }
    return $query . ' VALUES (' . implode('), (', $values) . ')';
}

            
insertReturningPks() public method

public string insertReturningPks ( string $table, array|Yiisoft\Db\Query\QueryInterface $columns, array &$params = [] )
$table string
$columns array|Yiisoft\Db\Query\QueryInterface
$params array
throws Yiisoft\Db\Exception\NotSupportedException

                public function insertReturningPks(string $table, array|QueryInterface $columns, array &$params = []): string
{
    throw new NotSupportedException(__METHOD__ . '() is not supported by this DBMS.');
}

            
isTypecastingEnabled() public method

public boolean isTypecastingEnabled ( )

                public function isTypecastingEnabled(): bool
{
    return $this->typecasting;
}

            
normalizeColumnNames() protected method

Normalizes the column names.

protected array normalizeColumnNames ( array $columns )
$columns array

The column data (name => value).

return array

The normalized column names (name => value).

                protected function normalizeColumnNames(array $columns): array
{
    /** @var string[] $columnNames */
    $columnNames = array_keys($columns);
    $normalizedNames = $this->getNormalizedColumnNames($columnNames);
    return array_combine($normalizedNames, $columns);
}

            
prepareBatchInsertValues() protected method

Prepare values for batch insert.

protected string[] prepareBatchInsertValues ( string $table, iterable $rows, string[] $columnNames, array &$params )
$table string

The table name.

$rows iterable

The rows to be batch inserted into the table.

$columnNames string[]

The column names.

$params array

The binding parameters that will be generated by this method.

return string[]

The values.

                protected function prepareBatchInsertValues(string $table, iterable $rows, array $columnNames, array &$params): array
{
    $values = [];
    $names = array_values($columnNames);
    $keys = array_fill_keys($names, false);
    $columns = $this->typecasting ? $this->schema->getTableSchema($table)?->getColumns() ?? [] : [];
    $queryBuilder = $this->queryBuilder;
    foreach ($rows as $row) {
        $i = 0;
        $placeholders = $keys;
        /** @var int|string $key */
        foreach ($row as $key => $value) {
            $columnName = $columnNames[$key] ?? (isset($keys[$key]) ? $key : $names[$i] ?? $i);
            if (isset($columns[$columnName])) {
                $value = $columns[$columnName]->dbTypecast($value);
            }
            $placeholders[$columnName] = $queryBuilder->buildValue($value, $params);
            ++$i;
        }
        $values[] = implode(', ', $placeholders);
    }
    return $values;
}

            
prepareInsertValues() protected method

Prepare column names and placeholders for INSERT SQL statement.

protected array prepareInsertValues ( string $table, array|Yiisoft\Db\Query\QueryInterface $columns, array $params = [] )
$table string

The table to insert new rows into.

$columns array|Yiisoft\Db\Query\QueryInterface

The column data (name => value) to insert into the table or instance of {@see \Yiisoft\Db\QueryBuilder\Query} to perform INSERT INTO ... SELECT SQL statement.

$params array

The binding parameters that will be generated by this method. They should be bound to the DB command later.

return array

Array of column names, placeholders, values, and params.

throws Yiisoft\Db\Exception\Exception
throws Yiisoft\Db\Exception\InvalidConfigException
throws InvalidArgumentException
throws Yiisoft\Db\Exception\NotSupportedException

                protected function prepareInsertValues(string $table, array|QueryInterface $columns, array $params = []): array
{
    if (empty($columns)) {
        return [[], [], 'DEFAULT VALUES', []];
    }
    if ($columns instanceof QueryInterface) {
        $names = $this->getQueryColumnNames($columns, $params);
        [$values, $params] = $this->queryBuilder->build($columns, $params);
        return [$names, [], $values, $params];
    }
    $placeholders = [];
    $columns = $this->normalizeColumnNames($columns);
    $tableColumns = $this->typecasting ? $this->schema->getTableSchema($table)?->getColumns() ?? [] : [];
    foreach ($columns as $name => $value) {
        if (isset($tableColumns[$name])) {
            $value = $tableColumns[$name]->dbTypecast($value);
        }
        $placeholders[] = $this->queryBuilder->buildValue($value, $params);
    }
    return [array_keys($columns), $placeholders, '', $params];
}

            
prepareTraversable() protected method

Prepare traversable for batch insert.

protected array|Iterator prepareTraversable ( Traversable $rows )
$rows Traversable

The rows to be batch inserted into the table.

return array|Iterator

The prepared rows.

                final protected function prepareTraversable(Traversable $rows): Iterator|array
{
    while ($rows instanceof IteratorAggregate) {
        $rows = $rows->getIterator();
    }
    /** @var Iterator $rows */
    if (!$rows->valid()) {
        return [];
    }
    return $rows;
}

            
prepareUpdateSets() protected method

Prepare column names and placeholders for UPDATE SQL statement.

protected string[] prepareUpdateSets ( string $table, array $columns, array &$params, boolean $forUpsert false, boolean $useTableName false )
$table string
$columns array
$params array
$forUpsert boolean
$useTableName boolean

                protected function prepareUpdateSets(
    string $table,
    array $columns,
    array &$params,
    bool $forUpsert = false,
    bool $useTableName = false,
): array {
    $sets = [];
    $columns = $this->normalizeColumnNames($columns);
    $tableColumns = $this->schema->getTableSchema($table)?->getColumns() ?? [];
    $typecastColumns = $this->typecasting ? $tableColumns : [];
    $queryBuilder = $this->queryBuilder;
    $quoter = $this->quoter;
    if ($useTableName) {
        $quotedTableName = $quoter->quoteTableName($table);
        $columnPrefix = "$quotedTableName.";
    } else {
        $columnPrefix = '';
    }
    foreach ($columns as $name => $value) {
        if (isset($typecastColumns[$name])) {
            $value = $typecastColumns[$name]->dbTypecast($value);
        }
        $quotedName = $quoter->quoteSimpleColumnName($name);
        if ($forUpsert && $value instanceof MultiOperandFunction && empty($value->getOperands())) {
            $quotedTableName ??= $quoter->quoteTableName($table);
            $value->add(new Expression("$quotedTableName.$quotedName"))
                ->add(new Expression("EXCLUDED.$quotedName"));
            if (isset($tableColumns[$name]) && $value instanceof ArrayMerge) {
                $value->type($tableColumns[$name]);
            }
            $builtValue = $queryBuilder->buildExpression($value, $params);
        } else {
            $builtValue = $queryBuilder->buildValue($value, $params);
        }
        $sets[] = "$columnPrefix$quotedName=$builtValue";
    }
    return $sets;
}

            
prepareUpsertColumns() protected method

Prepare column names and constraints for "upsert" operation.

protected array prepareUpsertColumns ( string $table, array|Yiisoft\Db\Query\QueryInterface $insertColumns, array|boolean $updateColumns, Yiisoft\Db\Constraint\Index[] &$constraints = [] )
$table string
$insertColumns array|Yiisoft\Db\Query\QueryInterface
$updateColumns array|boolean
$constraints Yiisoft\Db\Constraint\Index[]
return array

Array of unique, insert and update column names.

                protected function prepareUpsertColumns(
    string $table,
    array|QueryInterface $insertColumns,
    array|bool $updateColumns,
    array &$constraints = [],
): array {
    if ($insertColumns instanceof QueryInterface) {
        $insertNames = $this->getQueryColumnNames($insertColumns);
    } else {
        $insertNames = $this->getNormalizedColumnNames(array_keys($insertColumns));
    }
    $uniqueNames = $this->getTableUniqueColumnNames($table, $insertNames, $constraints);
    if ($updateColumns === true) {
        return [$uniqueNames, $insertNames, array_diff($insertNames, $uniqueNames)];
    }
    return [$uniqueNames, $insertNames, null];
}

            
prepareUpsertSets() protected method

Prepare column names and placeholders for upsert SQL statement.

protected string[] prepareUpsertSets ( string $table, array|boolean $updateColumns, array|null $updateNames, array &$params )
$table string
$updateColumns array|boolean
$updateNames array|null
$params array

                protected function prepareUpsertSets(
    string $table,
    array|bool $updateColumns,
    ?array $updateNames,
    array &$params,
): array {
    if ($updateColumns === true) {
        $quoter = $this->quoter;
        $sets = [];
        /** @var string[] $updateNames */
        foreach ($updateNames as $name) {
            $quotedName = $quoter->quoteSimpleColumnName($name);
            $sets[] = "$quotedName=EXCLUDED.$quotedName";
        }
        return $sets;
    }
    return $this->prepareUpdateSets($table, $updateColumns, $params, true);
}

            
resetSequence() public method

public string resetSequence ( string $table, integer|string|null $value null )
$table string
$value integer|string|null
throws Yiisoft\Db\Exception\NotSupportedException

                public function resetSequence(string $table, int|string|null $value = null): string
{
    throw new NotSupportedException(__METHOD__ . '() is not supported by this DBMS.');
}

            
update() public method

public string update ( string $table, array $columns, array|Yiisoft\Db\Expression\ExpressionInterface|string $condition, array|Yiisoft\Db\Expression\ExpressionInterface|string|null $from null, array &$params = [] )
$table string
$columns array
$condition array|Yiisoft\Db\Expression\ExpressionInterface|string
$from array|Yiisoft\Db\Expression\ExpressionInterface|string|null
$params array

                public function update(
    string $table,
    array $columns,
    array|ExpressionInterface|string $condition,
    array|ExpressionInterface|string|null $from = null,
    array &$params = [],
): string {
    $updates = $this->prepareUpdateSets($table, $columns, $params);
    $sql = 'UPDATE ' . $this->quoter->quoteTableName($table) . ' SET ' . implode(', ', $updates);
    $where = $this->queryBuilder->buildWhere($condition, $params);
    if ($from !== null) {
        $from = DbArrayHelper::normalizeExpressions($from);
        $fromClause = $this->queryBuilder->buildFrom($from, $params);
        $sql .=  $fromClause === '' ? '' : ' ' . $fromClause;
    }
    return $where === '' ? $sql : $sql . ' ' . $where;
}

            
upsert() public method

public string upsert ( string $table, array|Yiisoft\Db\Query\QueryInterface $insertColumns, array|boolean $updateColumns true, array &$params = [] )
$table string
$insertColumns array|Yiisoft\Db\Query\QueryInterface
$updateColumns array|boolean
$params array
throws Yiisoft\Db\Exception\NotSupportedException

                public function upsert(
    string $table,
    array|QueryInterface $insertColumns,
    array|bool $updateColumns = true,
    array &$params = [],
): string {
    throw new NotSupportedException(__METHOD__ . ' is not supported by this DBMS.');
}

            
upsertReturning() public method

public string upsertReturning ( string $table, array|Yiisoft\Db\Query\QueryInterface $insertColumns, array|boolean $updateColumns true, array|null $returnColumns null, array &$params = [] )
$table string
$insertColumns array|Yiisoft\Db\Query\QueryInterface
$updateColumns array|boolean
$returnColumns array|null
$params array
throws Yiisoft\Db\Exception\NotSupportedException

                public function upsertReturning(
    string $table,
    array|QueryInterface $insertColumns,
    array|bool $updateColumns = true,
    ?array $returnColumns = null,
    array &$params = [],
): string {
    throw new NotSupportedException(__METHOD__ . '() is not supported by this DBMS.');
}

            
withTypecasting() public method

public Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder withTypecasting ( boolean $typecasting true )
$typecasting boolean

                public function withTypecasting(bool $typecasting = true): static
{
    $new = clone $this;
    $new->typecasting = $typecasting;
    return $new;
}