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 <fabien@symfony.com>
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 <fabien@symfony.com>
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
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy