Skip to content

Commit

Permalink
Merge branch '3.6.x' into 4.0.x
Browse files Browse the repository at this point in the history
* 3.6.x:
  Formally allow `url` in `DriverManager::getConnection()`
  Use narrower return types for convertTo*Value methods
  Reuse the Params type alias for getConnection()
  Test the return type of DriverManager::getAvailableDrivers()
  Use a more specific return type for DriverManager::getAvailableDrivers()
  Remove database URLs from tests
  Allow to explicitly set the wrapper class to the default one
  • Loading branch information
derrabus committed Jan 9, 2023
2 parents 851e42d + d432414 commit 5634ab4
Show file tree
Hide file tree
Showing 25 changed files with 259 additions and 39 deletions.
6 changes: 5 additions & 1 deletion phpstan.neon.dist
Expand Up @@ -3,6 +3,7 @@ parameters:
phpVersion: 80200
paths:
- src
- static-analysis
- tests
treatPhpDocTypesAsCertain: false
reportUnmatchedIgnoredErrors: false
Expand Down Expand Up @@ -70,11 +71,14 @@ parameters:
message: '~array{driver: ''invalid_driver''} given\.$~'
path: tests/DriverManagerTest.php
-
message: '~array{url: ''sqlite::memory:'', wrapperClass: ''stdClass''} given\.$~'
message: '~array{driver: ''pdo_sqlite'', memory: true, wrapperClass: ''stdClass''} given\.$~'
path: tests/DriverManagerTest.php
-
message: '~array{driverClass: ''stdClass''} given\.$~'
path: tests/DriverManagerTest.php
-
message: '~^Call to static method PHPUnit\\Framework\\Assert\:\:assert(?:NotNull|Null|InstanceOf|IsFloat|IsInt)\(\) with .* will always evaluate to true\.$~'
path: tests/Types/

# DriverManagerTest::testDatabaseUrl() should be refactored as it's too dynamic.
-
Expand Down
8 changes: 8 additions & 0 deletions psalm.xml.dist
Expand Up @@ -166,6 +166,14 @@
-->
<file name="src/Platforms/AbstractMySQLPlatform.php"/>
<file name="tests/Functional/Driver/AbstractDriverTest.php"/>

<!-- We're testing invalid input. -->
<file name="tests/Types/DateImmutableTypeTest.php"/>
<file name="tests/Types/DateTimeImmutableTypeTest.php"/>
<file name="tests/Types/TimeImmutableTypeTest.php"/>

<!-- False positive: "mixed is never string" -->
<file name="src/Platforms/PostgreSQLPlatform.php" />
</errorLevel>
</RedundantConditionGivenDocblockType>
<RedundantPropertyInitializationCheck>
Expand Down
40 changes: 8 additions & 32 deletions src/DriverManager.php
Expand Up @@ -18,7 +18,7 @@
use function array_keys;
use function class_implements;
use function in_array;
use function is_subclass_of;
use function is_a;

/**
* Factory for creating {@see Connection} instances.
Expand Down Expand Up @@ -123,30 +123,9 @@ private function __construct()
* The driver class to use.
*
* @param Configuration|null $config The configuration to use.
* @psalm-param array{
* charset?: string,
* dbname?: string,
* driver?: key-of<self::DRIVER_MAP>,
* driverClass?: class-string<Driver>,
* driverOptions?: array<mixed>,
* host?: string,
* keepSlave?: bool,
* keepReplica?: bool,
* master?: OverrideParams,
* memory?: bool,
* password?: string,
* path?: string,
* pdo?: \PDO,
* port?: int,
* primary?: OverrideParams,
* replica?: array<OverrideParams>,
* sharding?: array<string,mixed>,
* slaves?: array<OverrideParams>,
* user?: string,
* wrapperClass?: class-string<T>,
* } $params
* @psalm-param Params $params
*
* @psalm-return ($params is array{wrapperClass:mixed} ? T : Connection)
* @psalm-return ($params is array{wrapperClass: class-string<T>} ? T : Connection)
*
* @template T of Connection
*/
Expand All @@ -159,14 +138,10 @@ public static function getConnection(array $params, ?Configuration $config = nul
$driver = $middleware->wrap($driver);
}

