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

Skip to content

Commit c991df6

Browse files
feature #47515 [Uid] Add MaxUuid and MaxUlid (nicolas-grekas)
This PR was merged into the 6.2 branch. Discussion ---------- [Uid] Add MaxUuid and MaxUlid | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | no | New feature? | no | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - As described for UUIDs in https://datatracker.ietf.org/doc/draft-peabody-dispatch-new-uuid-format/ Commits ------- 7ee57e9 [Uid] Add MaxUuid and MaxUlid
2 parents 25f4de0 + 7ee57e9 commit c991df6

File tree

11 files changed

+120
-33
lines changed

11 files changed

+120
-33
lines changed

.github/workflows/psalm.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ jobs:
4949
git checkout composer.json
5050
git checkout -m ${{ github.base_ref }}
5151
52+
# to be removed when psalm adds support for intersection types
53+
sed -i 's/Uuid&/Uuid|/' src/Symfony/Component/Uid/Factory/TimeBasedUuidFactory.php
5254
./vendor/bin/psalm.phar --set-baseline=.github/psalm/psalm.baseline.xml --no-progress
5355
git checkout -m FETCH_HEAD
5456

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/UidTest.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818
use Symfony\Component\Uid\UuidV4;
1919
use Symfony\Component\Uid\UuidV6;
2020

21-
/**
22-
* @see UidController
23-
*/
2421
class UidTest extends AbstractWebTestCase
2522
{
2623
protected function setUp(): void
@@ -41,7 +38,7 @@ public function testArgumentValueResolverDisabled()
4138
$exception = reset($exceptions);
4239

4340
$this->assertInstanceOf(\TypeError::class, $exception);
44-
$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());
41+
$this->assertStringContainsString(UidController::class.'::anyFormat(): Argument #1 ($userId) must be of type Symfony\Component\Uid\UuidV1, string given', $exception->getMessage());
4542
}
4643

4744
public function testArgumentValueResolverEnabled()

src/Symfony/Component/Uid/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ CHANGELOG
44
6.2
55
---
66

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

910
5.4
1011
---

src/Symfony/Component/Uid/Command/InspectUuidCommand.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
use Symfony\Component\Console\Output\ConsoleOutputInterface;
2020
use Symfony\Component\Console\Output\OutputInterface;
2121
use Symfony\Component\Console\Style\SymfonyStyle;
22+
use Symfony\Component\Uid\MaxUuid;
23+
use Symfony\Component\Uid\NilUuid;
24+
use Symfony\Component\Uid\TimeBasedUidInterface;
2225
use Symfony\Component\Uid\Uuid;
23-
use Symfony\Component\Uid\UuidV1;
24-
use Symfony\Component\Uid\UuidV6;
2526

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

59-
if (-1 === $version = uuid_type($uuid)) {
60+
if (new NilUuid() == $uuid) {
6061
$version = 'nil';
61-
} elseif (0 === $version || 2 === $version || 6 < $version) {
62-
$version = 'unknown';
62+
} elseif (new MaxUuid() == $uuid) {
63+
$version = 'max';
64+
} else {
65+
$version = uuid_type($uuid);
6366
}
6467

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

73-
if ($uuid instanceof UuidV1 || $uuid instanceof UuidV6) {
76+
if ($uuid instanceof TimeBasedUidInterface) {
7477
$rows[] = new TableSeparator();
7578
$rows[] = ['Time', $uuid->getDateTime()->format('Y-m-d H:i:s.u \U\T\C')];
7679
}

src/Symfony/Component/Uid/MaxUlid.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Uid;
13+
14+
class MaxUlid extends Ulid
15+
{
16+
public function __construct()
17+
{
18+
$this->uid = parent::MAX;
19+
}
20+
}

src/Symfony/Component/Uid/MaxUuid.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Uid;
13+
14+
class MaxUuid extends Uuid
15+
{
16+
protected const TYPE = -1;
17+
18+
public function __construct()
19+
{
20+
$this->uid = parent::MAX;
21+
}
22+
}

src/Symfony/Component/Uid/Tests/Command/InspectUuidCommandTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function testUnknown()
5555
----------------------- --------------------------------------
5656
Label Value
5757
----------------------- --------------------------------------
58-
Version unknown
58+
Version 0
5959
toRfc4122 (canonical) 461cc9b9-2397-0dba-91e9-33af4c63f7ec
6060
toBase58 9f9nftX6dw4oVPm5uT17um
6161
toBase32 263K4VJ8WQ1PX93T9KNX667XZC
@@ -71,7 +71,7 @@ public function testUnknown()
7171
----------------------- --------------------------------------
7272
Label Value
7373
----------------------- --------------------------------------
74-
Version unknown
74+
Version 2
7575
toRfc4122 (canonical) 461cc9b9-2397-2dba-91e9-33af4c63f7ec
7676
toBase58 9f9nftX6fjLfNnvSAHMV7Z
7777
toBase32 263K4VJ8WQ5PX93T9KNX667XZC
@@ -87,7 +87,7 @@ public function testUnknown()
8787
----------------------- --------------------------------------
8888
Label Value
8989
----------------------- --------------------------------------
90-
Version unknown
90+
Version 7
9191
toRfc4122 (canonical) 461cc9b9-2397-7dba-91e9-33af4c63f7ec
9292
toBase58 9f9nftX6kE2K6HpooNEQ83
9393
toBase32 263K4VJ8WQFPX93T9KNX667XZC
@@ -103,7 +103,7 @@ public function testUnknown()
103103
----------------------- --------------------------------------
104104
Label Value
105105
----------------------- --------------------------------------
106-
Version unknown
106+
Version 12
107107
toRfc4122 (canonical) 461cc9b9-2397-cdba-91e9-33af4c63f7ec
108108
toBase58 9f9nftX6pihxonjBST7K8X
109109
toBase32 263K4VJ8WQSPX93T9KNX667XZC

src/Symfony/Component/Uid/Tests/UlidTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Uid\Tests;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Uid\MaxUlid;
1516
use Symfony\Component\Uid\NilUlid;
1617
use Symfony\Component\Uid\Tests\Fixtures\CustomUlid;
1718
use Symfony\Component\Uid\Ulid;
@@ -267,4 +268,21 @@ public function testNewNilUlid()
267268
{
268269
$this->assertSame('00000000000000000000000000', (string) new NilUlid());
269270
}
271+
272+
/**
273+
* @testWith ["ffffffff-ffff-ffff-ffff-ffffffffffff"]
274+
* ["7zzzzzzzzzzzzzzzzzzzzzzzzz"]
275+
*/
276+
public function testMaxUlid(string $ulid)
277+
{
278+
$ulid = Ulid::fromString($ulid);
279+
280+
$this->assertInstanceOf(MaxUlid::class, $ulid);
281+
$this->assertSame('7ZZZZZZZZZZZZZZZZZZZZZZZZZ', (string) $ulid);
282+
}
283+
284+
public function testNewMaxUlid()
285+
{
286+
$this->assertSame('7ZZZZZZZZZZZZZZZZZZZZZZZZZ', (string) new MaxUlid());
287+
}
270288
}

src/Symfony/Component/Uid/Tests/UuidTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Uid\Tests;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Uid\MaxUuid;
1516
use Symfony\Component\Uid\NilUuid;
1617
use Symfony\Component\Uid\Tests\Fixtures\CustomUuid;
1718
use Symfony\Component\Uid\Ulid;
@@ -238,6 +239,23 @@ public function testNewNilUuid()
238239
$this->assertSame('00000000-0000-0000-0000-000000000000', (string) new NilUuid());
239240
}
240241

