Skip to content
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
18 changes: 18 additions & 0 deletions analyzer-baseline.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1464,6 +1464,24 @@ code = "missing-api-or-internal"
message = 'Interface `PhpDb\Exception\ExceptionInterface` is missing an `@api` or `@internal` annotation.'
count = 1

[[issues]]
file = "src/Metadata/Exception/ExceptionInterface.php"
code = "missing-api-or-internal"
message = 'Interface `PhpDb\Metadata\Exception\ExceptionInterface` is missing an `@api` or `@internal` annotation.'
count = 1

[[issues]]
file = "src/Metadata/Exception/InvalidArgumentException.php"
code = "class-must-be-final"
message = 'Class `PhpDb\Metadata\Exception\InvalidArgumentException` should be declared `final`.'
count = 1

[[issues]]
file = "src/Metadata/Exception/RuntimeException.php"
code = "class-must-be-final"
message = 'Class `PhpDb\Metadata\Exception\RuntimeException` should be declared `final`.'
count = 1

[[issues]]
file = "src/Metadata/Object/ConstraintKeyObject.php"
code = "missing-constant-type"
Expand Down
9 changes: 9 additions & 0 deletions src/Metadata/Exception/InvalidArgumentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace PhpDb\Metadata\Exception;

use PhpDb\Exception;

class InvalidArgumentException extends Exception\InvalidArgumentException {}
54 changes: 54 additions & 0 deletions src/Metadata/Exception/RuntimeException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace PhpDb\Metadata\Exception;

use PhpDb\Exception;

use function sprintf;

class RuntimeException extends Exception\RuntimeException
{
final public const string UNKNOWN_COLUMN = 'A column by that name was not found.';

final public const string UNKNOWN_CONSTRAINT = 'Cannot find a constraint by that name in this table';

final public const string UNKNOWN_TABLE = 'Table "%s" does not exist';

final public const string UNKNOWN_TRIGGER = 'Trigger "%s" does not exist';

final public const string UNKNOWN_VIEW = 'View "%s" does not exist';

final public const string UNSUPPORTED_TABLE_TYPE = 'Table "%s" is of an unsupported type "%s"';

public static function forUnknownColumn(): self
{
return new self(self::UNKNOWN_COLUMN);
}

public static function forUnknownConstraint(): self
{
return new self(self::UNKNOWN_CONSTRAINT);
}

public static function forUnknownTable(string $tableName): self
{
return new self(sprintf(self::UNKNOWN_TABLE, $tableName));
}

public static function forUnknownTrigger(string $triggerName): self
{
return new self(sprintf(self::UNKNOWN_TRIGGER, $triggerName));
}

public static function forUnknownView(string $viewName): self
{
return new self(sprintf(self::UNKNOWN_VIEW, $viewName));
}

public static function forUnsupportedTableType(string $tableName, string $tableType): self
{
return new self(sprintf(self::UNSUPPORTED_TABLE_TYPE, $tableName, $tableType));
}
}
40 changes: 19 additions & 21 deletions src/Metadata/Source/AbstractSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
namespace PhpDb\Metadata\Source;

use DateTime;
use Exception;
use Override;
use PhpDb\Adapter\AdapterInterface;
use PhpDb\Adapter\SchemaAwareInterface;
use PhpDb\Metadata\Exception;
use PhpDb\Metadata\MetadataInterface;
use PhpDb\Metadata\Object\ColumnObject;
use PhpDb\Metadata\Object\ConstraintKeyObject;
Expand Down Expand Up @@ -115,7 +115,7 @@
}

/**
* @throws Exception If the column does not exist.
* @throws Exception\RuntimeException If the column does not exist.
*/
#[Override]
public function getColumn(string $columnName, string $table, ?string $schema = null): ColumnObject
Expand All @@ -124,11 +124,11 @@
$schema = $this->defaultSchema;
}

$this->loadColumnData($table, $schema);

Check warning on line 127 in src/Metadata/Source/AbstractSource.php

View workflow job for this annotation