$wrapperClass = Connection::class;
if (isset($params['wrapperClass'])) {
if (! is_subclass_of($params['wrapperClass'], $wrapperClass)) {
throw InvalidWrapperClass::new($params['wrapperClass']);
}

/** @var class-string<Connection> $wrapperClass */
$wrapperClass = $params['wrapperClass'];
/** @var class-string<Connection> $wrapperClass */
$wrapperClass = $params['wrapperClass'] ?? Connection::class;
if (! is_a($wrapperClass, Connection::class, true)) {
throw InvalidWrapperClass::new($wrapperClass);
}

return new $wrapperClass($params, $driver, $config);
Expand All @@ -176,6 +151,7 @@ public static function getConnection(array $params, ?Configuration $config = nul
* Returns the list of supported drivers.
*
* @return string[]
* @psalm-return list<key-of<self::DRIVER_MAP>>
*/
public static function getAvailableDrivers(): array
{
Expand Down
6 changes: 6 additions & 0 deletions src/Platforms/AbstractPlatform.php
Expand Up @@ -1736,6 +1736,12 @@ public function convertBooleans(mixed $item): mixed
* Some platforms have boolean literals that needs to be correctly converted
*
* The default conversion tries to convert value into bool "(bool)$item"
*
* @param T $item
*
* @return (T is null ? null : bool)
*
* @template T
*/
public function convertFromBoolean(mixed $item): ?bool
{
Expand Down
7 changes: 7 additions & 0 deletions src/Platforms/PostgreSQLPlatform.php
Expand Up @@ -531,6 +531,13 @@ static function ($value): ?int {
);
}

/**
* @param T $item
*
* @return (T is null ? null : bool)
*
* @template T
*/
public function convertFromBoolean(mixed $item): ?bool
{
if (in_array($item, $this->booleanLiterals['false'], true)) {
Expand Down
7 changes: 7 additions & 0 deletions src/Types/BigIntType.php
Expand Up @@ -25,6 +25,13 @@ public function getBindingType(): ParameterType
return ParameterType::STRING;
}

/**
* @param T $value
*
* @return (T is null ? null : string)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?string
{
return $value === null ? null : (string) $value;
Expand Down
7 changes: 7 additions & 0 deletions src/Types/BooleanType.php
Expand Up @@ -25,6 +25,13 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
return $platform->convertBooleansToDatabaseValue($value);
}

/**
* @param T $value
*
* @return (T is null ? null : bool)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?bool
{
return $platform->convertFromBoolean($value);
Expand Down
14 changes: 14 additions & 0 deletions src/Types/DateImmutableType.php
Expand Up @@ -14,6 +14,13 @@
*/
class DateImmutableType extends DateType
{
/**
* @param T $value
*
* @return (T is null ? null : string)
*
* @template T
*/
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
{
if ($value === null) {
Expand All @@ -31,6 +38,13 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
);
}

/**
* @param T $value
*
* @return (T is null ? null : DateTimeImmutable)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTimeImmutable
{
if ($value === null || $value instanceof DateTimeImmutable) {
Expand Down
14 changes: 14 additions & 0 deletions src/Types/DateIntervalType.php
Expand Up @@ -29,6 +29,13 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform): st
return $platform->getStringTypeDeclarationSQL($column);
}

/**
* @param T $value
*
* @return (T is null ? null : string)
*
* @template T
*/
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
{
if ($value === null) {
Expand All @@ -42,6 +49,13 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
throw InvalidType::new($value, static::class, ['null', 'DateInterval']);
}

/**
* @param T $value
*
* @return (T is null ? null : DateInterval)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateInterval
{
if ($value === null || $value instanceof DateInterval) {
Expand Down
14 changes: 14 additions & 0 deletions src/Types/DateTimeImmutableType.php
Expand Up @@ -16,6 +16,13 @@
*/
class DateTimeImmutableType extends DateTimeType
{
/**
* @param T $value
*
* @return (T is null ? null : string)
*
* @template T
*/
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
{
if ($value === null) {
Expand All @@ -33,6 +40,13 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
);
}

/**
* @param T $value
*
* @return (T is null ? null : DateTimeImmutable)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTimeImmutable
{
if ($value === null || $value instanceof DateTimeImmutable) {
Expand Down
14 changes: 14 additions & 0 deletions src/Types/DateTimeType.php
Expand Up @@ -25,6 +25,13 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform): st
return $platform->getDateTimeTypeDeclarationSQL($column);
}

/**
* @param T $value
*
* @return (T is null ? null : string)
*
* @template T
*/
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
{
if ($value === null) {
Expand All @@ -38,6 +45,13 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
throw InvalidType::new($value, static::class, ['null', 'DateTime']);
}

/**
* @param T $value
*
* @return (T is null ? null : DateTimeInterface)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTimeInterface
{
if ($value === null || $value instanceof DateTimeInterface) {
Expand Down
14 changes: 14 additions & 0 deletions src/Types/DateTimeTzImmutableType.php
Expand Up @@ -14,6 +14,13 @@
*/
class DateTimeTzImmutableType extends DateTimeTzType
{
/**
* @psalm-param T $value
*
* @return (T is null ? null : string)
*
* @template T
*/
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
{
if ($value === null) {
Expand All @@ -31,6 +38,13 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
);
}

/**
* @param T $value
*
* @return (T is null ? null : DateTimeImmutable)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTimeImmutable
{
if ($value === null || $value instanceof DateTimeImmutable) {
Expand Down
14 changes: 14 additions & 0 deletions src/Types/DateTimeTzType.php
Expand Up @@ -36,6 +36,13 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform): st
return $platform->getDateTimeTzTypeDeclarationSQL($column);
}

/**
* @param T $value
*
* @return (T is null ? null : string)
*
* @template T
*/
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
{
if ($value === null) {
Expand All @@ -53,6 +60,13 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
);
}

/**
* @param T $value
*
* @return (T is null ? null : DateTimeInterface)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTimeInterface
{
if ($value === null || $value instanceof DateTimeInterface) {
Expand Down
14 changes: 14 additions & 0 deletions src/Types/DateType.php
Expand Up @@ -23,6 +23,13 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform): st
return $platform->getDateTypeDeclarationSQL($column);
}

/**
* @psalm-param T $value
*
* @return (T is null ? null : string)
*
* @template T
*/
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): mixed
{
if ($value === null) {
Expand All @@ -36,6 +43,13 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
throw InvalidType::new($value, static::class, ['null', 'DateTime']);
}

/**
* @param T $value
*
* @return (T is null ? null : DateTimeInterface)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTimeInterface
{
if ($value === null || $value instanceof DateTimeInterface) {
Expand Down
7 changes: 7 additions & 0 deletions src/Types/FloatType.php
Expand Up @@ -16,6 +16,13 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform): st
return $platform->getFloatDeclarationSQL($column);
}

/**
* @param T $value
*
* @return (T is null ? null : float)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?float
{
return $value === null ? null : (float) $value;
Expand Down
7 changes: 7 additions & 0 deletions src/Types/IntegerType.php
Expand Up @@ -20,6 +20,13 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform): st
return $platform->getIntegerTypeDeclarationSQL($column);
}

/**
* @param T $value
*
* @return (T is null ? null : int)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?int
{
return $value === null ? null : (int) $value;
Expand Down

0 comments on commit 5634ab4

Please sign in to comment.