Skip to content

Commit

Permalink
Stricter DateTime types (#6161)
Browse files Browse the repository at this point in the history
  • Loading branch information
derrabus authored Sep 22, 2023
1 parent c41e4db commit c031ad0
Show file tree
Hide file tree
Showing 15 changed files with 108 additions and 155 deletions.
19 changes: 19 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,25 @@ awareness about deprecated code.

# Upgrade to 4.0

## BC BREAK: Stricter `DateTime` types

The following types don't accept or return `DateTimeImmutable` instances anymore:

* `DateTimeType`
* `DateTimeTzType`
* `DateType`
* `TimeType`
* `VarDateTimeType`

As a consequence, the following type classes don't extend their mutable
counterparts anymore:

* `DateTimeImmutableType`
* `DateTimeTzImmutableType`
* `DateImmutableType`
* `TimeImmutableType`
* `VarDateTimeImmutableType`

## BC BREAK: Remove legacy execute and fetch methods.

The following methods have been removed:
Expand Down
4 changes: 2 additions & 2 deletions src/Platforms/AbstractPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -1463,11 +1463,11 @@ public function getDefaultValueDeclarationSQL(array $column): string
return ' DEFAULT ' . $this->getCurrentTimestampSQL();
}

if ($type instanceof Types\TimeType && $default === $this->getCurrentTimeSQL()) {
if ($type instanceof Types\PhpTimeMappingType && $default === $this->getCurrentTimeSQL()) {
return ' DEFAULT ' . $this->getCurrentTimeSQL();
}

if ($type instanceof Types\DateType && $default === $this->getCurrentDateSQL()) {
if ($type instanceof Types\PhpDateMappingType && $default === $this->getCurrentDateSQL()) {
return ' DEFAULT ' . $this->getCurrentDateSQL();
}

Expand Down
10 changes: 9 additions & 1 deletion src/Types/DateImmutableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,16 @@
/**
* Immutable type of {@see DateType}.
*/
class DateImmutableType extends DateType
class DateImmutableType extends Type implements PhpDateMappingType
{
/**
* {@inheritDoc}
*/
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
return $platform->getDateTypeDeclarationSQL($column);
}

/**
* @param T $value
*
Expand Down
10 changes: 9 additions & 1 deletion src/Types/DateTimeImmutableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,16 @@
/**
* Immutable type of {@see DateTimeType}.
*/
class DateTimeImmutableType extends DateTimeType
class DateTimeImmutableType extends Type implements PhpDateTimeMappingType
{
/**
* {@inheritDoc}
*/
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
return $platform->getDateTimeTypeDeclarationSQL($column);
}

/**
* @param T $value
*
Expand Down
35 changes: 5 additions & 30 deletions src/Types/DateTimeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@
namespace Doctrine\DBAL\Types;

use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Exception\InvalidFormat;
use Doctrine\DBAL\Types\Exception\InvalidType;
use Doctrine\Deprecations\Deprecation;
use Exception;

/**
Expand Down Expand Up @@ -39,49 +36,27 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
return $value;
}

if ($value instanceof DateTimeImmutable) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated, use %s::%s() instead.',
$value::class,
DateTimeImmutableType::class,
__FUNCTION__,
);
}

if ($value instanceof DateTimeInterface) {
if ($value instanceof DateTime) {
return $value->format($platform->getDateTimeFormatString());
}

throw InvalidType::new(
$value,
static::class,
['null', DateTime::class, DateTimeImmutable::class],
['null', DateTime::class],
);
}

/**
* @param T $value
*
* @return (T is null ? null : DateTimeInterface)
* @return (T is null ? null : DateTime)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTimeInterface
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTime
{
if ($value instanceof DateTimeImmutable) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated, use %s::%s() instead.',
$value::class,
DateTimeImmutableType::class,
__FUNCTION__,
);
}

if ($value === null || $value instanceof DateTimeInterface) {
if ($value === null || $value instanceof DateTime) {
return $value;
}

Expand Down
10 changes: 9 additions & 1 deletion src/Types/DateTimeTzImmutableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,16 @@
/**
* Immutable type of {@see DateTimeTzType}.
*/
class DateTimeTzImmutableType extends DateTimeTzType
class DateTimeTzImmutableType extends Type implements PhpDateTimeMappingType
{
/**
* {@inheritDoc}
*/
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
return $platform->getDateTimeTzTypeDeclarationSQL($column);
}

/**
* @psalm-param T $value
*
Expand Down
33 changes: 4 additions & 29 deletions src/Types/DateTimeTzType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@
namespace Doctrine\DBAL\Types;

use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Exception\InvalidFormat;
use Doctrine\DBAL\Types\Exception\InvalidType;
use Doctrine\Deprecations\Deprecation;

/**
* DateTime type saving additional timezone information.
Expand Down Expand Up @@ -51,18 +48,7 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
return $value;
}

if ($value instanceof DateTimeImmutable) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated, use %s::%s() instead.',
$value::class,
DateTimeTzImmutableType::class,
__FUNCTION__,
);
}

if ($value instanceof DateTimeInterface) {
if ($value instanceof DateTime) {
return $value->format($platform->getDateTimeTzFormatString());
}

Expand All @@ -76,24 +62,13 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
/**
* @param T $value
*
* @return (T is null ? null : DateTimeInterface)
* @return (T is null ? null : DateTime)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTimeInterface
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTime
{
if ($value instanceof DateTimeImmutable) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated, use %s::%s() instead.',
$value::class,
DateTimeTzImmutableType::class,
__FUNCTION__,
);
}

if ($value === null || $value instanceof DateTimeInterface) {
if ($value === null || $value instanceof DateTime) {
return $value;
}

Expand Down
35 changes: 5 additions & 30 deletions src/Types/DateType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@
namespace Doctrine\DBAL\Types;

use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Exception\InvalidFormat;
use Doctrine\DBAL\Types\Exception\InvalidType;
use Doctrine\Deprecations\Deprecation;

/**
* Type that maps an SQL DATE to a PHP Date object.
*/
class DateType extends Type
class DateType extends Type implements PhpDateMappingType
{
/**
* {@inheritDoc}
Expand All @@ -38,18 +35,7 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
return $value;
}

if ($value instanceof DateTimeInterface) {
if ($value instanceof DateTimeImmutable) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated, use %s::%s() instead.',
$value::class,
DateImmutableType::class,
__FUNCTION__,
);
}

if ($value instanceof DateTime) {
return $value->format($platform->getDateFormatString());
}

Expand All @@ -59,24 +45,13 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform)
/**
* @param T $value
*
* @return (T is null ? null : DateTimeInterface)
* @return (T is null ? null : DateTime)
*
* @template T
*/
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTimeInterface
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTime
{
if ($value instanceof DateTimeImmutable) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated, use %s::%s() instead.',
$value::class,
DateImmutableType::class,
__FUNCTION__,
);
}

if ($value === null || $value instanceof DateTimeInterface) {
if ($value === null || $value instanceof DateTime) {
return $value;
}

Expand Down
14 changes: 14 additions & 0 deletions src/Types/PhpDateMappingType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Types;

/**
* Implementations should map a database type to a PHP DateTimeInterface instance.
*
* @internal
*/
interface PhpDateMappingType
{
}
14 changes: 14 additions & 0 deletions src/Types/PhpTimeMappingType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Types;

/**
* Implementations should map a database type to a PHP DateTimeInterface instance.
*
* @internal
*/
interface PhpTimeMappingType
{
}
10 changes: 9 additions & 1 deletion src/Types/TimeImmutableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,16 @@
/**
* Immutable type of {@see TimeType}.
*/
class TimeImmutableType extends TimeType
class TimeImmutableType extends Type implements PhpTimeMappingType
{
/**
* {@inheritDoc}
*/
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
return $platform->getTimeTypeDeclarationSQL($column);
}

/**
* @param T $value
*
Expand Down
Loading

0 comments on commit c031ad0

Please sign in to comment.