242+
/**
243+
* @testWith ["ffffffff-ffff-ffff-ffff-ffffffffffff"]
244+
* ["7zzzzzzzzzzzzzzzzzzzzzzzzz"]
245+
*/
246+
public function testMaxUuid(string $uuid)
247+
{
248+
$uuid = Uuid::fromString($uuid);
249+
250+
$this->assertInstanceOf(MaxUuid::class, $uuid);
251+
$this->assertSame('ffffffff-ffff-ffff-ffff-ffffffffffff', (string) $uuid);
252+
}
253+
254+
public function testNewMaxUuid()
255+
{
256+
$this->assertSame('ffffffff-ffff-ffff-ffff-ffffffffffff', (string) new MaxUuid());
257+
}
258+
241259
public function testFromBinary()
242260
{
243261
$this->assertEquals(

src/Symfony/Component/Uid/Ulid.php

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
class Ulid extends AbstractUid implements TimeBasedUidInterface
2222
{
2323
protected const NIL = '00000000000000000000000000';
24+
protected const MAX = '7ZZZZZZZZZZZZZZZZZZZZZZZZZ';
2425

2526
private static string $time = '';
2627
private static array $rand = [];
@@ -29,21 +30,17 @@ public function __construct(string $ulid = null)
2930
{
3031
if (null === $ulid) {
3132
$this->uid = static::generate();
32-
33-
return;
34-
}
35-
36-
if (self::NIL === $ulid) {
33+
} elseif (self::NIL === $ulid) {
3734
$this->uid = $ulid;
35+
} elseif (self::MAX === strtr($ulid, 'z', 'Z')) {
36+
$this->uid = $ulid;
37+
} else {
38+
if (!self::isValid($ulid)) {
39+
throw new \InvalidArgumentException(sprintf('Invalid ULID: "%s".', $ulid));
40+
}
3841

39-
return;
40-
}
41-
42-
if (!self::isValid($ulid)) {
43-
throw new \InvalidArgumentException(sprintf('Invalid ULID: "%s".', $ulid));
42+
$this->uid = strtoupper($ulid);
4443
}
45-
46-
$this->uid = strtoupper($ulid);
4744
}
4845

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

7067
if (16 !== \strlen($ulid)) {
71-
if (self::NIL === $ulid) {
72-
return new NilUlid();
73-
}
74-
75-
return new static($ulid);
68+
return match (strtr($ulid, 'z', 'Z')) {
69+
self::NIL => new NilUlid(),
70+
self::MAX => new MaxUlid(),
71+
default => new static($ulid),
72+
};
7673
}
7774

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

90+
if (self::MAX === $ulid = strtr($ulid, 'abcdefghijklmnopqrstuv', 'ABCDEFGHJKMNPQRSTVWXYZ')) {
91+
return new MaxUlid();
92+
}
93+
9394
$u = new static(self::NIL);
94-
$u->uid = strtr($ulid, 'abcdefghijklmnopqrstuv', 'ABCDEFGHJKMNPQRSTVWXYZ');
95+
$u->uid = $ulid;
9596

9697
return $u;
9798
}

src/Symfony/Component/Uid/Uuid.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Uuid extends AbstractUid
2525

2626
protected const TYPE = 0;
2727
protected const NIL = '00000000-0000-0000-0000-000000000000';
28+
protected const MAX = 'ffffffff-ffff-ffff-ffff-ffffffffffff';
2829

2930
public function __construct(string $uuid, bool $checkVariant = false)
3031
{
@@ -68,6 +69,10 @@ public static function fromString(string $uuid): static
6869
return new NilUuid();
6970
}
7071

72+
if (self::MAX === $uuid = strtr($uuid, 'F', 'f')) {
73+
return new MaxUuid();
74+
}
75+
7176
if (!\in_array($uuid[19], ['8', '9', 'a', 'b', 'A', 'B'], true)) {
7277
return new self($uuid);
7378
}

0 commit comments

Comments
 (0)