Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor DMLQueryBuilder #302

Merged
merged 8 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Chg #297: Remove `QueryBuilder::getColumnType()` child method as legacy code (@Tigrov)
- Enh #300: Refactor insert default values (@Tigrov)
- Bug #302: Refactor `DMLQueryBuilder`, related with yiisoft/db#746 (@Tigrov)

## 1.0.1 July 24, 2023

Expand Down
30 changes: 9 additions & 21 deletions src/DMLQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@
use Yiisoft\Db\Exception\InvalidConfigException;
use Yiisoft\Db\Exception\NotSupportedException;
use Yiisoft\Db\Expression\Expression;
use Yiisoft\Db\Expression\ExpressionInterface;
use Yiisoft\Db\Query\Query;
use Yiisoft\Db\Query\QueryInterface;
use Yiisoft\Db\QueryBuilder\AbstractDMLQueryBuilder;

use function implode;
use function reset;
use function str_replace;

/**
* Implements a DML (Data Manipulation Language) SQL statements for MySQL, MariaDB.
Expand Down Expand Up @@ -50,8 +49,7 @@ public function resetSequence(string $table, int|string $value = null): string
return 'ALTER TABLE ' . $tableName . ' AUTO_INCREMENT=' . $value . ';';
}

$pk = $tableSchema->getPrimaryKey();
$key = (string) reset($pk);
$key = $tableSchema->getPrimaryKey()[0];

return "SET @new_autoincrement_value := (SELECT MAX(`$key`) + 1 FROM $tableName);
SET @sql = CONCAT('ALTER TABLE $tableName AUTO_INCREMENT =', @new_autoincrement_value);
Expand All @@ -67,35 +65,24 @@ public function upsert(
): string {
$insertSql = $this->insert($table, $insertColumns, $params);

/** @psalm-var array $uniqueNames */
[$uniqueNames, , $updateNames] = $this->prepareUpsertColumns(
$table,
$insertColumns,
$updateColumns,
);
[$uniqueNames, , $updateNames] = $this->prepareUpsertColumns($table, $insertColumns, $updateColumns);

if (empty($uniqueNames)) {
return $insertSql;
}

if ($updateColumns === true) {
$updateColumns = [];
/** @psalm-var string $name */
foreach ($updateNames as $name) {
$updateColumns[$name] = new Expression(
'VALUES(' . $this->quoter->quoteColumnName($name) . ')'
);
/** @psalm-var string[] $updateNames */
vjik marked this conversation as resolved.
Show resolved Hide resolved
foreach ($updateNames as $quotedName) {
$updateColumns[$quotedName] = new Expression('VALUES(' . $quotedName . ')');
}
}

if (empty($updateColumns)) {
return str_replace('INSERT INTO', 'INSERT IGNORE INTO', $insertSql);
}

/**
* @psalm-var array<array-key, string> $updates
* @psalm-var array<string, ExpressionInterface|string> $updateColumns
*/
[$updates, $params] = $this->prepareUpdateSets($table, $updateColumns, $params);

return $insertSql . ' ON DUPLICATE KEY UPDATE ' . implode(', ', $updates);
Expand All @@ -115,12 +102,13 @@ public function upsert(
* @throws InvalidConfigException
* @throws NotSupportedException
*
* @return array Array of column names, placeholders, values, and params.
* @return array Array of quoted column names, placeholders, values, and params.
* @psalm-return array{0: string[], 1: string[], 2: string, 3: array}
*/
protected function prepareInsertValues(string $table, QueryInterface|array $columns, array $params = []): array
{
if (empty($columns)) {
return [[], [], ' VALUES ()', []];
return [[], [], 'VALUES ()', []];
}

return parent::prepareInsertValues($table, $columns, $params);
Expand Down
4 changes: 4 additions & 0 deletions tests/Provider/QueryBuilderProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ public static function upsert(): array
3 => 'INSERT INTO `T_upsert` (`email`, `address`, `status`, `profile_id`) VALUES (:qp0, :qp1, :qp2, :qp3) ' .
'ON DUPLICATE KEY UPDATE `address`=VALUES(`address`), `status`=VALUES(`status`), `profile_id`=VALUES(`profile_id`)',
],
'regular values with unique at not the first position' => [
3 => 'INSERT INTO `T_upsert` (`address`, `email`, `status`, `profile_id`) VALUES (:qp0, :qp1, :qp2, :qp3) ' .
'ON DUPLICATE KEY UPDATE `address`=VALUES(`address`), `status`=VALUES(`status`), `profile_id`=VALUES(`profile_id`)',
],
'regular values with update part' => [
3 => 'INSERT INTO `T_upsert` (`email`, `address`, `status`, `profile_id`) VALUES (:qp0, :qp1, :qp2, :qp3) ' .
'ON DUPLICATE KEY UPDATE `address`=:qp4, `status`=:qp5, `orders`=T_upsert.orders + 1',
Expand Down
3 changes: 1 addition & 2 deletions tests/QueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Yiisoft\Db\Mysql\Tests;

use Generator;
use Throwable;
use Yiisoft\Db\Exception\Exception;
use Yiisoft\Db\Exception\InvalidArgumentException;
Expand Down Expand Up @@ -143,7 +142,7 @@ public function testAddUnique(string $name, string $table, array|string $columns
* @throws InvalidArgumentException
* @throws NotSupportedException
*/
public function testBatchInsert(string $table, array $columns, iterable|Generator $rows, string $expected): void
public function testBatchInsert(string $table, array $columns, iterable $rows, string $expected): void
{
parent::testBatchInsert($table, $columns, $rows, $expected);
}
Expand Down
Loading