diff --git a/baseline.xml b/baseline.xml index 3ed282f31..8b7252a2a 100644 --- a/baseline.xml +++ b/baseline.xml @@ -85,6 +85,7 @@ $bus + $id $repository $store @@ -93,14 +94,19 @@ $adapter $bus + $id $repository $snapshotStore $store + + id]]> + $bus + $id $repository $snapshotStore $store @@ -109,6 +115,7 @@ $bus + $id $profile $repository $store diff --git a/composer.json b/composer.json index 90ba31fb4..0b48a17f5 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "psr/clock": "^1.0", "psr/log": "^2.0.0|^3.0.0", "psr/simple-cache": "^2.0.0|^3.0.0", + "ramsey/uuid": "^4.7", "symfony/console": "^5.4.32|^6.4.1|^7.0.1", "symfony/finder": "^5.4.27|^6.4.0|^7.0.0", "symfony/lock": "^5.4.32|^6.4.0|^7.0.0" diff --git a/composer.lock b/composer.lock index a2d1aaaa6..52cd6424f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,63 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e4f404ab231a5bdafd3f79b6c0214ae7", + "content-hash": "6d8b289f331bdf12d6cd2dca8ef7ff36", "packages": [ + { + "name": "brick/math", + "version": "0.11.0", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/0ad82ce168c82ba30d1c01ec86116ab52f589478", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "5.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.11.0" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2023-01-15T23:15:59+00:00" + }, { "name": "doctrine/cache", "version": "2.2.0", @@ -778,6 +833,187 @@ }, "time": "2021-10-29T13:26:27+00:00" }, + { + "name": "ramsey/collection", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2022-12-31T21:50:55+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.7.5", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", + "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", + "ext-json": "*", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^8.5 || ^9", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.7.5" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2023-11-08T05:53:05+00:00" + }, { "name": "symfony/console", "version": "v7.0.1", diff --git a/src/Aggregate/AggregateRootId.php b/src/Aggregate/AggregateRootId.php index 3ce2a1cda..5bbb66491 100644 --- a/src/Aggregate/AggregateRootId.php +++ b/src/Aggregate/AggregateRootId.php @@ -7,4 +7,6 @@ interface AggregateRootId { public function toString(): string; + + public static function fromString(string $id): self; } diff --git a/src/Aggregate/BasicAggregateRootId.php b/src/Aggregate/BasicAggregateRootId.php index 248e17136..d68a33ac0 100644 --- a/src/Aggregate/BasicAggregateRootId.php +++ b/src/Aggregate/BasicAggregateRootId.php @@ -6,13 +6,5 @@ final class BasicAggregateRootId implements AggregateRootId { - public function __construct( - private readonly string $id, - ) { - } - - public function toString(): string - { - return $this->id; - } + use ValueAggregateIdBehaviour; } diff --git a/src/Aggregate/RamseyAggregateIdBehaviour.php b/src/Aggregate/RamseyAggregateIdBehaviour.php new file mode 100644 index 000000000..e5954e330 --- /dev/null +++ b/src/Aggregate/RamseyAggregateIdBehaviour.php @@ -0,0 +1,31 @@ +id->toString(); + } + + public static function generate(): self + { + return new self(Uuid::uuid7()); + } +} diff --git a/src/Aggregate/UuidAggregateRootId.php b/src/Aggregate/UuidAggregateRootId.php new file mode 100644 index 000000000..a02f5c506 --- /dev/null +++ b/src/Aggregate/UuidAggregateRootId.php @@ -0,0 +1,10 @@ +id; + } +} diff --git a/tests/Benchmark/BasicImplementation/ProfileId.php b/tests/Benchmark/BasicImplementation/ProfileId.php index 0eaada1b0..6d947e410 100644 --- a/tests/Benchmark/BasicImplementation/ProfileId.php +++ b/tests/Benchmark/BasicImplementation/ProfileId.php @@ -5,28 +5,9 @@ namespace Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation; use Patchlevel\EventSourcing\Aggregate\AggregateRootId; - -use function uniqid; +use Patchlevel\EventSourcing\Aggregate\RamseyAggregateIdBehaviour; final class ProfileId implements AggregateRootId { - private function __construct( - private string $id, - ) { - } - - public static function fromString(string $id): self - { - return new self($id); - } - - public function toString(): string - { - return $this->id; - } - - public static function generate(): self - { - return new self(uniqid('', true)); - } + use RamseyAggregateIdBehaviour; } diff --git a/tests/Benchmark/SimpleSetupBench.php b/tests/Benchmark/SimpleSetupBench.php index d0488d430..4abd77e1f 100644 --- a/tests/Benchmark/SimpleSetupBench.php +++ b/tests/Benchmark/SimpleSetupBench.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Driver\PDO\SQLite\Driver; use Doctrine\DBAL\DriverManager; +use Patchlevel\EventSourcing\Aggregate\AggregateRootId; use Patchlevel\EventSourcing\EventBus\DefaultEventBus; use Patchlevel\EventSourcing\EventBus\EventBus; use Patchlevel\EventSourcing\Metadata\AggregateRoot\AttributeAggregateRootRegistryFactory; @@ -31,6 +32,8 @@ final class SimpleSetupBench private EventBus $bus; private Repository $repository; + private AggregateRootId $id; + public function setUp(): void { if (file_exists(self::DB_PATH)) { @@ -60,7 +63,9 @@ public function setUp(): void $schemaDirector->create(); - $profile = Profile::create(ProfileId::fromString('1'), 'Peter'); + $this->id = ProfileId::generate(); + + $profile = Profile::create($this->id, 'Peter'); for ($i = 0; $i < 10_000; $i++) { $profile->changeName('Peter'); @@ -72,7 +77,7 @@ public function setUp(): void #[Bench\Revs(20)] public function benchLoad10000Events(): void { - $this->repository->load(ProfileId::fromString('1')); + $this->repository->load($this->id); } #[Bench\Revs(20)] diff --git a/tests/Benchmark/SnapshotsBench.php b/tests/Benchmark/SnapshotsBench.php index f1d6bf27a..f4dbd5e13 100644 --- a/tests/Benchmark/SnapshotsBench.php +++ b/tests/Benchmark/SnapshotsBench.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Driver\PDO\SQLite\Driver; use Doctrine\DBAL\DriverManager; +use Patchlevel\EventSourcing\Aggregate\AggregateRootId; use Patchlevel\EventSourcing\EventBus\DefaultEventBus; use Patchlevel\EventSourcing\EventBus\EventBus; use Patchlevel\EventSourcing\Metadata\AggregateRoot\AttributeAggregateRootRegistryFactory; @@ -37,6 +38,8 @@ final class SnapshotsBench private InMemorySnapshotAdapter $adapter; + private AggregateRootId $id; + public function setUp(): void { if (file_exists(self::DB_PATH)) { @@ -70,7 +73,8 @@ public function setUp(): void $schemaDirector->create(); - $profile = Profile::create(ProfileId::fromString('1'), 'Peter'); + $this->id = ProfileId::generate(); + $profile = Profile::create($this->id, 'Peter'); for ($i = 0; $i < 10_000; $i++) { $profile->changeName('Peter'); @@ -84,12 +88,12 @@ public function setUp(): void public function benchLoad10000EventsMissingSnapshot(): void { $this->adapter->clear(); - $this->repository->load(ProfileId::fromString('1')); + $this->repository->load($this->id); } #[Bench\Revs(20)] public function benchLoad10000Events(): void { - $this->repository->load(ProfileId::fromString('1')); + $this->repository->load($this->id); } } diff --git a/tests/Benchmark/SplitStreamBench.php b/tests/Benchmark/SplitStreamBench.php index 29ec188c3..46aa0c0f3 100644 --- a/tests/Benchmark/SplitStreamBench.php +++ b/tests/Benchmark/SplitStreamBench.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Driver\PDO\SQLite\Driver; use Doctrine\DBAL\DriverManager; +use Patchlevel\EventSourcing\Aggregate\AggregateRootId; use Patchlevel\EventSourcing\EventBus\Decorator\SplitStreamDecorator; use Patchlevel\EventSourcing\EventBus\DefaultEventBus; use Patchlevel\EventSourcing\EventBus\EventBus; @@ -36,6 +37,8 @@ final class SplitStreamBench private SnapshotStore $snapshotStore; private Repository $repository; + private AggregateRootId $id; + public function setUp(): void { if (file_exists(self::DB_PATH)) { @@ -72,11 +75,13 @@ public function setUp(): void ); $schemaDirector->create(); + + $this->id = ProfileId::generate(); } public function provideData(): void { - $profile = Profile::create(ProfileId::fromString('1'), 'Peter'); + $profile = Profile::create($this->id, 'Peter'); for ($i = 0; $i < 10_000; $i++) { $profile->changeName(sprintf('Peter %d', $i)); @@ -95,7 +100,7 @@ public function provideData(): void #[Bench\BeforeMethods('provideData')] public function benchLoad10000Events(): void { - $this->repository->load(ProfileId::fromString('1')); + $this->repository->load($this->id); } #[Bench\Revs(20)] diff --git a/tests/Benchmark/SyncProjectionistBench.php b/tests/Benchmark/SyncProjectionistBench.php index 028eec29c..9aef5d853 100644 --- a/tests/Benchmark/SyncProjectionistBench.php +++ b/tests/Benchmark/SyncProjectionistBench.php @@ -42,6 +42,8 @@ final class SyncProjectionistBench private Repository $repository; private Profile $profile; + private ProfileId $id; + public function setUp(): void { if (file_exists(self::DB_PATH)) { @@ -100,7 +102,8 @@ public function setUp(): void $schemaDirector->create(); $projectionist->boot(); - $this->profile = Profile::create(ProfileId::fromString('1'), 'Peter'); + $this->id = ProfileId::generate(); + $this->profile = Profile::create($this->id, 'Peter'); $this->repository->save($this->profile); }