Skip to content
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

WIP: !!! TASK: Add workspace content stream mapping to content graph projection #5041

Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,9 @@ public function __construct(

public function buildForWorkspace(WorkspaceName $workspaceName): ContentGraph
{
// FIXME: Should be part of this projection, this is forbidden
$tableName = strtolower(sprintf(
'cr_%s_p_%s',
$this->contentRepositoryId->value,
'workspace'
));

$row = $this->client->getConnection()->executeQuery(
'
SELECT * FROM ' . $tableName . '
SELECT * FROM ' . $this->tableNames->workspaces() . '
WHERE workspaceName = :workspaceName
LIMIT 1
',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ public function referenceRelation(): string
return $this->tableNamePrefix . '_referencerelation';
}

public function workspaces(): string
{
return $this->tableNamePrefix . '_workspaces';
}

public function checkpoint(): string
{
return $this->tableNamePrefix . '_checkpoint';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Types\Types;
use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Projection\Feature\CurrentWorkspaceContentStreamId;
use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Projection\Feature\NodeMove;
use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Projection\Feature\NodeRemoval;
use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Projection\Feature\NodeVariation;
Expand Down Expand Up @@ -43,6 +44,15 @@
use Neos\ContentRepository\Core\Feature\SubtreeTagging\Dto\SubtreeTags;
use Neos\ContentRepository\Core\Feature\SubtreeTagging\Event\SubtreeWasTagged;
use Neos\ContentRepository\Core\Feature\SubtreeTagging\Event\SubtreeWasUntagged;
use Neos\ContentRepository\Core\Feature\WorkspaceCreation\Event\RootWorkspaceWasCreated;
use Neos\ContentRepository\Core\Feature\WorkspaceCreation\Event\WorkspaceWasCreated;
use Neos\ContentRepository\Core\Feature\WorkspaceModification\Event\WorkspaceBaseWorkspaceWasChanged;
use Neos\ContentRepository\Core\Feature\WorkspaceModification\Event\WorkspaceWasRemoved;
use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasDiscarded;
use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyDiscarded;
use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyPublished;
use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPublished;
use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Event\WorkspaceWasRebased;
use Neos\ContentRepository\Core\Infrastructure\DbalCheckpointStorage;
use Neos\ContentRepository\Core\Infrastructure\DbalClientInterface;
use Neos\ContentRepository\Core\Infrastructure\DbalSchemaDiff;
Expand All @@ -69,7 +79,7 @@ final class DoctrineDbalContentGraphProjection implements ProjectionInterface
use SubtreeTagging;
use NodeRemoval;
use NodeMove;

use CurrentWorkspaceContentStreamId;

public const RELATION_DEFAULT_OFFSET = 128;

Expand Down Expand Up @@ -157,6 +167,7 @@ private function truncateDatabaseTables(): void
$connection->executeQuery('TRUNCATE table ' . $this->tableNames->hierarchyRelation());
$connection->executeQuery('TRUNCATE table ' . $this->tableNames->referenceRelation());
$connection->executeQuery('TRUNCATE table ' . $this->tableNames->dimensionSpacePoints());
$connection->executeQuery('TRUNCATE table ' . $this->tableNames->workspaces());
}

public function canHandle(EventInterface $event): bool
Expand All @@ -180,6 +191,21 @@ public function canHandle(EventInterface $event): bool
NodePeerVariantWasCreated::class,
SubtreeWasTagged::class,
SubtreeWasUntagged::class,

/**
* Workspace related commands, see {@see CurrentWorkspaceContentStreamId}
* We are not interested in the events WorkspaceWasRenamed, WorkspaceRebaseFailed and WorkspaceOwnerWasChanged
* As they do not change the current content stream id
*/
WorkspaceWasCreated::class,
RootWorkspaceWasCreated::class,
WorkspaceWasDiscarded::class,
WorkspaceWasPartiallyDiscarded::class,
WorkspaceWasPartiallyPublished::class,
WorkspaceWasPublished::class,
WorkspaceWasRebased::class,
WorkspaceWasRemoved::class,
WorkspaceBaseWorkspaceWasChanged::class,
]);
}

