Support symfony UUID (#2826)

* Add new type for Symfony UUIDs

* Add UUID type to type class

* Don't transform PHP UUIDs again

* Support generating Symfony UUID objects in AUTO generator

* Deprecate string-based UUID generator

* Add documentation around UUIDs

* Apply Copilot review feedback

* Unify logic in binary uuid type

* Apply code review feedback

* Undo type conditional change to fix errors

* Add documentation around UUID generator deprecation

* Link to Symfony UID component

* Explain deprecation of UUID generator in docs

* Simplify ID generator docblocks

* Fix ObjectId check when using auto generation

* Use InvalidArgumentException in type
This commit is contained in:
Andreas Braun
2025-09-24 16:41:58 +02:00
committed by GitHub
parent 2a9118a626
commit c813a57540
17 changed files with 428 additions and 25 deletions

View File

@@ -14,6 +14,11 @@ The `Doctrine\ODM\MongoDB\Id\AbstractIdGenerator` class has been removed. Custom
ID generators must implement the `Doctrine\ODM\MongoDB\Id\IdGenerator`
interface.
The `Doctrine\ODM\MongoDB\Id\UuidGenerator` class has been removed. Use a custom
generator to generate string UUIDs. For more efficient storage of UUIDs, use the
`Doctrine\ODM\MongoDB\Types\BinaryUuidType` type in combination with the
`Doctrine\ODM\MongoDB\Id\SymfonyUuidGenerator` generator.
## Metadata
The `Doctrine\ODM\MongoDB\Mapping\ClassMetadata` class has been marked final and
will no longer be extendable.

View File

@@ -49,7 +49,8 @@
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^10.4",
"squizlabs/php_codesniffer": "^3.5",
"symfony/cache": "^5.4 || ^6.0 || ^7.0"
"symfony/cache": "^5.4 || ^6.0 || ^7.0",
"symfony/uid": "^5.4 || ^6.0 || ^7.0"
},
"conflict": {
"doctrine/annotations": "<1.12 || >=3.0"

View File

@@ -151,6 +151,7 @@ Here is a quick overview of the built-in mapping types:
- ``raw``
- ``string``
- ``timestamp``
- ``uuid``
You can read more about the available MongoDB types on `php.net <https://www.php.net/mongodb.bson>`_.
@@ -178,6 +179,7 @@ This list explains some of the less obvious mapping types:
- ``id``: string to ObjectId by default, but other formats are possible
- ``timestamp``: string to ``MongoDB\BSON\Timestamp``
- ``raw``: any type
- ``uuid``: `Symfony UID <https://symfony.com/doc/current/components/uid.html>`_ to ``MongoDB\BSON\Binary`` instance with a "uuid" type
.. note::
@@ -206,6 +208,7 @@ follows:
- ``float``: ``float``
- ``int``: ``int``
- ``string``: ``string``
- ``Symfony\Component\Uid\Uuid``: ``uuid``
Doctrine can also autoconfigure any backed ``enum`` it encounters: ``type``
will be set to ``string`` or ``int``, depending on the enum's backing type,
@@ -269,13 +272,23 @@ Here is an example:
You can configure custom ID strategies if you don't want to use the default
object ID. The available strategies are:
- ``AUTO`` - Uses the native generated ObjectId.
- ``AUTO`` - Automatically generates an ObjectId or Symfony UUID depending on the identifier type.
- ``ALNUM`` - Generates an alpha-numeric string (based on an incrementing value).
- ``CUSTOM`` - Defers generation to an implementation of ``IdGenerator`` specified in the ``class`` option.
- ``INCREMENT`` - Uses another collection to auto increment an integer identifier.
- ``UUID`` - Generates a UUID identifier.
- ``UUID`` - Generates a UUID identifier (deprecated).
- ``NONE`` - Do not generate any identifier. ID must be manually set.
When using the ``AUTO`` strategy in combination with a UUID identifier, the generator can create UUIDs of type 1, type 4,
and type 7 automatically. For all other UUID types, assign the identifier manually in combination with the ``NONE``
strategy.
.. note::
The ``UUID`` generator is deprecated, as it stores UUIDs as strings. It is recommended to use the ``AUTO`` strategy
with a ``uuid`` type identifier field instead. If you need to keep generating string UUIDs, you can use the
``CUSTOM`` strategy with your own generator.
Here is an example how to manually set a string identifier for your documents:
.. configuration-block::

View File

@@ -9,6 +9,8 @@ use MongoDB\BSON\ObjectId;
/**
* AutoGenerator generates a native ObjectId
*
* @deprecated use ObjectIdGenerator instead
*/
final class AutoGenerator extends AbstractIdGenerator
{

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace Doctrine\ODM\MongoDB\Id;
use Doctrine\ODM\MongoDB\DocumentManager;
use MongoDB\BSON\ObjectId;
/** @internal */
final class ObjectIdGenerator extends AbstractIdGenerator
{
public function generate(DocumentManager $dm, object $document): ObjectId
{
return new ObjectId();
}
}

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Doctrine\ODM\MongoDB\Id;
use Doctrine\ODM\MongoDB\DocumentManager;
use InvalidArgumentException;
use Symfony\Component\Uid\Uuid;
use Symfony\Component\Uid\UuidV1;
use Symfony\Component\Uid\UuidV4;
use Symfony\Component\Uid\UuidV7;
use function array_values;
use function implode;
use function in_array;
use function sprintf;
/** @internal */
final class SymfonyUuidGenerator extends AbstractIdGenerator
{
private const SUPPORTED_TYPES = [
1 => UuidV1::class,
4 => UuidV4::class,
7 => UuidV7::class,
];
public function __construct(private readonly string $class)
{
if (! in_array($this->class, self::SUPPORTED_TYPES, true)) {
throw new InvalidArgumentException(sprintf('Invalid UUID type "%s". Expected one of: %s.', $this->class, implode(', ', array_values(self::SUPPORTED_TYPES))));
}
}
public function generate(DocumentManager $dm, object $document): Uuid
{
return new $this->class();
}
}

View File

@@ -18,9 +18,7 @@ use function str_replace;
use function strlen;
use function substr;
/**
* Generates UUIDs.
*/
/** @deprecated without replacement. Use a custom generator or switch to binary UUIDs. */
final class UuidGenerator extends AbstractIdGenerator
{
/**

View File

@@ -34,6 +34,9 @@ use ReflectionClass;
use ReflectionEnum;
use ReflectionNamedType;
use ReflectionProperty;
use Symfony\Component\Uid\UuidV1;
use Symfony\Component\Uid\UuidV4;
use Symfony\Component\Uid\UuidV7;
use function array_column;
use function array_filter;
@@ -300,6 +303,8 @@ use function trigger_deprecation;
/**
* UUID means Doctrine will generate a uuid for us.
*
* @deprecated without replacement. Use a custom generator or switch to binary UUIDs.
*/
public const GENERATOR_TYPE_UUID = 3;
@@ -942,6 +947,16 @@ use function trigger_deprecation;
return [$this->identifier];
}
/**
* Gets the mapping of the identifier field
*
* @phpstan-return FieldMapping
*/
public function getIdentifierMapping(): array
{
return $this->fieldMappings[$this->identifier];
}
/**
* Since MongoDB only allows exactly one identifier field
* this will always return an array with only one value
@@ -2391,22 +2406,18 @@ use function trigger_deprecation;
}
$this->generatorOptions = $mapping['options'] ?? [];
switch ($this->generatorType) {
case self::GENERATOR_TYPE_AUTO:
$mapping['type'] = 'id';
break;
default:
if (! empty($this->generatorOptions['type'])) {
$mapping['type'] = (string) $this->generatorOptions['type'];
} elseif (empty($mapping['type'])) {
$mapping['type'] = $this->generatorType === self::GENERATOR_TYPE_INCREMENT ? Type::INT : Type::CUSTOMID;
}
if ($this->generatorType !== self::GENERATOR_TYPE_AUTO) {
if (! empty($this->generatorOptions['type'])) {
$mapping['type'] = (string) $this->generatorOptions['type'];
} elseif (empty($mapping['type'])) {
$mapping['type'] = $this->generatorType === self::GENERATOR_TYPE_INCREMENT ? Type::INT : Type::CUSTOMID;
}
} elseif ($mapping['type'] !== Type::UUID) {
$mapping['type'] = Type::ID;
}
unset($this->generatorOptions['type']);
}
if (! isset($mapping['type'])) {
} elseif (! isset($mapping['type'])) {
// Default to string
$mapping['type'] = Type::STRING;
}
@@ -2798,6 +2809,11 @@ use function trigger_deprecation;
}
switch ($type->getName()) {
case UuidV1::class:
case UuidV4::class:
case UuidV7::class:
$mapping['type'] = Type::UUID;
break;
case DateTime::class:
$mapping['type'] = Type::DATE;
break;

View File

@@ -12,15 +12,17 @@ use Doctrine\ODM\MongoDB\Event\LoadClassMetadataEventArgs;
use Doctrine\ODM\MongoDB\Event\OnClassMetadataNotFoundEventArgs;
use Doctrine\ODM\MongoDB\Events;
use Doctrine\ODM\MongoDB\Id\AlnumGenerator;
use Doctrine\ODM\MongoDB\Id\AutoGenerator;
use Doctrine\ODM\MongoDB\Id\IdGenerator;
use Doctrine\ODM\MongoDB\Id\IncrementGenerator;
use Doctrine\ODM\MongoDB\Id\ObjectIdGenerator;
use Doctrine\ODM\MongoDB\Id\SymfonyUuidGenerator;
use Doctrine\ODM\MongoDB\Id\UuidGenerator;
use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory;
use Doctrine\Persistence\Mapping\ClassMetadata as ClassMetadataInterface;
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\Persistence\Mapping\ReflectionService;
use ReflectionException;
use ReflectionNamedType;
use function assert;
use function get_class_methods;
@@ -186,7 +188,7 @@ final class ClassMetadataFactory extends AbstractClassMetadataFactory implements
if ($parent->idGenerator) {
$class->setIdGenerator($parent->idGenerator);
}
} else {
} elseif ($class->identifier) {
$this->completeIdGeneratorMapping($class);
}
@@ -230,12 +232,36 @@ final class ClassMetadataFactory extends AbstractClassMetadataFactory implements
return new ClassMetadata($className);
}
private function generateAutoIdGenerator(ClassMetadata $class): void
{
$identifierMapping = $class->getIdentifierMapping();
switch ($identifierMapping['type']) {
case 'id':
case 'objectId':
$class->setIdGenerator(new ObjectIdGenerator());
break;
case 'uuid':
$reflectionProperty = $class->getReflectionProperty($identifierMapping['fieldName']);
if (! $reflectionProperty->getType() instanceof ReflectionNamedType) {
throw MappingException::autoIdGeneratorNeedsType($class->name, $identifierMapping['fieldName']);
}
$class->setIdGenerator(new SymfonyUuidGenerator($reflectionProperty->getType()->getName()));
break;
default:
throw MappingException::unsupportedTypeForAutoGenerator(
$class->name,
$identifierMapping['type'],
);
}
}
private function completeIdGeneratorMapping(ClassMetadata $class): void
{
$idGenOptions = $class->generatorOptions;
switch ($class->generatorType) {
case ClassMetadata::GENERATOR_TYPE_AUTO:
$class->setIdGenerator(new AutoGenerator());
$this->generateAutoIdGenerator($class);
break;
case ClassMetadata::GENERATOR_TYPE_INCREMENT:
$incrementGenerator = new IncrementGenerator();

View File

@@ -319,4 +319,22 @@ final class MappingException extends BaseMappingException
$className,
));
}
public static function unsupportedTypeForAutoGenerator(string $className, string $type): self
{
return new self(sprintf(
'The type "%s" can not be used for auto ID generation in class "%s".',
$type,
$className,
));
}
public static function autoIdGeneratorNeedsType(string $className, string $identifierFieldName): self
{
return new self(sprintf(
'The auto ID generator for class "%s" requires the identifier field "%s" to have a type.',
$className,
$identifierFieldName,
));
}
}

View File

@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace Doctrine\ODM\MongoDB\Types;
use InvalidArgumentException;
use MongoDB\BSON\Binary;
use Symfony\Component\Uid\Uuid;
use function get_debug_type;
use function is_string;
use function sprintf;
class BinaryUuidType extends Type
{
public function convertToDatabaseValue(mixed $value): ?Binary
{
return match (true) {
$value === null => null,
$value instanceof Binary => $value,
$value instanceof Uuid => new Binary($value->toBinary(), Binary::TYPE_UUID),
is_string($value) => new Binary(Uuid::fromString($value)->toBinary(), Binary::TYPE_UUID),
default => throw new InvalidArgumentException(sprintf('Invalid data type %s received for UUID', get_debug_type($value))),
};
}
public function convertToPHPValue(mixed $value): Uuid
{
if ($value instanceof Uuid) {
return $value;
}
if (! $value instanceof Binary) {
throw new InvalidArgumentException(sprintf('Invalid data of type "%s" received for Uuid', get_debug_type($value)));
}
if ($value->getType() !== Binary::TYPE_UUID) {
throw new InvalidArgumentException(sprintf('Invalid binary data of type %d received for Uuid', $value->getType()));
}
return Uuid::fromBinary($value->getData());
}
public function closureToMongo(): string
{
return <<<'PHP'
$return = match (true) {
$value === null => null,
$value instanceof \MongoDB\BSON\Binary => $value,
$value instanceof \Symfony\Component\Uid\Uuid => new \MongoDB\BSON\Binary($value->toBinary(), \MongoDB\BSON\Binary::TYPE_UUID),
is_string($value) => new \MongoDB\BSON\Binary(\Symfony\Component\Uid\Uuid::fromString($value)->toBinary(), \MongoDB\BSON\Binary::TYPE_UUID),
default => throw new \InvalidArgumentException(sprintf('Invalid data type %s received for UUID', get_debug_type($value))),
};
PHP;
}
public function closureToPHP(): string
{
return <<<'PHP'
if ($value instanceof \Symfony\Component\Uid\Uuid) {
$return = $value;
return;
}
if (! $value instanceof \MongoDB\BSON\Binary) {
throw new \InvalidArgumentException(sprintf('Invalid data of type "%s" received for Uuid', get_debug_type($value)));
}
if ($value->getType() !== \MongoDB\BSON\Binary::TYPE_UUID) {
throw new \InvalidArgumentException(sprintf('Invalid binary data of type %d received for Uuid', $value->getType()));
}
$return = \Symfony\Component\Uid\Uuid::fromBinary($value->getData());
PHP;
}
}

View File

@@ -9,6 +9,7 @@ use Doctrine\ODM\MongoDB\Mapping\MappingException;
use Doctrine\ODM\MongoDB\Types;
use InvalidArgumentException;
use MongoDB\BSON\ObjectId;
use Symfony\Component\Uid\Uuid;
use function end;
use function explode;
@@ -45,6 +46,7 @@ abstract class Type
public const OBJECTID = 'object_id';
public const RAW = 'raw';
public const DECIMAL128 = 'decimal128';
public const UUID = 'uuid';
/** @deprecated const was deprecated in doctrine/mongodb-odm 2.1 and will be removed in 3.0. Use Type::INT instead */
public const INTID = 'int_id';
@@ -86,6 +88,7 @@ abstract class Type
self::OBJECTID => Types\ObjectIdType::class,
self::RAW => Types\RawType::class,
self::DECIMAL128 => Types\Decimal128Type::class,
self::UUID => Types\BinaryUuidType::class,
];
/** Prevent instantiation and force use of the factory method. */
@@ -167,11 +170,15 @@ abstract class Type
{
if (is_object($variable)) {
if ($variable instanceof DateTimeInterface) {
return self::getType('date');
return self::getType(self::DATE);
}
if ($variable instanceof ObjectId) {
return self::getType('id');
return self::getType(self::ID);
}
if ($variable instanceof Uuid) {
return self::getType(self::UUID);
}
} else {
$type = gettype($variable);

View File

@@ -1139,7 +1139,7 @@ final class UnitOfWork implements PropertyChangedListener
));
}
if ($class->generatorType === ClassMetadata::GENERATOR_TYPE_AUTO && $idValue !== null && ! preg_match('#^[0-9a-f]{24}$#', (string) $idValue)) {
if ($class->getIdentifierMapping()['type'] === Type::ID && $idValue !== null && $class->generatorType === ClassMetadata::GENERATOR_TYPE_AUTO && ! preg_match('#^[0-9a-f]{24}$#', (string) $idValue)) {
throw new InvalidArgumentException(sprintf(
'%s uses AUTO identifier generation strategy but provided identifier is not a valid ObjectId.',
$document::class,

View File

@@ -882,6 +882,12 @@ parameters:
count: 1
path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataFactory.php
-
message: '#^Method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadataFactory\:\:generateAutoIdGenerator\(\) has parameter \$class with generic class Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata but does not specify its types\: T$#'
identifier: missingType.generics
count: 1
path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataFactory.php
-
message: '#^Method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadataFactory\:\:initializeReflection\(\) has parameter \$class with generic class Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata but does not specify its types\: T$#'
identifier: missingType.generics
@@ -2106,6 +2112,18 @@ parameters:
count: 1
path: tests/Doctrine/ODM/MongoDB/Tests/Tools/ResolveTargetDocumentListenerTest.php
-
message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertSame\(\) with arguments MongoDB\\BSON\\Binary, null and ''Binary UUIDs are…'' will always evaluate to false\.$#'
identifier: staticMethod.impossibleType
count: 1
path: tests/Doctrine/ODM/MongoDB/Tests/Types/BinaryUuidTypeTest.php
-
message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertSame\(\) with arguments Symfony\\Component\\Uid\\UuidV4, null and ''Uuid objects are…'' will always evaluate to false\.$#'
identifier: staticMethod.impossibleType
count: 1
path: tests/Doctrine/ODM/MongoDB/Tests/Types/BinaryUuidTypeTest.php
-
message: '#^Property Doctrine\\ODM\\MongoDB\\Tests\\ArrayTest\:\:\$id is unused\.$#'
identifier: property.unused

View File

@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace Doctrine\ODM\MongoDB\Tests\Functional;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Doctrine\ODM\MongoDB\Tests\BaseTestCase;
use Doctrine\ODM\MongoDB\Types\Type;
use Symfony\Component\Uid\UuidV4;
class UuidMappingTest extends BaseTestCase
{
public function testIdHasUuidType(): void
{
$metadata = $this->dm->getClassMetadata(UuidTestDocument::class);
$idMapping = $metadata->getIdentifierMapping();
self::assertSame(Type::UUID, $idMapping['type'], 'Id field should have UUID type');
}
public function testExplicitValue(): void
{
$uuid = new UuidV4();
$document = new UuidTestDocument();
$document->id = $uuid;
$document->explicitlyTypedUuid = $uuid;
$document->untypedUuid = $uuid;
$this->dm->persist($document);
$this->dm->flush();
$check = $this->dm->find(UuidTestDocument::class, $document->id);
self::assertInstanceOf(UuidTestDocument::class, $check);
self::assertEquals($uuid, $check->id);
self::assertEquals($uuid, $check->explicitlyTypedUuid);
self::assertEquals($uuid, $check->untypedUuid);
}
public function testAutoGenerateIdV4(): void
{
$document = new UuidTestDocument();
$this->dm->persist($document);
$this->dm->flush();
$check = $this->dm->find(UuidTestDocument::class, $document->id);
self::assertInstanceOf(UuidTestDocument::class, $check);
self::assertInstanceOf(UuidV4::class, $check->id);
}
}
#[ODM\Document]
class UuidTestDocument
{
#[ODM\Id]
public UuidV4 $id;
#[ODM\Field(type: Type::UUID)]
public ?UuidV4 $explicitlyTypedUuid = null;
#[ODM\Field]
public ?UuidV4 $untypedUuid = null;
}

View File

@@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
namespace Doctrine\ODM\MongoDB\Tests\Types;
use Doctrine\ODM\MongoDB\Types\Type;
use InvalidArgumentException;
use MongoDB\BSON\Binary;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Uid\UuidV4;
use Throwable;
class BinaryUuidTypeTest extends TestCase
{
public function testConvertToDatabaseValue(): void
{
$type = Type::getType(Type::UUID);
$uuid = new UuidV4();
$stringUuid = $uuid->toRfc4122();
$binaryUuid = new Binary($uuid->toBinary(), Binary::TYPE_UUID);
self::assertNull($type->convertToDatabaseValue(null), 'null is not converted');
self::assertEquals($binaryUuid, $type->convertToDatabaseValue($uuid), 'Uuid objects are converted to Binary objects');
self::assertEquals($binaryUuid, $type->convertToDatabaseValue($stringUuid), 'String UUIDs are converted to Binary objects');
self::assertSame($binaryUuid, $type->convertToDatabaseValue($binaryUuid), 'Binary UUIDs are returned as is');
}
public function testConvertInvalidUuid(): void
{
$type = Type::getType(Type::UUID);
$this->expectException(InvalidArgumentException::class);
$type->convertToDatabaseValue('invalid');
}
public function testConvertToPHPValue(): void
{
$type = Type::getType(Type::UUID);
$uuid = new UuidV4();
$binaryUuid = new Binary($uuid->toBinary(), Binary::TYPE_UUID);
self::assertEquals($uuid, $type->convertToPHPValue($binaryUuid), 'Binary UUIDs are converted to Uuid objects');
self::assertSame($uuid, $type->convertToPHPValue($uuid), 'Uuid objects are returned as is');
}
public function testConvertInvalidBinaryUuid(): void
{
$type = Type::getType(Type::UUID);
$this->expectException(InvalidArgumentException::class);
$type->convertToPHPValue(new Binary('invalid', Binary::TYPE_UUID));
}
public function testConvertInvalidBinary(): void
{
$type = Type::getType(Type::UUID);
$this->expectException(Throwable::class);
$type->convertToPHPValue(new Binary('invalid', Binary::TYPE_GENERIC));
}
public function testClosureToMongo(): void
{
$type = Type::getType(Type::UUID);
$uuid = new UuidV4();
$stringUuid = $uuid->toRfc4122();
$binaryUuid = new Binary($uuid->toBinary(), Binary::TYPE_UUID);
$convertToDatabaseValue = static function ($value) use ($type) {
$return = null;
eval($type->closureToMongo());
return $return;
};
self::assertNull($convertToDatabaseValue(null), 'null is not converted');
self::assertEquals($binaryUuid, $convertToDatabaseValue($uuid), 'Uuid objects are converted to Binary objects');
self::assertEquals($binaryUuid, $convertToDatabaseValue($stringUuid), 'String UUIDs are converted to Binary objects');
self::assertSame($binaryUuid, $convertToDatabaseValue($binaryUuid), 'Binary UUIDs are returned as is');
}
public function testClosureToPhp(): void
{
$type = Type::getType(Type::UUID);
$uuid = new UuidV4();
$binaryUuid = new Binary($uuid->toBinary(), Binary::TYPE_UUID);
$convertToPHPValue = static function ($value) use ($type) {
$return = null;
eval($type->closureToPHP());
return $return;
};
self::assertEquals($uuid, $convertToPHPValue($binaryUuid), 'Binary UUIDs are converted to Uuid objects');
self::assertSame($uuid, $convertToPHPValue($uuid), 'Uuid objects are returned as is');
}
}

View File

@@ -17,8 +17,10 @@ use MongoDB\BSON\ObjectId;
use MongoDB\BSON\Timestamp;
use MongoDB\BSON\UTCDateTime;
use PHPUnit\Framework\Attributes\DataProvider;
use Symfony\Component\Uid\UuidV4;
use function get_debug_type;
use function hex2bin;
use function md5;
use function str_pad;
use function str_repeat;
@@ -66,6 +68,7 @@ class TypeTest extends BaseTestCase
'objectId' => [Type::OBJECTID, '507f1f77bcf86cd799439011', new ObjectId('507f1f77bcf86cd799439011')],
'raw' => [Type::RAW, (object) ['foo' => 'bar']],
'decimal128' => [Type::DECIMAL128, '4.20', new Decimal128('4.20')],
'uuid' => [Type::UUID, new UuidV4('550e8400-e29b-41d4-a716-446655440000'), new Binary(hex2bin('550e8400e29b41d4a716446655440000'), Binary::TYPE_UUID)],
];
}