Skip to content

Commit

Permalink
DriverException::getCode() returns driver error code instead of SQLSt…
Browse files Browse the repository at this point in the history
…ate (BC break)
  • Loading branch information
dg committed Aug 27, 2024
1 parent f527cac commit d27aa8a
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 86 deletions.
11 changes: 2 additions & 9 deletions src/Database/DriverException.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,11 @@ class DriverException extends \Exception
public function __construct(
string $message,
private readonly ?string $sqlState = null,
private int $driverCode = 0,
int $code = 0,
private readonly ?SqlLiteral $query = null,
?\Throwable $previous = null,
) {
parent::__construct($message, 0, $previous);
$this->code = $sqlState ?: null;
}


public function getDriverCode(): int|string|null
{
return $this->driverCode ?: null;
parent::__construct($message, $code, $previous);
}


Expand Down
41 changes: 17 additions & 24 deletions tests/Database/Connection.exceptions.mysql.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,31 @@ test('Exception thrown for invalid database credentials', function () {
fn() => new Nette\Database\Connection($options['dsn'], 'unknown', 'unknown'),
Nette\Database\ConnectionException::class,
'%a% Access denied for user %a%',
1045,
);

Assert::same(1045, $e->getDriverCode());
Assert::contains($e->getSqlState(), ['HY000', '28000']);
Assert::same($e->getCode(), $e->getSqlState());
});


testException(
'Exception thrown when calling rollback with no active transaction',
fn() => $connection->rollback(),
Nette\Database\DriverException::class,
'There is no active transaction',
);
test('Exception thrown when calling rollback with no active transaction', function () use ($connection) {
$e = Assert::exception(
fn() => $connection->rollback(),
Nette\Database\DriverException::class,
'There is no active transaction',
);
Assert::null($e->getSqlState());
});


test('Exception thrown for syntax error in SQL query', function () use ($connection) {
$e = Assert::exception(
fn() => $connection->query('SELECT'),
Nette\Database\DriverException::class,
'%a% Syntax error %a%',
'42000',
1064,
);

Assert::same(1064, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('42000', $e->getSqlState());
});


Expand All @@ -54,11 +53,9 @@ test('Exception thrown for unique constraint violation', function () use ($conne
fn() => $connection->query('INSERT INTO author (id, name, web, born) VALUES (11, "", "", NULL)'),
Nette\Database\UniqueConstraintViolationException::class,
'%a% Integrity constraint violation: %a%',
'23000',
1062,
);

Assert::same(1062, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('23000', $e->getSqlState());
});


Expand All @@ -67,11 +64,9 @@ test('Exception thrown for not null constraint violation', function () use ($con
fn() => $connection->query('INSERT INTO author (name, web, born) VALUES (NULL, "", NULL)'),
Nette\Database\NotNullConstraintViolationException::class,
'%a% Integrity constraint violation: %a%',
'23000',
1048,
);

Assert::same(1048, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('23000', $e->getSqlState());
});


Expand All @@ -80,9 +75,7 @@ test('Exception thrown for foreign key constraint violation', function () use ($
fn() => $connection->query('INSERT INTO book (author_id, translator_id, title) VALUES (999, 12, "")'),
Nette\Database\ForeignKeyConstraintViolationException::class,
'%a% a foreign key constraint fails %a%',
'23000',
1452,
);

Assert::same(1452, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('23000', $e->getSqlState());
});
45 changes: 18 additions & 27 deletions tests/Database/Connection.exceptions.postgre.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,30 @@ test('Exception thrown for invalid database credentials', function () {
fn() => new Nette\Database\Connection($options['dsn'], 'unknown', 'unknown'),
Nette\Database\ConnectionException::class,
null,
'08006',
7,
);

Assert::same(7, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('08006', $e->getSqlState());
});


testException(
'Exception thrown when calling rollback with no active transaction',
fn() => $connection->rollback(),
Nette\Database\DriverException::class,
'There is no active transaction',
null,
);
test('Exception thrown when calling rollback with no active transaction', function () use ($connection) {
$e = Assert::exception(
fn() => $connection->rollback(),
Nette\Database\DriverException::class,
'There is no active transaction',
);
Assert::null($e->getSqlState());
});


test('Exception thrown for syntax error in SQL query', function () use ($connection) {
$e = Assert::exception(
fn() => $connection->query('SELECT INTO'),
Nette\Database\DriverException::class,
'%a% syntax error %A%',
'42601',
7,
);

Assert::same(7, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('42601', $e->getSqlState());
});


Expand All @@ -56,11 +53,9 @@ test('Exception thrown for unique constraint violation', function () use ($conne
fn() => $connection->query("INSERT INTO author (id, name, web, born) VALUES (11, '', '', NULL)"),
Nette\Database\UniqueConstraintViolationException::class,
'%a% Unique violation: %A%',
'23505',
7,
);

Assert::same(7, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('23505', $e->getSqlState());
});


Expand All @@ -69,11 +64,9 @@ test('Exception thrown for not null constraint violation', function () use ($con
fn() => $connection->query("INSERT INTO author (name, web, born) VALUES (NULL, '', NULL)"),
Nette\Database\NotNullConstraintViolationException::class,
'%a% Not null violation: %A%',
'23502',
7,
);

Assert::same(7, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('23502', $e->getSqlState());
});


Expand All @@ -82,9 +75,7 @@ test('Exception thrown for foreign key constraint violation', function () use ($
fn() => $connection->query("INSERT INTO book (author_id, translator_id, title) VALUES (999, 12, '')"),
Nette\Database\ForeignKeyConstraintViolationException::class,
'%a% Foreign key violation: %A%',
'23503',
7,
);

Assert::same(7, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('23503', $e->getSqlState());
});
43 changes: 18 additions & 25 deletions tests/Database/Connection.exceptions.sqlite.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,31 @@ test('Exception thrown for unable to open database file', function () {
fn() => new Nette\Database\Connection('sqlite:.'),
Nette\Database\ConnectionException::class,
'SQLSTATE[HY000] [14] unable to open database file',
'HY000',
14,
);

Assert::same(14, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('HY000', $e->getSqlState());
});


testException(
'Exception thrown when calling rollback with no active transaction',
fn() => $connection->rollback(),
Nette\Database\DriverException::class,
'There is no active transaction',
);
test('Exception thrown when calling rollback with no active transaction', function () use ($connection) {
$e = Assert::exception(
fn() => $connection->rollback(),
Nette\Database\DriverException::class,
'There is no active transaction',
);
Assert::null($e->getSqlState());
});


test('Exception thrown for error in SQL query', function () use ($connection) {
$e = Assert::exception(
fn() => $connection->query('SELECT'),
Nette\Database\DriverException::class,
'%a% error%a%',
'HY000',
7,
);

Assert::same(1, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('HY000', $e->getSqlState());
});


Expand All @@ -54,11 +53,9 @@ test('Exception thrown for unique constraint violation', function () use ($conne
fn() => $connection->query('INSERT INTO author (id, name, web, born) VALUES (11, "", "", NULL)'),
Nette\Database\UniqueConstraintViolationException::class,
'%a% Integrity constraint violation: %a%',
'23000',
19,
);

Assert::same(19, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('23000', $e->getSqlState());
});


Expand All @@ -67,20 +64,16 @@ test('Exception thrown for not null constraint violation', function () use ($con
fn() => $connection->query('INSERT INTO author (name, web, born) VALUES (NULL, "", NULL)'),
Nette\Database\NotNullConstraintViolationException::class,
'%a% Integrity constraint violation: %a%',
'23000',
19,
);

Assert::same(19, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
Assert::same('23000', $e->getSqlState());
});


test('Exception thrown for foreign key constraint violation', function () use ($connection) {
$e = Assert::exception(function () use ($connection) {
$connection->query('PRAGMA foreign_keys=true');
$connection->query('INSERT INTO book (author_id, translator_id, title) VALUES (999, 12, "")');
}, Nette\Database\ForeignKeyConstraintViolationException::class, '%a% Integrity constraint violation: %a%', '23000');

Assert::same(19, $e->getDriverCode());
Assert::same($e->getCode(), $e->getSqlState());
}, Nette\Database\ForeignKeyConstraintViolationException::class, '%a% Integrity constraint violation: %a%', 19);
Assert::same('23000', $e->getSqlState());
});
2 changes: 1 addition & 1 deletion tests/Database/Explorer/Explorer.update().phpt
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ $tag2 = $explorer->table('tag')->insert([
'name' => 'PS4 Game',
]); // INSERT INTO `tag` (`name`) VALUES ('PS4 Game')

// SQL Server throw PDOException because does not allow to update identity column
// SQL Server throw exception because does not allow to update identity column
if ($driverName !== 'sqlsrv') {
$tag2->update([
'id' => 1,
Expand Down

0 comments on commit d27aa8a

Please sign in to comment.