mirror of
https://github.com/yiisoft/yii2.git
synced 2026-03-21 22:47:17 +01:00
Fixes #8293: yii\db\Query can be passed to insert method in yii\db\QueryBuilder
This commit is contained in:
committed by
Alexander Makarov
parent
240bca515a
commit
25f08afc96
@@ -142,7 +142,9 @@ class QueryBuilder extends \yii\base\Object
|
||||
* The method will properly escape the table and column names.
|
||||
*
|
||||
* @param string $table the table that new rows will be inserted into.
|
||||
* @param array $columns the column data (name => value) to be inserted into the table.
|
||||
* @param array|\yii\db\Query $columns the column data (name => value) to be inserted into the table or instance
|
||||
* of [[yii\db\Query|Query]] to perform INSERT INTO ... SELECT SQL statement.
|
||||
* Passing of [[yii\db\Query|Query]] is available since version 2.0.11.
|
||||
* @param array $params the binding parameters that will be generated by this method.
|
||||
* They should be bound to the DB command later.
|
||||
* @return string the INSERT SQL
|
||||
@@ -157,23 +159,58 @@ class QueryBuilder extends \yii\base\Object
|
||||
}
|
||||
$names = [];
|
||||
$placeholders = [];
|
||||
foreach ($columns as $name => $value) {
|
||||
$names[] = $schema->quoteColumnName($name);
|
||||
if ($value instanceof Expression) {
|
||||
$placeholders[] = $value->expression;
|
||||
foreach ($value->params as $n => $v) {
|
||||
$params[$n] = $v;
|
||||
$values = ' DEFAULT VALUES';
|
||||
if ($columns instanceof \yii\db\Query) {
|
||||
list($names, $values) = $this->prepareInsertSelectSubQuery($columns, $schema);
|
||||
} else {
|
||||
foreach ($columns as $name => $value) {
|
||||
$names[] = $schema->quoteColumnName($name);
|
||||
if ($value instanceof Expression) {
|
||||
$placeholders[] = $value->expression;
|
||||
foreach ($value->params as $n => $v) {
|
||||
$params[$n] = $v;
|
||||
}
|
||||
} else {
|
||||
$phName = self::PARAM_PREFIX . count($params);
|
||||
$placeholders[] = $phName;
|
||||
$params[$phName] = !is_array($value) && isset($columnSchemas[$name]) ? $columnSchemas[$name]->dbTypecast($value) : $value;
|
||||
}
|
||||
} else {
|
||||
$phName = self::PARAM_PREFIX . count($params);
|
||||
$placeholders[] = $phName;
|
||||
$params[$phName] = !is_array($value) && isset($columnSchemas[$name]) ? $columnSchemas[$name]->dbTypecast($value) : $value;
|
||||
}
|
||||
}
|
||||
|
||||
return 'INSERT INTO ' . $schema->quoteTableName($table)
|
||||
. (!empty($names) ? ' (' . implode(', ', $names) . ')' : '')
|
||||
. (!empty($placeholders) ? ' VALUES (' . implode(', ', $placeholders) . ')' : ' DEFAULT VALUES');
|
||||
. (!empty($placeholders) ? ' VALUES (' . implode(', ', $placeholders) . ')' : $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare select-subquery and field names for INSERT INTO ... SELECT SQL statement.
|
||||
*
|
||||
* @param \yii\db\Query $columns Object, which represents select query
|
||||
* @param \yii\db\Schema $schema Schema object to qoute column name
|
||||
* @return array
|
||||
* @since 2.0.11
|
||||
*/
|
||||
protected function prepareInsertSelectSubQuery($columns, $schema)
|
||||
{
|
||||
if (!is_array($columns->select) || empty($columns->select) || in_array('*', $columns->select)) {
|
||||
throw new InvalidParamException('Expected select query object with enumerated (named) parameters');
|
||||
}
|
||||
|
||||
list ($values, ) = $this->build($columns);
|
||||
$names = [];
|
||||
$values = ' ' . $values;
|
||||
foreach ($columns->select as $title => $field) {
|
||||
if (is_string($title)) {
|
||||
$names[] = $title;
|
||||
} else if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)([\w\-_\.]+)$/', $field, $matches)) {
|
||||
$names[] = $schema->quoteColumnName($matches[2]);
|
||||
} else {
|
||||
$names[] = $schema->quoteColumnName($field);
|
||||
}
|
||||
}
|
||||
|
||||
return [$names, $values];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user