doctrine-ulid/src/Types/UlidType.php
lubiana eb40f1df49
All checks were successful
/ ls (push) Successful in 20s
add tests
2024-06-02 11:20:20 +02:00

101 lines
2.7 KiB
PHP

<?php declare(strict_types=1);
namespace Lubiana\DoctrineUlid\Types;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Exception\InvalidType;
use Doctrine\DBAL\Types\Exception\ValueNotConvertible;
use Doctrine\DBAL\Types\Type;
use InvalidArgumentException;
use Override;
use Symfony\Component\Uid\Ulid;
use function is_string;
final class UlidType extends Type
{
public const NAME = 'ulid';
#[Override]
public function getSQLDeclaration(
array $column,
AbstractPlatform $platform,
): string {
if ($this->hasNativeGuidType($platform)) {
return $platform->getGuidTypeDeclarationSQL($column);
}
return $platform->getBinaryTypeDeclarationSQL([
'length' => 16,
'fixed' => true,
]);
}
#[Override]
public function convertToPHPValue(
mixed $value,
AbstractPlatform $platform,
): Ulid|null {
if ($value instanceof Ulid || $value === null) {
return $value;
}
if (! is_string($value)) {
throw InvalidType::new($value, self::NAME, ['null', 'string', self::class]);
}
try {
return Ulid::fromString($value);
} catch (InvalidArgumentException $e) {
throw ValueNotConvertible::new($value, self::NAME, null, $e);
}
}
#[Override]
public function convertToDatabaseValue(
mixed $value,
AbstractPlatform $platform,
): string|null {
$toStringFunc = static fn(Ulid $v): string => $v->toRfc4122();
if (! $this->hasNativeGuidType($platform)) {
$toStringFunc = static fn(Ulid $v): string => $v->toBinary();
}
if ($value instanceof Ulid) {
return $toStringFunc($value);
}
if ($value === null || $value === '') {
return null;
}
if (! is_string($value)) {
throw InvalidType::new($value, self::NAME, ['null', 'string', self::class]);
}
try {
return $toStringFunc(Ulid::fromString($value));
} catch (InvalidArgumentException $e) {
throw ValueNotConvertible::new($value, self::NAME, null, $e);
}
}
private function hasNativeGuidType(AbstractPlatform $platform): bool
{
return $platform->getGuidTypeDeclarationSQL([]) !== $platform->getStringTypeDeclarationSQL([
'fixed' => true,
'length' => 36,
]);
}
public static function register(): void
{
if (Type::hasType(self::NAME)) {
Type::overrideType(self::NAME, self::class);
return;
}
Type::addType(self::NAME, self::class);
}
}