From 8b058c1368d0226759960bd218b0179a2d3b6e56 Mon Sep 17 00:00:00 2001 From: Wilhelm Behncke Date: Sat, 8 Jul 2023 14:58:49 +0200 Subject: [PATCH 1/3] !!!FEATURE: (Neos.Neos) Track created nodes in PendingChangesProjection --- .../PendingChangesProjection/Change.php | 10 ++++ .../ChangeProjection.php | 57 +++++++++++++++++-- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/Neos.Neos/Classes/PendingChangesProjection/Change.php b/Neos.Neos/Classes/PendingChangesProjection/Change.php index a39952d655c..4bbeeec0263 100644 --- a/Neos.Neos/Classes/PendingChangesProjection/Change.php +++ b/Neos.Neos/Classes/PendingChangesProjection/Change.php @@ -44,6 +44,11 @@ class Change */ public $originDimensionSpacePoint; + /** + * @var bool + */ + public $created; + /** * @var bool */ @@ -68,6 +73,7 @@ public function __construct( ContentStreamId $contentStreamId, NodeAggregateId $nodeAggregateId, OriginDimensionSpacePoint $originDimensionSpacePoint, + bool $created, bool $changed, bool $moved, bool $deleted, @@ -76,6 +82,7 @@ public function __construct( $this->contentStreamId = $contentStreamId; $this->nodeAggregateId = $nodeAggregateId; $this->originDimensionSpacePoint = $originDimensionSpacePoint; + $this->created = $created; $this->changed = $changed; $this->moved = $moved; $this->deleted = $deleted; @@ -93,6 +100,7 @@ public function addToDatabase(Connection $databaseConnection, string $tableName) 'nodeAggregateId' => $this->nodeAggregateId->value, 'originDimensionSpacePoint' => $this->originDimensionSpacePoint->toJson(), 'originDimensionSpacePointHash' => $this->originDimensionSpacePoint->hash, + 'created' => (int)$this->created, 'changed' => (int)$this->changed, 'moved' => (int)$this->moved, 'deleted' => (int)$this->deleted, @@ -105,6 +113,7 @@ public function updateToDatabase(Connection $databaseConnection, string $tableNa $databaseConnection->update( $tableName, [ + 'created' => (int)$this->created, 'changed' => (int)$this->changed, 'moved' => (int)$this->moved, 'deleted' => (int)$this->deleted, @@ -128,6 +137,7 @@ public static function fromDatabaseRow(array $databaseRow): self ContentStreamId::fromString($databaseRow['contentStreamId']), NodeAggregateId::fromString($databaseRow['nodeAggregateId']), OriginDimensionSpacePoint::fromJsonString($databaseRow['originDimensionSpacePoint']), + (bool)$databaseRow['created'], (bool)$databaseRow['changed'], (bool)$databaseRow['moved'], (bool)$databaseRow['deleted'], diff --git a/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php b/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php index 5d9525b1787..e5f38b35fc2 100644 --- a/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php +++ b/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php @@ -108,6 +108,8 @@ private function setupTables(): void $changeTable->addColumn('contentStreamId', Types::STRING) ->setLength(40) ->setNotnull(true); + $changeTable->addColumn('created', Types::BOOLEAN) + ->setNotnull(true); $changeTable->addColumn('changed', Types::BOOLEAN) ->setNotnull(true); $changeTable->addColumn('moved', Types::BOOLEAN) @@ -257,7 +259,7 @@ private function whenNodeReferencesWereSet(NodeReferencesWereSet $event): void private function whenNodeAggregateWithNodeWasCreated(NodeAggregateWithNodeWasCreated $event): void { - $this->markAsChanged( + $this->markAsCreated( $event->contentStreamId, $event->nodeAggregateId, $event->originDimensionSpacePoint @@ -319,12 +321,13 @@ private function whenNodeAggregateWasRemoved(NodeAggregateWasRemoved $event): vo $this->getDatabaseConnection()->executeUpdate( 'INSERT INTO ' . $this->tableName . ' (contentStreamId, nodeAggregateId, originDimensionSpacePoint, - originDimensionSpacePointHash, deleted, changed, moved, removalAttachmentPoint) + originDimensionSpacePointHash, created, deleted, changed, moved, removalAttachmentPoint) VALUES ( :contentStreamId, :nodeAggregateId, :originDimensionSpacePoint, :originDimensionSpacePointHash, + 0, 1, 0, 0, @@ -369,7 +372,7 @@ private function whenDimensionSpacePointWasMoved(DimensionSpacePointWasMoved $ev private function whenNodeSpecializationVariantWasCreated(NodeSpecializationVariantWasCreated $event): void { - $this->markAsChanged( + $this->markAsCreated( $event->contentStreamId, $event->nodeAggregateId, $event->specializationOrigin @@ -378,7 +381,7 @@ private function whenNodeSpecializationVariantWasCreated(NodeSpecializationVaria private function whenNodeGeneralizationVariantWasCreated(NodeGeneralizationVariantWasCreated $event): void { - $this->markAsChanged( + $this->markAsCreated( $event->contentStreamId, $event->nodeAggregateId, $event->generalizationOrigin @@ -387,7 +390,7 @@ private function whenNodeGeneralizationVariantWasCreated(NodeGeneralizationVaria private function whenNodePeerVariantWasCreated(NodePeerVariantWasCreated $event): void { - $this->markAsChanged( + $this->markAsCreated( $event->contentStreamId, $event->nodeAggregateId, $event->peerOrigin @@ -422,12 +425,55 @@ private function markAsChanged( $contentStreamId, $nodeAggregateId, $originDimensionSpacePoint, + false, + true, + false, + false + ); + $change->addToDatabase($this->getDatabaseConnection(), $this->tableName); + } else { + $change->changed = true; + $change->updateToDatabase($this->getDatabaseConnection(), $this->tableName); + } + }); + } + + private function markAsCreated( + ContentStreamId $contentStreamId, + NodeAggregateId $nodeAggregateId, + OriginDimensionSpacePoint $originDimensionSpacePoint, + ): void { + $this->transactional(function () use ( + $contentStreamId, + $nodeAggregateId, + $originDimensionSpacePoint + ) { + // HACK: basically we are not allowed to read other Projection's finder methods here; + // but we nevertheless do it. + // we can maybe figure out another way of solving this lateron. + $workspace = $this->workspaceFinder->findOneByCurrentContentStreamId($contentStreamId); + if ($workspace instanceof Workspace && $workspace->baseWorkspaceName === null) { + // Workspace is the live workspace (has no base workspace); we do not need to do anything + return; + } + $change = $this->getChange( + $contentStreamId, + $nodeAggregateId, + $originDimensionSpacePoint + ); + if ($change === null) { + $change = new Change( + $contentStreamId, + $nodeAggregateId, + $originDimensionSpacePoint, + true, true, false, false ); $change->addToDatabase($this->getDatabaseConnection(), $this->tableName); } else { + $change->created = true; $change->changed = true; $change->updateToDatabase($this->getDatabaseConnection(), $this->tableName); } @@ -460,6 +506,7 @@ private function markAsMoved( $nodeAggregateId, $originDimensionSpacePoint, false, + false, true, false ); From fb0a17cecfd8915b75274f3f75873cdc38e4076d Mon Sep 17 00:00:00 2001 From: Wilhelm Behncke Date: Sat, 8 Jul 2023 16:48:31 +0200 Subject: [PATCH 2/3] TASK: (Neos.Neos) Refactor change modification logic in ChangeProjection In Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php: This moves most of the repeated code from the methods `markAsChanged`, `markAsCreated` and `markAsMoved` into a unified `modifyChange` method that accepts a callback for the aforementioned methods to perform their unique tasks in. --- .../ChangeProjection.php | 111 ++++++------------ 1 file changed, 35 insertions(+), 76 deletions(-) diff --git a/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php b/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php index e5f38b35fc2..cb63a7c3d86 100644 --- a/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php +++ b/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php @@ -402,40 +402,14 @@ private function markAsChanged( NodeAggregateId $nodeAggregateId, OriginDimensionSpacePoint $originDimensionSpacePoint, ): void { - $this->transactional(function () use ( + $this->modifyChange( $contentStreamId, $nodeAggregateId, - $originDimensionSpacePoint - ) { - // HACK: basically we are not allowed to read other Projection's finder methods here; - // but we nevertheless do it. - // we can maybe figure out another way of solving this lateron. - $workspace = $this->workspaceFinder->findOneByCurrentContentStreamId($contentStreamId); - if ($workspace instanceof Workspace && $workspace->baseWorkspaceName === null) { - // Workspace is the live workspace (has no base workspace); we do not need to do anything - return; - } - $change = $this->getChange( - $contentStreamId, - $nodeAggregateId, - $originDimensionSpacePoint - ); - if ($change === null) { - $change = new Change( - $contentStreamId, - $nodeAggregateId, - $originDimensionSpacePoint, - false, - true, - false, - false - ); - $change->addToDatabase($this->getDatabaseConnection(), $this->tableName); - } else { + $originDimensionSpacePoint, + static function (Change $change) { $change->changed = true; - $change->updateToDatabase($this->getDatabaseConnection(), $this->tableName); } - }); + ); } private function markAsCreated( @@ -443,76 +417,61 @@ private function markAsCreated( NodeAggregateId $nodeAggregateId, OriginDimensionSpacePoint $originDimensionSpacePoint, ): void { - $this->transactional(function () use ( + $this->modifyChange( $contentStreamId, $nodeAggregateId, - $originDimensionSpacePoint - ) { - // HACK: basically we are not allowed to read other Projection's finder methods here; - // but we nevertheless do it. - // we can maybe figure out another way of solving this lateron. - $workspace = $this->workspaceFinder->findOneByCurrentContentStreamId($contentStreamId); - if ($workspace instanceof Workspace && $workspace->baseWorkspaceName === null) { - // Workspace is the live workspace (has no base workspace); we do not need to do anything - return; - } - $change = $this->getChange( - $contentStreamId, - $nodeAggregateId, - $originDimensionSpacePoint - ); - if ($change === null) { - $change = new Change( - $contentStreamId, - $nodeAggregateId, - $originDimensionSpacePoint, - true, - true, - false, - false - ); - $change->addToDatabase($this->getDatabaseConnection(), $this->tableName); - } else { + $originDimensionSpacePoint, + static function (Change $change) { $change->created = true; $change->changed = true; - $change->updateToDatabase($this->getDatabaseConnection(), $this->tableName); } - }); + ); } private function markAsMoved( ContentStreamId $contentStreamId, NodeAggregateId $nodeAggregateId, OriginDimensionSpacePoint $originDimensionSpacePoint, + ): void { + $this->modifyChange( + $contentStreamId, + $nodeAggregateId, + $originDimensionSpacePoint, + static function (Change $change) { + $change->moved = true; + } + ); + } + + private function modifyChange( + ContentStreamId $contentStreamId, + NodeAggregateId $nodeAggregateId, + OriginDimensionSpacePoint $originDimensionSpacePoint, + callable $modifyFn ): void { $this->transactional(function () use ( $contentStreamId, $nodeAggregateId, - $originDimensionSpacePoint + $originDimensionSpacePoint, + $modifyFn ) { + // HACK: basically we are not allowed to read other Projection's finder methods here; + // but we nevertheless do it. + // we can maybe figure out another way of solving this lateron. $workspace = $this->workspaceFinder->findOneByCurrentContentStreamId($contentStreamId); if ($workspace instanceof Workspace && $workspace->baseWorkspaceName === null) { // Workspace is the live workspace (has no base workspace); we do not need to do anything return; } - $change = $this->getChange( - $contentStreamId, - $nodeAggregateId, - $originDimensionSpacePoint - ); + + $change = $this->getChange($contentStreamId, $nodeAggregateId, $originDimensionSpacePoint); + if ($change === null) { - $change = new Change( - $contentStreamId, - $nodeAggregateId, - $originDimensionSpacePoint, - false, - false, - true, - false - ); + $change = new Change($contentStreamId, $nodeAggregateId, $originDimensionSpacePoint, false, false, false, false); + $modifyFn($change); $change->addToDatabase($this->getDatabaseConnection(), $this->tableName); } else { - $change->moved = true; + $modifyFn($change); $change->updateToDatabase($this->getDatabaseConnection(), $this->tableName); } }); From 1c4c3d0a9439cb4ecc420229cd0aa52f6aac5728 Mon Sep 17 00:00:00 2001 From: Sebastian Kurfuerst Date: Wed, 2 Aug 2023 06:48:17 +0200 Subject: [PATCH 3/3] fix all tableName -> tableNamePrefix renamings --- .../Classes/PendingChangesProjection/ChangeProjection.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php b/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php index 16eecd5126c..b3fb8a84670 100644 --- a/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php +++ b/Neos.Neos/Classes/PendingChangesProjection/ChangeProjection.php @@ -495,10 +495,10 @@ private function modifyChange( if ($change === null) { $change = new Change($contentStreamId, $nodeAggregateId, $originDimensionSpacePoint, false, false, false, false); $modifyFn($change); - $change->addToDatabase($this->getDatabaseConnection(), $this->tableName); + $change->addToDatabase($this->getDatabaseConnection(), $this->tableNamePrefix); } else { $modifyFn($change); - $change->updateToDatabase($this->getDatabaseConnection(), $this->tableName); + $change->updateToDatabase($this->getDatabaseConnection(), $this->tableNamePrefix); } }); }