GitHub Actions / qa / Mutation testing

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $schema = $this->defaultSchema; } - $this->loadColumnData($table, $schema); + $info = $this->data['columns'][$schema][$table][$columnName] ?? null; if (null === $info) {

$info = $this->data['columns'][$schema][$table][$columnName] ?? null;
if (null === $info) {
throw new Exception('A column by that name was not found.');
throw Exception\RuntimeException::forUnknownColumn();
}

$column = new ColumnObject($columnName, $table, $schema);
Expand All @@ -142,13 +142,13 @@
$column->setCharacterOctetLength(
$info['character_octet_length'] ? (int) $info['character_octet_length'] : null,
);
$column->setNumericPrecision(

Check warning on line 145 in src/Metadata/Source/AbstractSource.php

View workflow job for this annotation

GitHub Actions / qa / Mutation testing

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $column->setCharacterOctetLength( $info['character_octet_length'] ? (int) $info['character_octet_length'] : null, ); - $column->setNumericPrecision( - $info['numeric_precision'] ? (int) $info['numeric_precision'] : null, - ); + $column->setNumericScale( $info['numeric_scale'] ? (int) $info['numeric_scale'] : null, );
$info['numeric_precision'] ? (int) $info['numeric_precision'] : null,
);
$column->setNumericScale(

Check warning on line 148 in src/Metadata/Source/AbstractSource.php

View workflow job for this annotation

GitHub Actions / qa / Mutation testing

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $column->setNumericPrecision( $info['numeric_precision'] ? (int) $info['numeric_precision'] : null, ); - $column->setNumericScale( - $info['numeric_scale'] ? (int) $info['numeric_scale'] : null, - ); + $column->setNumericUnsigned($info['numeric_unsigned']); $column->setErratas($info['erratas']);
$info['numeric_scale'] ? (int) $info['numeric_scale'] : null,
);
$column->setNumericUnsigned($info['numeric_unsigned']);

Check warning on line 151 in src/Metadata/Source/AbstractSource.php

View workflow job for this annotation

GitHub Actions / qa / Mutation testing

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $column->setNumericScale( $info['numeric_scale'] ? (int) $info['numeric_scale'] : null, ); - $column->setNumericUnsigned($info['numeric_unsigned']); + $column->setErratas($info['erratas']); return $column;
$column->setErratas($info['erratas']);

return $column;
Expand All @@ -157,7 +157,7 @@
/**
* @return list<string>
*
* @throws Exception If the table does not exist.
* @throws Exception\RuntimeException If the table does not exist.
*/
#[Override]
public function getColumnNames(string $table, ?string $schema = null): array
Expand All @@ -166,11 +166,11 @@
$schema = $this->defaultSchema;
}

$this->loadColumnData($table, $schema);

Check warning on line 169 in src/Metadata/Source/AbstractSource.php

View workflow job for this annotation

GitHub Actions / qa / Mutation testing

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $schema = $this->defaultSchema; } - $this->loadColumnData($table, $schema); + $columns = $this->data['columns'][$schema][$table] ?? null; if (null === $columns) {

$columns = $this->data['columns'][$schema][$table] ?? null;
if (null === $columns) {
throw new Exception("\"{$table}\" does not exist");
throw Exception\RuntimeException::forUnknownTable($table);
}

return array_keys($columns);
Expand All @@ -181,7 +181,7 @@
*
* @return list<ColumnObject>
*
* @throws Exception If the table does not exist.
* @throws Exception\RuntimeException If the table does not exist.
*/
#[Override]
public function getColumns(string $table, ?string $schema = null): array
Expand All @@ -201,7 +201,7 @@
}

/**
* @throws Exception If the constraint does not exist.
* @throws Exception\RuntimeException If the constraint does not exist.
*/
#[Override]
public function getConstraint(
Expand All @@ -217,7 +217,7 @@

$info = $this->data['constraints'][$schema][$table][$constraintName] ?? null;
if (null === $info) {
throw new Exception('Cannot find a constraint by that name in this table');
throw Exception\RuntimeException::forUnknownConstraint();
}

$constraint = new ConstraintObject($constraintName, $table, $schema);
Expand Down Expand Up @@ -331,7 +331,7 @@
*
* @return list<ConstraintObject>
*
* @throws Exception If a constraint cannot be loaded.
* @throws Exception\RuntimeException If a constraint cannot be loaded.
*/
#[Override]
public function getConstraints(string $table, ?string $schema = null): array
Expand Down Expand Up @@ -364,7 +364,7 @@
}

/**
* @throws Exception If the table does not exist or is of an unsupported type.
* @throws Exception\RuntimeException If the table does not exist or is of an unsupported type.
*/
#[Override]
public function getTable(string $tableName, ?string $schema = null): TableObject|ViewObject
Expand All @@ -377,7 +377,7 @@

$data = $this->data['table_names'][$schema][$tableName] ?? null;
if (null === $data) {
throw new Exception("Table \"{$tableName}\" does not exist");
throw Exception\RuntimeException::forUnknownTable($tableName);
}

switch ($data['table_type']) {
Expand All @@ -391,9 +391,7 @@
$table->setIsUpdatable($data['is_updatable'] ?? null);
break;
default:
throw new Exception(
"Table \"{$tableName}\" is of an unsupported type \"{$data['table_type']}\"",
);
throw Exception\RuntimeException::forUnsupportedTableType($tableName, $data['table_type']);
}

$table->setColumns($this->getColumns($tableName, $schema));
Expand Down Expand Up @@ -440,7 +438,7 @@
*
* @return list<TableObject|ViewObject>
*
* @throws Exception If a table cannot be loaded.
* @throws Exception\RuntimeException If a table cannot be loaded.
*/
#[Override]
public function getTables(?string $schema = null, bool $includeViews = false): array
Expand All @@ -458,7 +456,7 @@
}

/**
* @throws Exception If the trigger does not exist.
* @throws Exception\RuntimeException If the trigger does not exist.
*/
#[Override]
public function getTrigger(string $triggerName, ?string $schema = null): TriggerObject
Expand All @@ -471,7 +469,7 @@

