Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Uid] Add MaxUuid and MaxUlid #47515

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 9, 2022
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
2 changes: 2 additions & 0 deletions .github/workflows/psalm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ jobs:
git checkout composer.json
git checkout -m ${{ github.base_ref }}

# to be removed when psalm adds support for intersection types
sed -i 's/Uuid&/Uuid|/' src/Symfony/Component/Uid/Factory/TimeBasedUuidFactory.php
./vendor/bin/psalm.phar --set-baseline=.github/psalm/psalm.baseline.xml --no-progress
git checkout -m FETCH_HEAD

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
use Symfony\Component\Uid\UuidV4;
use Symfony\Component\Uid\UuidV6;

/**
* @see UidController
*/
class UidTest extends AbstractWebTestCase
{
protected function setUp(): void
Expand All @@ -41,7 +38,7 @@ public function testArgumentValueResolverDisabled()
$exception = reset($exceptions);

$this->assertInstanceOf(\TypeError::class, $exception);
$this->assertStringContainsString('Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\UidController::anyFormat(): Argument #1 ($userId) must be of type Symfony\Component\Uid\UuidV1, string given', $exception->getMessage());
$this->assertStringContainsString(UidController::class.'::anyFormat(): Argument #1 ($userId) must be of type Symfony\Component\Uid\UuidV1, string given', $exception->getMessage());
}

public function testArgumentValueResolverEnabled()
Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Component/Uid/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ CHANGELOG
6.2
---

* Add `TimeBasedUidInterface` to `Ulid`, `UuidV1`, and `UuidV6` to describe that they present `getDateTime()` as an available method
* Add `TimeBasedUidInterface` to describe UIDs that embed a timestamp
* Add `MaxUuid` and `MaxUlid`

5.4
---
Expand Down
15 changes: 9 additions & 6 deletions src/Symfony/Component/Uid/Command/InspectUuidCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Uid\MaxUuid;
use Symfony\Component\Uid\NilUuid;
use Symfony\Component\Uid\TimeBasedUidInterface;
use Symfony\Component\Uid\Uuid;
use Symfony\Component\Uid\UuidV1;
use Symfony\Component\Uid\UuidV6;

#[AsCommand(name: 'uuid:inspect', description: 'Inspect a UUID')]
class InspectUuidCommand extends Command
Expand Down Expand Up @@ -56,10 +57,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return 1;
}