Expand All @@ -204,6 +230,15 @@ public function apply(EventInterface $event, EventEnvelope $eventEnvelope): void
NodePeerVariantWasCreated::class => $this->whenNodePeerVariantWasCreated($event, $eventEnvelope),
SubtreeWasTagged::class => $this->whenSubtreeWasTagged($event),
SubtreeWasUntagged::class => $this->whenSubtreeWasUntagged($event),
WorkspaceWasCreated::class => $this->whenWorkspaceWasCreated($event),
RootWorkspaceWasCreated::class => $this->whenRootWorkspaceWasCreated($event),
WorkspaceWasDiscarded::class => $this->whenWorkspaceWasDiscarded($event),
WorkspaceWasPartiallyDiscarded::class => $this->whenWorkspaceWasPartiallyDiscarded($event),
WorkspaceWasPartiallyPublished::class => $this->whenWorkspaceWasPartiallyPublished($event),
WorkspaceWasPublished::class => $this->whenWorkspaceWasPublished($event),
WorkspaceWasRebased::class => $this->whenWorkspaceWasRebased($event),
WorkspaceWasRemoved::class => $this->whenWorkspaceWasRemoved($event),
WorkspaceBaseWorkspaceWasChanged::class => $this->whenWorkspaceBaseWorkspaceWasChanged($event),
default => throw new \InvalidArgumentException(sprintf('Unsupported event %s', get_debug_type($event))),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class DoctrineDbalContentGraphSchemaBuilder
private const DEFAULT_TEXT_COLLATION = 'utf8mb4_unicode_520_ci';

public function __construct(
private readonly ContentGraphTableNames $contentGraphTableNames
private readonly ContentGraphTableNames $tableNames
) {
}

Expand All @@ -28,13 +28,14 @@ public function buildSchema(AbstractSchemaManager $schemaManager): Schema
$this->createNodeTable(),
$this->createHierarchyRelationTable(),
$this->createReferenceRelationTable(),
$this->createDimensionSpacePointsTable()
$this->createDimensionSpacePointsTable(),
$this->createWorkspacesTable()
]);
}

