Skip to content

Commit

Permalink
Merge pull request neos#5042 from neos/task/workspaceAwareNode
Browse files Browse the repository at this point in the history
FEATURE: workspace aware Node (introduce new `NodeAdress`)
  • Loading branch information
kitsunet authored May 13, 2024
2 parents 6cd089a + 4e5993a commit 96ce9e9
Show file tree
Hide file tree
Showing 35 changed files with 537 additions and 256 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ public function __construct(
$this->nodeQueryBuilder = new NodeQueryBuilder($this->client->getConnection(), $this->tableNames);
}

public function getContentRepositoryId(): ContentRepositoryId
{
return $this->contentRepositoryId;
}

public function getWorkspaceName(): WorkspaceName
{
return $this->workspaceName;
}

public function getSubgraph(
DimensionSpacePoint $dimensionSpacePoint,
VisibilityConstraints $visibilityConstraints
Expand Down Expand Up @@ -171,6 +181,7 @@ public function findNodeAggregateById(

return $this->nodeFactory->mapNodeRowsToNodeAggregate(
$this->fetchRows($queryBuilder),
$this->workspaceName,
$this->contentStreamId,
VisibilityConstraints::withoutRestrictions()
);
Expand Down Expand Up @@ -236,6 +247,7 @@ public function findParentNodeAggregateByChildOriginDimensionSpacePoint(NodeAggr

return $this->nodeFactory->mapNodeRowsToNodeAggregate(
$this->fetchRows($queryBuilder),
$this->workspaceName,
$this->contentStreamId,
VisibilityConstraints::withoutRestrictions()
);
Expand Down Expand Up @@ -304,7 +316,7 @@ public function countNodes(): int
try {
return (int)$result->fetchOne();
} catch (DriverException | DBALException $e) {
throw new \RuntimeException(sprintf('Failed to fetch rows from database: %s', $e->getMessage()), 1701444590, $e);
throw new \RuntimeException(sprintf('Failed to count rows in database: %s', $e->getMessage()), 1701444590, $e);
}
}

Expand All @@ -325,6 +337,7 @@ private function mapQueryBuilderToNodeAggregate(QueryBuilder $queryBuilder): ?No
{
return $this->nodeFactory->mapNodeRowsToNodeAggregate(
$this->fetchRows($queryBuilder),
$this->workspaceName,
$this->contentStreamId,
VisibilityConstraints::withoutRestrictions()
);
Expand All @@ -338,6 +351,7 @@ private function mapQueryBuilderToNodeAggregates(QueryBuilder $queryBuilder): it
{
return $this->nodeFactory->mapNodeRowsToNodeAggregates(
$this->fetchRows($queryBuilder),
$this->workspaceName,
$this->contentStreamId,
VisibilityConstraints::withoutRestrictions()
);
Expand All @@ -359,13 +373,6 @@ private function fetchRows(QueryBuilder $queryBuilder): array
}
}

/** The workspace this content graph is operating on */
public function getWorkspaceName(): WorkspaceName
{
return $this->workspaceName;
}

/** @internal The content stream id where the workspace name points to for this instance */
public function getContentStreamId(): ContentStreamId
{
return $this->contentStreamId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ final class ContentSubgraph implements ContentSubgraphInterface

public function __construct(
private readonly ContentRepositoryId $contentRepositoryId,
/** @phpstan-ignore-next-line */
private readonly WorkspaceName $workspaceName,
private readonly ContentStreamId $contentStreamId,
private readonly DimensionSpacePoint $dimensionSpacePoint,
Expand All @@ -105,14 +104,24 @@ public function __construct(
$this->nodeQueryBuilder = new NodeQueryBuilder($this->client->getConnection(), $tableNames);
}

public function getIdentity(): ContentSubgraphIdentity
public function getContentRepositoryId(): ContentRepositoryId
{
return ContentSubgraphIdentity::create(
$this->contentRepositoryId,
$this->contentStreamId,
$this->dimensionSpacePoint,
$this->visibilityConstraints
);
return $this->contentRepositoryId;
}

public function getWorkspaceName(): WorkspaceName
{
return $this->workspaceName;
}

public function getDimensionSpacePoint(): DimensionSpacePoint
{
return $this->dimensionSpacePoint;
}

public function getVisibilityConstraints(): VisibilityConstraints
{
return $this->visibilityConstraints;
}

public function findChildNodes(NodeAggregateId $parentNodeAggregateId, FindChildNodesFilter $filter): Nodes
Expand Down Expand Up @@ -290,7 +299,13 @@ public function findSubtree(NodeAggregateId $entryNodeAggregateId, FindSubtreeFi
foreach (array_reverse($result) as $nodeData) {
$nodeAggregateId = $nodeData['nodeaggregateid'];
$parentNodeAggregateId = $nodeData['parentNodeAggregateId'];
$node = $this->nodeFactory->mapNodeRowToNode($nodeData, $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints);
$node = $this->nodeFactory->mapNodeRowToNode(
$nodeData,
$this->workspaceName,
$this->contentStreamId,
$this->dimensionSpacePoint,
$this->visibilityConstraints
);
$subtree = new Subtree((int)$nodeData['level'], $node, array_key_exists($nodeAggregateId, $subtreesByParentNodeId) ? array_reverse($subtreesByParentNodeId[$nodeAggregateId]) : []);
if ($subtree->level === 0) {
return $subtree;
Expand Down Expand Up @@ -319,6 +334,7 @@ public function findAncestorNodes(NodeAggregateId $entryNodeAggregateId, FindAnc

return $this->nodeFactory->mapNodeRowsToNodes(
$nodeRows,
$this->workspaceName,
$this->contentStreamId,
$this->dimensionSpacePoint,
$this->visibilityConstraints
Expand Down Expand Up @@ -374,6 +390,7 @@ public function findClosestNode(NodeAggregateId $entryNodeAggregateId, FindClose
);
return $this->nodeFactory->mapNodeRowsToNodes(
$nodeRows,
$this->workspaceName,
$this->contentStreamId,
$this->dimensionSpacePoint,
$this->visibilityConstraints
Expand All @@ -391,7 +408,13 @@ public function findDescendantNodes(NodeAggregateId $entryNodeAggregateId, FindD
}
$queryBuilderCte->addOrderBy('level')->addOrderBy('position');
$nodeRows = $this->fetchCteResults($queryBuilderInitial, $queryBuilderRecursive, $queryBuilderCte, 'tree');
return $this->nodeFactory->mapNodeRowsToNodes($nodeRows, $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints);
return $this->nodeFactory->mapNodeRowsToNodes(
$nodeRows,
$this->workspaceName,
$this->contentStreamId,
$this->dimensionSpacePoint,
$this->visibilityConstraints
);
}

public function countDescendantNodes(NodeAggregateId $entryNodeAggregateId, CountDescendantNodesFilter $filter): int
Expand All @@ -416,9 +439,15 @@ public function countNodes(): int
return $result;
}

public function jsonSerialize(): ContentSubgraphIdentity
/**
* @return array<string,mixed>
*/
public function jsonSerialize(): array
{
return $this->getIdentity();
return [
'workspaceName' => $this->workspaceName,
'dimensionSpacePoint' => $this->dimensionSpacePoint,
];
}

/** ------------------------------------------- */
Expand Down Expand Up @@ -668,6 +697,7 @@ private function fetchNode(QueryBuilder $queryBuilder): ?Node
}
return $this->nodeFactory->mapNodeRowToNode(
$nodeRow,
$this->workspaceName,
$this->contentStreamId,
$this->dimensionSpacePoint,
$this->visibilityConstraints
Expand All @@ -681,7 +711,13 @@ private function fetchNodes(QueryBuilder $queryBuilder): Nodes
} catch (DbalDriverException | DbalException $e) {
throw new \RuntimeException(sprintf('Failed to fetch nodes: %s', $e->getMessage()), 1678292896, $e);
}
return $this->nodeFactory->mapNodeRowsToNodes($nodeRows, $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints);
return $this->nodeFactory->mapNodeRowsToNodes(
$nodeRows,
$this->workspaceName,
$this->contentStreamId,
$this->dimensionSpacePoint,
$this->visibilityConstraints
);
}

private function fetchCount(QueryBuilder $queryBuilder): int
Expand All @@ -700,7 +736,7 @@ private function fetchReferences(QueryBuilder $queryBuilder): References
} catch (DbalDriverException | DbalException $e) {
throw new \RuntimeException(sprintf('Failed to fetch references: %s', $e->getMessage()), 1678364944, $e);
}
return $this->nodeFactory->mapReferenceRowsToReferences($referenceRows, $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints);
return $this->nodeFactory->mapReferenceRowsToReferences($referenceRows, $this->workspaceName, $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint;
use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePointSet;
use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint;
use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePointSet;
use Neos\ContentRepository\Core\Feature\NodeModification\Dto\SerializedPropertyValues;
use Neos\ContentRepository\Core\Feature\SubtreeTagging\Dto\SubtreeTags;
Expand All @@ -38,11 +37,13 @@
use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints;
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
use Neos\ContentRepository\Core\SharedModel\Exception\NodeTypeNotFoundException;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
use Neos\ContentRepository\Core\SharedModel\Node\NodeName;
use Neos\ContentRepository\Core\SharedModel\Node\ReferenceName;
use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId;
use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName;

/**
* Implementation detail of ContentGraph and ContentSubgraph
Expand All @@ -64,6 +65,7 @@ public function __construct(
*/
public function mapNodeRowToNode(
array $nodeRow,
WorkspaceName $workspaceName,
ContentStreamId $contentStreamId,
DimensionSpacePoint $dimensionSpacePoint,
VisibilityConstraints $visibilityConstraints
Expand All @@ -73,17 +75,13 @@ public function mapNodeRowToNode(
: null;

return Node::create(
ContentSubgraphIdentity::create(
$this->contentRepositoryId,
$contentStreamId,
$dimensionSpacePoint,
$visibilityConstraints
),
$this->contentRepositoryId,
$workspaceName,
$dimensionSpacePoint,
NodeAggregateId::fromString($nodeRow['nodeaggregateid']),
$this->dimensionSpacePointRepository->getOriginDimensionSpacePointByHash($nodeRow['origindimensionspacepointhash']),
NodeAggregateClassification::from($nodeRow['classification']),
NodeTypeName::fromString($nodeRow['nodetypename']),
$nodeType,
$this->createPropertyCollectionFromJsonString($nodeRow['properties']),
isset($nodeRow['name']) ? NodeName::fromString($nodeRow['name']) : null,
self::extractNodeTagsFromJson($nodeRow['subtreetags']),
Expand All @@ -93,16 +91,30 @@ public function mapNodeRowToNode(
isset($nodeRow['lastmodified']) ? self::parseDateTimeString($nodeRow['lastmodified']) : null,
isset($nodeRow['originallastmodified']) ? self::parseDateTimeString($nodeRow['originallastmodified']) : null,
),
$visibilityConstraints,
$nodeType,
$contentStreamId
);
}

/**
* @param array<int, array<string, mixed>> $nodeRows
*/
public function mapNodeRowsToNodes(array $nodeRows, ContentStreamId $contentStreamId, DimensionSpacePoint $dimensionSpacePoint, VisibilityConstraints $visibilityConstraints): Nodes
{
public function mapNodeRowsToNodes(
array $nodeRows,
WorkspaceName $workspaceName,
ContentStreamId $contentStreamId,
DimensionSpacePoint $dimensionSpacePoint,
VisibilityConstraints $visibilityConstraints
): Nodes {
return Nodes::fromArray(
array_map(fn (array $nodeRow) => $this->mapNodeRowToNode($nodeRow, $contentStreamId, $dimensionSpacePoint, $visibilityConstraints), $nodeRows)
array_map(fn (array $nodeRow) => $this->mapNodeRowToNode(
$nodeRow,
$workspaceName,
$contentStreamId,
$dimensionSpacePoint,
$visibilityConstraints
), $nodeRows)
);
}

Expand All @@ -119,6 +131,7 @@ public function createPropertyCollectionFromJsonString(string $jsonString): Prop
*/
public function mapReferenceRowsToReferences(
array $nodeRows,
WorkspaceName $workspaceName,
ContentStreamId $contentStreamId,
DimensionSpacePoint $dimensionSpacePoint,
VisibilityConstraints $visibilityConstraints
Expand All @@ -127,6 +140,7 @@ public function mapReferenceRowsToReferences(
foreach ($nodeRows as $nodeRow) {
$node = $this->mapNodeRowToNode(
$nodeRow,
$workspaceName,
$contentStreamId,
$dimensionSpacePoint,
$visibilityConstraints
Expand All @@ -149,6 +163,7 @@ public function mapReferenceRowsToReferences(
*/
public function mapNodeRowsToNodeAggregate(
array $nodeRows,
WorkspaceName $workspaceName,
ContentStreamId $contentStreamId,
VisibilityConstraints $visibilityConstraints
): ?NodeAggregate {
Expand All @@ -175,6 +190,7 @@ public function mapNodeRowsToNodeAggregate(
// ... so we handle occupation exactly once ...
$nodesByOccupiedDimensionSpacePoints[$occupiedDimensionSpacePoint->hash] = $this->mapNodeRowToNode(
$nodeRow,
$workspaceName,
$contentStreamId,
$occupiedDimensionSpacePoint->toDimensionSpacePoint(),
$visibilityConstraints
Expand Down Expand Up @@ -230,6 +246,7 @@ public function mapNodeRowsToNodeAggregate(
*/
public function mapNodeRowsToNodeAggregates(
iterable $nodeRows,
WorkspaceName $workspaceName,
ContentStreamId $contentStreamId,
VisibilityConstraints $visibilityConstraints
): iterable {
Expand All @@ -256,6 +273,7 @@ public function mapNodeRowsToNodeAggregates(
$nodesByOccupiedDimensionSpacePointsByNodeAggregate
[$rawNodeAggregateId][$occupiedDimensionSpacePoint->hash] = $this->mapNodeRowToNode(
$nodeRow,
$workspaceName,
$contentStreamId,
$occupiedDimensionSpacePoint->toDimensionSpacePoint(),
$visibilityConstraints
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ public function __construct(
$this->nodeFactory = $nodeFactory;
}

public function getContentRepositoryId(): ContentRepositoryId
{
return $this->contentRepositoryId;
}

public function getWorkspaceName(): WorkspaceName
{
return $this->workspaceName;
}

public function getSubgraph(
DimensionSpacePoint $dimensionSpacePoint,
VisibilityConstraints $visibilityConstraints
Expand All @@ -77,6 +87,7 @@ public function getSubgraph(
$this->subhypergraphs[$index] = new ContentSubhypergraph(
$this->contentRepositoryId,
$this->contentStreamId,
$this->workspaceName,
$dimensionSpacePoint,
$visibilityConstraints,
$this->databaseClient,
Expand Down Expand Up @@ -307,11 +318,6 @@ private function getDatabaseConnection(): DatabaseConnection
return $this->databaseClient->getConnection();
}

public function getWorkspaceName(): WorkspaceName
{
return $this->workspaceName;
}

public function getContentStreamId(): ContentStreamId
{
return $this->contentStreamId;
Expand Down
Loading

0 comments on commit 96ce9e9

Please sign in to comment.