Skip to content

Commit

Permalink
修复 PostgreSQL replace() 没有更新字段值 (#634)
Browse files Browse the repository at this point in the history
* 修复 PostgreSQL replace() 没有更新字段值

* 更新测试
  • Loading branch information
Yurunsoft authored Nov 7, 2023
1 parent b3757da commit b3e6027
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 4 deletions.
2 changes: 0 additions & 2 deletions src/Components/pgsql/src/Db/Query/Builder/InsertBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Imi\Pgsql\Db\Query\Builder;

use Imi\Db\Query\QueryOption;
use Imi\Util\ArrayUtil;

class InsertBuilder extends BaseBuilder
Expand All @@ -14,7 +13,6 @@ public function build(...$args): string
parent::build(...$args);
$query = $this->query;
$params = &$this->params;
/** @var QueryOption $option */
$option = $query->getOption();
[$data] = $args;
if (null === $data)
Expand Down
29 changes: 27 additions & 2 deletions src/Components/pgsql/src/Db/Query/Builder/ReplaceBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Imi\Pgsql\Db\Query\Builder;

use Imi\Util\ArrayUtil;

class ReplaceBuilder extends InsertBuilder
{
public function build(...$args): string
Expand All @@ -14,11 +16,34 @@ public function build(...$args): string
throw new \InvalidArgumentException('pgsql replace must set unique fields');
}
$query = $this->query;
$setItems = [];
[$data] = $args;
if (null === $data)
{
$data = $query->getOption()->saveData;
}
if ($data instanceof \Traversable)
{
$data = iterator_to_array($data);
}
if (ArrayUtil::isAssoc($data))
{
$setItems = [];
foreach ($data as $k => $_)
{
if (!\in_array($k, $uniqueFields))
{
$fieldName = $query->fieldQuote($k);
$setItems[] = $fieldName . ' = excluded.' . $fieldName;
}
}
}
else
{
throw new \InvalidArgumentException('replace() only supports key-value arrays');
}
foreach ($uniqueFields as &$fieldName)
{
$fieldName = $query->fieldQuote($fieldName);
$setItems[] = $fieldName . ' = excluded.' . $fieldName;
}

return parent::build(...$args) . ' ON CONFLICT (' . implode(',', $uniqueFields) . ') DO UPDATE SET ' . implode(',', $setItems);
Expand Down
46 changes: 46 additions & 0 deletions src/Components/pgsql/tests/Unit/Db/QueryCurdBaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,52 @@ public function testInsert(): array
];
}

public function testReplace(): void
{
['id' => $id] = $this->testInsert();

$data = [
'id' => $id,
'title' => 'title1',
'content' => 'content2',
'time' => '2019-06-22 00:00:00',
];

$query = Db::query($this->poolName);
try
{
$query->from('tb_article')->replace($data);
$this->assertTrue(false);
}
catch (\InvalidArgumentException $e)
{
$this->assertEquals('pgsql replace must set unique fields', $e->getMessage());
}
$query->from('tb_article')->replace($data, ['id']);
$record = $query->from('tb_article')->where('id', '=', $id)->select()->get();
Assert::assertEquals($data, $record);

$data = [
'id' => $id,
'title' => 'title3',
'content' => 'content4',
'time' => '2019-06-23 00:00:00',
];
$query->from('tb_article')->replace($data, ['id']);
$record = $query->from('tb_article')->where('id', '=', $id)->select()->get();
Assert::assertEquals($data, $record);

try
{
$query->from('tb_article')->replace(array_values($data), ['id']);
$this->assertTrue(false);
}
catch (\InvalidArgumentException $e)
{
$this->assertEquals('replace() only supports key-value arrays', $e->getMessage());
}
}

public function testUpdate(): void
{
$data = [
Expand Down
16 changes: 16 additions & 0 deletions src/Components/pgsql/tests/Unit/Model/ModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,22 @@ public function testSave(): void
'bId' => 2,
'value' => 'yurun',
], $record3->toArray());

$record4 = NoIncPk::newInstance();
$record4->setAId(1);
$record4->setBId(2);
$record4->setValue('yurun2');
$record4->save();
$record5 = NoIncPk::find([
'a_id' => 1,
'b_id' => 2,
]);
$this->assertNotNull($record5);
$this->assertEquals([
'aId' => 1,
'bId' => 2,
'value' => 'yurun2',
], $record5->toArray());
}

public function testDelete(): void
Expand Down
29 changes: 29 additions & 0 deletions tests/unit/Component/Tests/Db/DbBaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,35 @@ public function testInsert(): array
];
}

public function testReplace(): void
{
['id' => $id] = $this->testInsert();

$data = [
'id' => $id,
'title' => 'title1',
'content' => 'content2',
'time' => '2019-06-22 00:00:00',
'member_id' => 1,
];

$query = Db::query($this->poolName);
$query->from('tb_article')->replace($data);
$record = $query->from('tb_article')->where('id', '=', $id)->select()->get();
Assert::assertEquals($data, $record);

$data = [
'id' => $id,
'title' => 'title3',
'content' => 'content4',
'time' => '2019-06-23 00:00:00',
'member_id' => 2,
];
$query->from('tb_article')->replace($data);
$record = $query->from('tb_article')->where('id', '=', $id)->select()->get();
Assert::assertEquals($data, $record);
}

/**
* @depends testInsert
*/
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/Component/Tests/ModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,22 @@ public function testSave(): void
'bId' => 2,
'value' => 'yurun',
], $record3->toArray());

$record4 = NoIncPk::newInstance();
$record4->setAId(1);
$record4->setBId(2);
$record4->setValue('yurun2');
$record4->save();
$record5 = NoIncPk::find([
'a_id' => 1,
'b_id' => 2,
]);
$this->assertNotNull($record5);
$this->assertEquals([
'aId' => 1,
'bId' => 2,
'value' => 'yurun2',
], $record5->toArray());
}

public function testDelete(): void
Expand Down

0 comments on commit b3e6027

Please sign in to comment.