private function createNodeTable(): Table
{
$table = new Table($this->contentGraphTableNames->node(), [
$table = new Table($this->tableNames->node(), [
DbalSchemaFactory::columnForNodeAnchorPoint('relationanchorpoint')->setAutoincrement(true),
DbalSchemaFactory::columnForNodeAggregateId('nodeaggregateid')->setNotnull(false),
DbalSchemaFactory::columnForDimensionSpacePointHash('origindimensionspacepointhash')->setNotnull(false),
Expand All @@ -55,7 +56,7 @@ private function createNodeTable(): Table

private function createHierarchyRelationTable(): Table
{
$table = new Table($this->contentGraphTableNames->hierarchyRelation(), [
$table = new Table($this->tableNames->hierarchyRelation(), [
(new Column('name', Type::getType(Types::STRING)))->setLength(255)->setNotnull(false)->setCustomSchemaOption('charset', 'ascii')->setCustomSchemaOption('collation', 'ascii_general_ci'),
(new Column('position', Type::getType(Types::INTEGER)))->setNotnull(true),
DbalSchemaFactory::columnForContentStreamId('contentstreamid')->setNotnull(true),
Expand All @@ -75,7 +76,7 @@ private function createHierarchyRelationTable(): Table

private function createDimensionSpacePointsTable(): Table
{
$table = new Table($this->contentGraphTableNames->dimensionSpacePoints(), [
$table = new Table($this->tableNames->dimensionSpacePoints(), [
DbalSchemaFactory::columnForDimensionSpacePointHash('hash')->setNotnull(true),
DbalSchemaFactory::columnForDimensionSpacePoint('dimensionspacepoint')->setNotnull(true)
]);
Expand All @@ -86,7 +87,7 @@ private function createDimensionSpacePointsTable(): Table

private function createReferenceRelationTable(): Table
{
$table = new Table($this->contentGraphTableNames->referenceRelation(), [
$table = new Table($this->tableNames->referenceRelation(), [
(new Column('name', Type::getType(Types::STRING)))->setLength(255)->setNotnull(true)->setCustomSchemaOption('charset', 'ascii')->setCustomSchemaOption('collation', 'ascii_general_ci'),
(new Column('position', Type::getType(Types::INTEGER)))->setNotnull(true),
DbalSchemaFactory::columnForNodeAnchorPoint('nodeanchorpoint'),
Expand All @@ -97,4 +98,14 @@ private function createReferenceRelationTable(): Table
return $table
->setPrimaryKey(['name', 'position', 'nodeanchorpoint']);
}

private function createWorkspacesTable(): Table
{
$workspaceTable = new Table($this->tableNames->workspaces(), [
(new Column('workspacename', Type::getType(Types::STRING)))->setLength(255)->setNotnull(true)->setCustomSchemaOption('collation', self::DEFAULT_TEXT_COLLATION),
DbalSchemaFactory::columnForContentStreamId('currentcontentstreamid')->setNotNull(true),
]);

return $workspaceTable->setPrimaryKey(['workspacename']);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php

declare(strict_types=1);

namespace Neos\ContentGraph\DoctrineDbalAdapter\Domain\Projection\Feature;

use Doctrine\DBAL\Connection;
use Neos\ContentRepository\Core\Feature\WorkspaceCreation\Event\RootWorkspaceWasCreated;
use Neos\ContentRepository\Core\Feature\WorkspaceCreation\Event\WorkspaceWasCreated;
use Neos\ContentRepository\Core\Feature\WorkspaceModification\Event\WorkspaceBaseWorkspaceWasChanged;
use Neos\ContentRepository\Core\Feature\WorkspaceModification\Event\WorkspaceWasRemoved;
use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasDiscarded;
use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyDiscarded;
use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyPublished;
use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPublished;
use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Event\WorkspaceWasRebased;
use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId;
use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName;

/**
* The CurrentWorkspaceContentStreamId projection feature trait
*
* Duplicated from the projection {@see \Neos\ContentRepository\Core\Projection\Workspace\WorkspaceProjection}
* But we only require the workspace name to content stream id mapping.
*
* @internal
*/
trait CurrentWorkspaceContentStreamId
{
abstract protected function getDatabaseConnection(): Connection;

private function whenWorkspaceWasCreated(WorkspaceWasCreated $event): void
{
$this->getDatabaseConnection()->insert($this->tableNames->workspaces(), [
'workspaceName' => $event->workspaceName->value,
'currentContentStreamId' => $event->newContentStreamId->value
]);
}

private function whenRootWorkspaceWasCreated(RootWorkspaceWasCreated $event): void
{
$this->getDatabaseConnection()->insert($this->tableNames->workspaces(), [
'workspaceName' => $event->workspaceName->value,
'currentContentStreamId' => $event->newContentStreamId->value
]);
}

private function whenWorkspaceWasDiscarded(WorkspaceWasDiscarded $event): void
{
$this->updateContentStreamId($event->newContentStreamId, $event->workspaceName);
}

private function whenWorkspaceWasPartiallyDiscarded(WorkspaceWasPartiallyDiscarded $event): void
{
$this->updateContentStreamId($event->newContentStreamId, $event->workspaceName);
}

private function whenWorkspaceWasPartiallyPublished(WorkspaceWasPartiallyPublished $event): void
{
$this->updateContentStreamId($event->newSourceContentStreamId, $event->sourceWorkspaceName);
}

private function whenWorkspaceWasPublished(WorkspaceWasPublished $event): void
{
$this->updateContentStreamId($event->newSourceContentStreamId, $event->sourceWorkspaceName);
}

private function whenWorkspaceWasRebased(WorkspaceWasRebased $event): void
{
$this->updateContentStreamId($event->newContentStreamId, $event->workspaceName);
}

private function whenWorkspaceWasRemoved(WorkspaceWasRemoved $event): void
{
$this->getDatabaseConnection()->delete(
$this->tableNames->workspaces(),
['workspaceName' => $event->workspaceName->value]
);
}

private function whenWorkspaceBaseWorkspaceWasChanged(WorkspaceBaseWorkspaceWasChanged $event): void
{
$this->updateContentStreamId($event->newContentStreamId, $event->workspaceName);
}

private function updateContentStreamId(
ContentStreamId $contentStreamId,
WorkspaceName $workspaceName,
): void {
$this->getDatabaseConnection()->update($this->tableNames->workspaces(), [
'currentContentStreamId' => $contentStreamId->value,
], [
'workspaceName' => $workspaceName->value
]);
}
}
Loading