$info = $this->data['triggers'][$schema][$triggerName] ?? null;
if (null === $info) {
throw new Exception("Trigger \"{$triggerName}\" does not exist");
throw Exception\RuntimeException::forUnknownTrigger($triggerName);
}

$trigger = new TriggerObject();
Expand Down Expand Up @@ -517,7 +515,7 @@
*
* @return list<TriggerObject>
*
* @throws Exception If a trigger cannot be loaded.
* @throws Exception\RuntimeException If a trigger cannot be loaded.
*/
#[Override]
public function getTriggers(?string $schema = null): array
Expand All @@ -535,7 +533,7 @@
}

/**
* @throws Exception If the view does not exist.
* @throws Exception\RuntimeException If the view does not exist.
*/
#[Override]
public function getView(string $viewName, ?string $schema = null): ViewObject|TableObject
Expand All @@ -551,7 +549,7 @@
return $this->getTable($viewName, $schema);
}

throw new Exception("View \"{$viewName}\" does not exist");
throw Exception\RuntimeException::forUnknownView($viewName);
}

/**
Expand Down Expand Up @@ -585,7 +583,7 @@
*
* @return list<TableObject|ViewObject>
*
* @throws Exception If a view cannot be loaded.
* @throws Exception\RuntimeException If a view cannot be loaded.
*/
#[Override]
public function getViews(?string $schema = null): array
Expand Down
3 changes: 3 additions & 0 deletions test/unit/Exception/ExceptionHierarchyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use InvalidArgumentException;
use PhpDb\Adapter\Exception as AdapterException;
use PhpDb\Exception as DbException;
use PhpDb\Metadata\Exception as MetadataException;
use PhpDb\ResultSet\Exception as ResultSetException;
use PhpDb\RowGateway\Exception as RowGatewayException;
use PhpDb\Sql\Exception as SqlException;
Expand Down Expand Up @@ -66,6 +67,8 @@ final class ExceptionHierarchyTest extends TestCase
DbException\InvalidArgumentException::class => InvalidArgumentException::class,
DbException\RuntimeException::class => RuntimeException::class,
DbException\UnexpectedValueException::class => UnexpectedValueException::class,
MetadataException\InvalidArgumentException::class => InvalidArgumentException::class,
MetadataException\RuntimeException::class => RuntimeException::class,
ResultSetException\InvalidArgumentException::class => InvalidArgumentException::class,
ResultSetException\RuntimeException::class => RuntimeException::class,
RowGatewayException\InvalidArgumentException::class => InvalidArgumentException::class,
Expand Down
80 changes: 80 additions & 0 deletions test/unit/Metadata/Exception/RuntimeExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace PhpDbTest\Metadata\Exception;

use PhpDb\Exception\ExceptionInterface;
use PhpDb\Metadata\Exception\RuntimeException;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

use function sprintf;

#[Group('unit')]
#[CoversMethod(RuntimeException::class, 'forUnknownColumn')]
#[CoversMethod(RuntimeException::class, 'forUnknownConstraint')]
#[CoversMethod(RuntimeException::class, 'forUnknownTable')]
#[CoversMethod(RuntimeException::class, 'forUnknownTrigger')]
#[CoversMethod(RuntimeException::class, 'forUnknownView')]
#[CoversMethod(RuntimeException::class, 'forUnsupportedTableType')]
final class RuntimeExceptionTest extends TestCase
{
/** @return array<string, array{string, list<string>, string}> */
public static function namedConstructorProvider(): array
{
return [
'unknown column' => [
'forUnknownColumn',
[],
RuntimeException::UNKNOWN_COLUMN,
],
'unknown constraint' => [
'forUnknownConstraint',
[],
RuntimeException::UNKNOWN_CONSTRAINT,
],
'unknown table' => [
'forUnknownTable',
['users'],
RuntimeException::UNKNOWN_TABLE,
],
'unknown trigger' => [
'forUnknownTrigger',
['after_insert'],
RuntimeException::UNKNOWN_TRIGGER,
],
'unknown view' => [
'forUnknownView',
['active_users'],
RuntimeException::UNKNOWN_VIEW,
],
'unsupported table type' => [
'forUnsupportedTableType',
['users', 'SYSTEM VIEW'],
RuntimeException::UNSUPPORTED_TABLE_TYPE,
],
];
}

/** @param list<string> $arguments */
#[Test]
#[DataProvider('namedConstructorProvider')]
public function namedConstructorRendersItsTemplate(string $method, array $arguments, string $template): void
{
$exception = RuntimeException::{$method}(...$arguments);

self::assertSame(sprintf($template, ...$arguments), $exception->getMessage());
}

/** @param list<string> $arguments */
#[Test]
#[DataProvider('namedConstructorProvider')]
public function namedConstructorReturnsTheComponentExceptionType(string $method, array $arguments): void
{
self::assertInstanceOf(ExceptionInterface::class, RuntimeException::{$method}(...$arguments));
}
}
Loading
Loading