Skip to content

Commit 7a3e909

Browse files
committed
Wrap PDO exception for correct get sql query and parameters.
1 parent 80dfa5c commit 7a3e909

File tree

4 files changed

+121
-9
lines changed

4 files changed

+121
-9
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FiveLab Migrator package
5+
*
6+
* (c) FiveLab
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code
10+
*/
11+
12+
declare(strict_types = 1);
13+
14+
namespace FiveLab\Component\Migrator\Exception;
15+
16+
class PdoMigrationFailedException extends \Exception
17+
{
18+
/**
19+
* Constructor.
20+
*
21+
* @param string $sql
22+
* @param array<string|int, string|int|float> $parameters
23+
* @param \Throwable $previous
24+
*
25+
* @throws \JsonException
26+
*/
27+
public function __construct(
28+
public readonly string $sql,
29+
public readonly array $parameters,
30+
public \Throwable $previous
31+
) {
32+
$message = \sprintf(
33+
'Migration failed - "%s", parameters: %s with message: %s.',
34+
$this->sql,
35+
\json_encode($parameters, \JSON_THROW_ON_ERROR),
36+
\rtrim($this->previous->getMessage(), '.')
37+
);
38+
39+
parent::__construct($message, 0, $this->previous);
40+
}
41+
}

src/Migration/AbstractPdoMigration.php

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
namespace FiveLab\Component\Migrator\Migration;
1515

16+
use FiveLab\Component\Migrator\Exception\PdoMigrationFailedException;
17+
1618
abstract readonly class AbstractPdoMigration extends AbstractMigration
1719
{
1820
/**
@@ -29,19 +31,17 @@ final public function up(): void
2931
{
3032
$this->doUp();
3133

32-
foreach ($this->entries as [$sql, $parameters]) {
33-
$stmt = $this->pdo->prepare($sql);
34-
$stmt->execute($parameters);
34+
foreach ($this->entries as $entry) {
35+
$this->executeEntry($entry);
3536
}
3637
}
3738

3839
final public function down(): void
3940
{
4041
$this->doDown();
4142

42-
foreach ($this->entries as [$sql, $parameters]) {
43-
$stmt = $this->pdo->prepare($sql);
44-
$stmt->execute($parameters);
43+
foreach ($this->entries as $entry) {
44+
$this->executeEntry($entry);
4545
}
4646
}
4747

@@ -59,4 +59,22 @@ final protected function addSql(string $sql, array $parameters = []): void
5959
{
6060
$this->entries->offsetSet(\count($this->entries), [$sql, $parameters]);
6161
}
62+
63+
/**
64+
* Execute SQL entry.
65+
*
66+
* @param array{"0": string, 1: array<string|int, string|int|float>} $entry
67+
*
68+
* @throws PdoMigrationFailedException
69+
*/
70+
private function executeEntry(array $entry): void
71+
{
72+
$stmt = $this->pdo->prepare($entry[0]);
73+
74+
try {
75+
$stmt->execute($entry[1]);
76+
} catch (\Throwable $error) {
77+
throw new PdoMigrationFailedException($entry[0], $entry[1], $error);
78+
}
79+
}
6280
}

tests/Functional/Migrator/MigratorMySqlTest.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace FiveLab\Component\Migrator\Tests\Functional\Migrator;
1515

16+
use FiveLab\Component\Migrator\Exception\PdoMigrationFailedException;
1617
use FiveLab\Component\Migrator\Locator\FilesystemMigrationsLocator;
1718
use FiveLab\Component\Migrator\MigrateDirection;
1819
use FiveLab\Component\Migrator\Migrator;
@@ -33,16 +34,21 @@ protected function setUp(): void
3334
{
3435
$this->setUpMySql();
3536

36-
$locator = new FilesystemMigrationsLocator(__DIR__.'/../../Migrations/DataSet02', 'Database');
37-
38-
$this->migrator = new Migrator($locator, $this->executor);
37+
$this->migrator = $this->createMigrator(__DIR__.'/../../Migrations/DataSet02', 'Database');
3938
}
4039

4140
protected function tearDown(): void
4241
{
4342
$this->dropTables();
4443
}
4544

45+
protected function createMigrator(string $path, string $group): Migrator
46+
{
47+
$locator = new FilesystemMigrationsLocator($path, $group);
48+
49+
return new Migrator($locator, $this->executor);
50+
}
51+
4652
#[Test]
4753
public function shouldSuccessUp(): void
4854
{
@@ -120,4 +126,15 @@ public function shouldSuccessExecuteSpecificVersion(): void
120126
['id' => 2, 'label' => 'Foo Bar'],
121127
], $rows);
122128
}
129+
130+
#[Test]
131+
public function shouldSuccessWrapPdoException(): void
132+
{
133+
$migrator = $this->createMigrator(__DIR__.'/../../Migrations/DataSet03', 'Database');
134+
135+
$this->expectException(PdoMigrationFailedException::class);
136+
$this->expectExceptionMessage('Migration failed - "SELECT * FROM not_existing_table WHERE label = :foo", parameters: {"foo":"bar"} with message: SQLSTATE[42S02]: Base table or view not found:');
137+
138+
$migrator->migrate(MigrateDirection::Up, null);
139+
}
123140
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FiveLab Migrator package
5+
*
6+
* (c) FiveLab
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code
10+
*/
11+
12+
declare(strict_types = 1);
13+
14+
namespace FiveLab\Component\Migrator\Tests\Migrations\DataSet03;
15+
16+
use FiveLab\Component\Migrator\Migration\AbstractPdoMigration;
17+
18+
readonly class Version01 extends AbstractPdoMigration
19+
{
20+
public function getDescription(): string
21+
{
22+
return 'pdo version 01';
23+
}
24+
25+
protected function doUp(): void
26+
{
27+
$this->addSql('SELECT * FROM not_existing_table WHERE label = :foo', [
28+
'foo' => 'bar',
29+
]);
30+
}
31+
32+
protected function doDown(): void
33+
{
34+
$this->addSql('DROP TABLE not_existing_table');
35+
}
36+
}

0 commit comments

Comments
 (0)