if (-1 === $version = uuid_type($uuid)) {
if (new NilUuid() == $uuid) {
$version = 'nil';
} elseif (0 === $version || 2 === $version || 6 < $version) {
$version = 'unknown';
} elseif (new MaxUuid() == $uuid) {
$version = 'max';
} else {
$version = uuid_type($uuid);
}

$rows = [
Expand All @@ -70,7 +73,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
['toHex', $uuid->toHex()],
];

if ($uuid instanceof UuidV1 || $uuid instanceof UuidV6) {
if ($uuid instanceof TimeBasedUidInterface) {
$rows[] = new TableSeparator();
$rows[] = ['Time', $uuid->getDateTime()->format('Y-m-d H:i:s.u \U\T\C')];
}
Expand Down
20 changes: 20 additions & 0 deletions src/Symfony/Component/Uid/MaxUlid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Uid;

class MaxUlid extends Ulid
{
public function __construct()
{
$this->uid = parent::MAX;
}
}
22 changes: 22 additions & 0 deletions src/Symfony/Component/Uid/MaxUuid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Uid;

class MaxUuid extends Uuid
{
protected const TYPE = -1;

public function __construct()
{
$this->uid = parent::MAX;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function testUnknown()
----------------------- --------------------------------------
Label Value
----------------------- --------------------------------------
Version unknown
Version 0
toRfc4122 (canonical) 461cc9b9-2397-0dba-91e9-33af4c63f7ec
toBase58 9f9nftX6dw4oVPm5uT17um
toBase32 263K4VJ8WQ1PX93T9KNX667XZC
Expand All @@ -71,7 +71,7 @@ public function testUnknown()
----------------------- --------------------------------------
Label Value
----------------------- --------------------------------------
Version unknown
Version 2
toRfc4122 (canonical) 461cc9b9-2397-2dba-91e9-33af4c63f7ec
toBase58 9f9nftX6fjLfNnvSAHMV7Z
toBase32 263K4VJ8WQ5PX93T9KNX667XZC
Expand All @@ -87,7 +87,7 @@ public function testUnknown()
----------------------- --------------------------------------
Label Value
----------------------- --------------------------------------
Version unknown
Version 7
toRfc4122 (canonical) 461cc9b9-2397-7dba-91e9-33af4c63f7ec
toBase58 9f9nftX6kE2K6HpooNEQ83
toBase32 263K4VJ8WQFPX93T9KNX667XZC
Expand All @@ -103,7 +103,7 @@ public function testUnknown()
----------------------- --------------------------------------
Label Value
----------------------- --------------------------------------
Version unknown
Version 12
toRfc4122 (canonical) 461cc9b9-2397-cdba-91e9-33af4c63f7ec
toBase58 9f9nftX6pihxonjBST7K8X
toBase32 263K4VJ8WQSPX93T9KNX667XZC
Expand Down
18 changes: 18 additions & 0 deletions src/Symfony/Component/Uid/Tests/UlidTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\Uid\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Uid\MaxUlid;
use Symfony\Component\Uid\NilUlid;
use Symfony\Component\Uid\Tests\Fixtures\CustomUlid;
use Symfony\Component\Uid\Ulid;
Expand Down Expand Up @@ -267,4 +268,21 @@ public function testNewNilUlid()
{
$this->assertSame('00000000000000000000000000', (string) new NilUlid());
}

/**
* @testWith ["ffffffff-ffff-ffff-ffff-ffffffffffff"]
* ["7zzzzzzzzzzzzzzzzzzzzzzzzz"]
*/
public function testMaxUlid(string $ulid)
{
$ulid = Ulid::fromString($ulid);

$this->assertInstanceOf(MaxUlid::class, $ulid);
$this->assertSame('7ZZZZZZZZZZZZZZZZZZZZZZZZZ', (string) $ulid);
}

public function testNewMaxUlid()
{
$this->assertSame('7ZZZZZZZZZZZZZZZZZZZZZZZZZ', (string) new MaxUlid());
}
}
18 changes: 18 additions & 0 deletions src/Symfony/Component/Uid/Tests/UuidTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\Uid\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Uid\MaxUuid;
use Symfony\Component\Uid\NilUuid;
use Symfony\Component\Uid\Tests\Fixtures\CustomUuid;
use Symfony\Component\Uid\Ulid;
Expand Down Expand Up @@ -238,6 +239,23 @@ public function testNewNilUuid()
$this->assertSame('00000000-0000-0000-0000-000000000000', (string) new NilUuid());
}

/**
* @testWith ["ffffffff-ffff-ffff-ffff-ffffffffffff"]
* ["7zzzzzzzzzzzzzzzzzzzzzzzzz"]
*/
public function testMaxUuid(string $uuid)
{
$uuid = Uuid::fromString($uuid);

$this->assertInstanceOf(MaxUuid::class, $uuid);
$this->assertSame('ffffffff-ffff-ffff-ffff-ffffffffffff', (string) $uuid);
}

public function testNewMaxUuid()
{
$this->assertSame('ffffffff-ffff-ffff-ffff-ffffffffffff', (string) new MaxUuid());
}

public function testFromBinary()
{
$this->assertEquals(
Expand Down
37 changes: 19 additions & 18 deletions src/Symfony/Component/Uid/Ulid.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
class Ulid extends AbstractUid implements TimeBasedUidInterface
{
protected const NIL = '00000000000000000000000000';
protected const MAX = '7ZZZZZZZZZZZZZZZZZZZZZZZZZ';

private static string $time = '';
private static array $rand = [];
Expand All @@ -29,21 +30,17 @@ public function __construct(string $ulid = null)
{
if (null === $ulid) {
$this->uid = static::generate();

return;
}

if (self::NIL === $ulid) {
} elseif (self::NIL === $ulid) {
$this->uid = $ulid;
} elseif (self::MAX === strtr($ulid, 'z', 'Z')) {
$this->uid = $ulid;
} else {
if (!self::isValid($ulid)) {
throw new \InvalidArgumentException(sprintf('Invalid ULID: "%s".', $ulid));
}

return;
}

if (!self::isValid($ulid)) {
throw new \InvalidArgumentException(sprintf('Invalid ULID: "%s".', $ulid));
$this->uid = strtoupper($ulid);
}

$this->uid = strtoupper($ulid);
}

public static function isValid(string $ulid): bool
Expand All @@ -68,11 +65,11 @@ public static function fromString(string $ulid): static
}

if (16 !== \strlen($ulid)) {
if (self::NIL === $ulid) {
return new NilUlid();
}

return new static($ulid);
return match (strtr($ulid, 'z', 'Z')) {
self::NIL => new NilUlid(),
self::MAX => new MaxUlid(),
default => new static($ulid),
};
}

$ulid = bin2hex($ulid);
Expand All @@ -90,8 +87,12 @@ public static function fromString(string $ulid): static
return new NilUlid();
}

if (self::MAX === $ulid = strtr($ulid, 'abcdefghijklmnopqrstuv', 'ABCDEFGHJKMNPQRSTVWXYZ')) {
return new MaxUlid();
}

$u = new static(self::NIL);
$u->uid = strtr($ulid, 'abcdefghijklmnopqrstuv', 'ABCDEFGHJKMNPQRSTVWXYZ');
$u->uid = $ulid;

return $u;
}
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Uid/Uuid.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Uuid extends AbstractUid

protected const TYPE = 0;
protected const NIL = '00000000-0000-0000-0000-000000000000';
protected const MAX = 'ffffffff-ffff-ffff-ffff-ffffffffffff';

public function __construct(string $uuid, bool $checkVariant = false)
{
Expand Down Expand Up @@ -68,6 +69,10 @@ public static function fromString(string $uuid): static
return new NilUuid();
}

if (self::MAX === $uuid = strtr($uuid, 'F', 'f')) {
return new MaxUuid();
}

if (!\in_array($uuid[19], ['8', '9', 'a', 'b', 'A', 'B'], true)) {
return new self($uuid);
}
Expand Down