Skip to content

Commit

Permalink
Merge pull request #4791 from kitsunet/task/use-int-relationanchors
Browse files Browse the repository at this point in the history
!!! TASK: Use integers as lightweight nodeanchorpoints
  • Loading branch information
mhsdesign authored Jan 31, 2024
2 parents 6a028f6 + 0a38f93 commit 76937c3
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public function iDetachTheFollowingReferenceRelationFromItsSource(TableNode $pay
$this->dbalClient->getConnection()->update(
$this->getTableNamePrefix() . '_referencerelation',
[
'nodeanchorpoint' => 'detached'
'nodeanchorpoint' => 7777777
],
$this->transformDatasetToReferenceRelationRecord($dataset)
);
Expand Down Expand Up @@ -246,14 +246,14 @@ private function transformDatasetToHierarchyRelationRecord(array $dataset): arra
'dimensionspacepoint' => $dimensionSpacePoint->toJson(),
'dimensionspacepointhash' => $dimensionSpacePoint->hash,
'parentnodeanchor' => $parentNodeAggregateId->isNonExistent()
? UuidFactory::create()
? 9999999
: $this->findRelationAnchorPointByIds(
ContentStreamId::fromString($dataset['contentStreamId']),
$dimensionSpacePoint,
NodeAggregateId::fromString($dataset['parentNodeAggregateId'])
),
'childnodeanchor' => $childAggregateId->isNonExistent()
? UuidFactory::create()
? 8888888
: $this->findRelationAnchorPointByIds(
ContentStreamId::fromString($dataset['contentStreamId']),
$dimensionSpacePoint,
Expand All @@ -263,7 +263,7 @@ private function transformDatasetToHierarchyRelationRecord(array $dataset): arra
];
}

private function findRelationAnchorPointByDataset(array $dataset): string
private function findRelationAnchorPointByDataset(array $dataset): int
{
$dimensionSpacePoint = DimensionSpacePoint::fromArray($dataset['originDimensionSpacePoint'] ?? $dataset['dimensionSpacePoint']);

Expand All @@ -278,7 +278,7 @@ private function findRelationAnchorPointByIds(
ContentStreamId $contentStreamId,
DimensionSpacePoint $dimensionSpacePoint,
NodeAggregateId $nodeAggregateId
): string {
): int {
$nodeRecord = $this->dbalClient->getConnection()->executeQuery(
'SELECT n.relationanchorpoint
FROM ' . $this->getTableNamePrefix() . '_node n
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,27 +258,26 @@ public function markStale(): void
*/
private function whenRootNodeAggregateWithNodeWasCreated(RootNodeAggregateWithNodeWasCreated $event, EventEnvelope $eventEnvelope): void
{
$nodeRelationAnchorPoint = NodeRelationAnchorPoint::create();
$originDimensionSpacePoint = OriginDimensionSpacePoint::createWithoutDimensions();
$node = new NodeRecord(
$nodeRelationAnchorPoint,
$event->nodeAggregateId,
$originDimensionSpacePoint->coordinates,
$originDimensionSpacePoint->hash,
SerializedPropertyValues::createEmpty(),
$event->nodeTypeName,
$event->nodeAggregateClassification,
null,
Timestamps::create(
$eventEnvelope->recordedAt,
self::initiatingDateTime($eventEnvelope),
null,
$this->transactional(function () use ($event, $eventEnvelope) {
$originDimensionSpacePoint = OriginDimensionSpacePoint::createWithoutDimensions();
$node = NodeRecord::createNewInDatabase(
$this->getDatabaseConnection(),
$this->tableNamePrefix,
$event->nodeAggregateId,
$originDimensionSpacePoint->coordinates,
$originDimensionSpacePoint->hash,
SerializedPropertyValues::createEmpty(),
$event->nodeTypeName,
$event->nodeAggregateClassification,
null,
),
);
Timestamps::create(
$eventEnvelope->recordedAt,
self::initiatingDateTime($eventEnvelope),
null,
null,
),
);

$this->transactional(function () use ($node, $event) {
$node->addToDatabase($this->getDatabaseConnection(), $this->tableNamePrefix);
$this->connectHierarchy(
$event->contentStreamId,
NodeRelationAnchorPoint::forRootEdge(),
Expand Down Expand Up @@ -447,9 +446,9 @@ private function createNodeWithHierarchy(
?NodeName $nodeName,
EventEnvelope $eventEnvelope,
): void {
$nodeRelationAnchorPoint = NodeRelationAnchorPoint::create();
$node = new NodeRecord(
$nodeRelationAnchorPoint,
$node = NodeRecord::createNewInDatabase(
$this->getDatabaseConnection(),
$this->tableNamePrefix,
$nodeAggregateId,
$originDimensionSpacePoint->jsonSerialize(),
$originDimensionSpacePoint->hash,
Expand Down Expand Up @@ -490,16 +489,14 @@ private function createNodeWithHierarchy(
$this->connectHierarchy(
$contentStreamId,
$parentNode->relationAnchorPoint,
$nodeRelationAnchorPoint,
$node->relationAnchorPoint,
new DimensionSpacePointSet([$dimensionSpacePoint]),
$succeedingSibling?->relationAnchorPoint,
$nodeName
);
}
}
}

$node->addToDatabase($this->getDatabaseConnection(), $this->tableNamePrefix);
}

/**
Expand Down Expand Up @@ -984,9 +981,9 @@ protected function copyNodeToDimensionSpacePoint(
OriginDimensionSpacePoint $originDimensionSpacePoint,
EventEnvelope $eventEnvelope,
): NodeRecord {
$copyRelationAnchorPoint = NodeRelationAnchorPoint::create();
$copy = new NodeRecord(
$copyRelationAnchorPoint,
return NodeRecord::createNewInDatabase(
$this->getDatabaseConnection(),
$this->tableNamePrefix,
$sourceNode->nodeAggregateId,
$originDimensionSpacePoint->coordinates,
$originDimensionSpacePoint->hash,
Expand All @@ -1001,9 +998,6 @@ protected function copyNodeToDimensionSpacePoint(
null,
),
);
$copy->addToDatabase($this->getDatabaseConnection(), $this->tableNamePrefix);

return $copy;
}

private function whenNodeAggregateTypeWasChanged(NodeAggregateTypeWasChanged $event, EventEnvelope $eventEnvelope): void
Expand Down Expand Up @@ -1039,11 +1033,11 @@ private function updateNodeRecordWithCopyOnWrite(
// thus we do not care about different DimensionSpacePoints here (but we copy all edges)

// 1) fetch node, adjust properties, assign new Relation Anchor Point
/** @var NodeRecord $copiedNode The anchor point appears in a content stream, so there must be a node */
$copiedNode = $this->projectionContentGraph->getNodeByAnchorPoint($anchorPoint);
$copiedNode->relationAnchorPoint = NodeRelationAnchorPoint::create();
/** @var NodeRecord $originalNode The anchor point appears in a content stream, so there must be a node */
$originalNode = $this->projectionContentGraph->getNodeByAnchorPoint($anchorPoint);
$copiedNode = NodeRecord::createCopyFromNodeRecord($this->getDatabaseConnection(), $this->tableNamePrefix, $originalNode);
$result = $operations($copiedNode);
$copiedNode->addToDatabase($this->getDatabaseConnection(), $this->tableNamePrefix);
$copiedNode->updateToDatabase($this->getDatabaseConnection(), $this->tableNamePrefix);

// 2) reconnect all edges belonging to this content stream to the new "copied node".
// IMPORTANT: We need to reconnect BOTH the incoming and outgoing edges.
Expand Down Expand Up @@ -1138,7 +1132,7 @@ private function whenDimensionSpacePointWasMoved(DimensionSpacePointWasMoved $ev
]
);
while ($res = $rel->fetchAssociative()) {
$relationAnchorPoint = NodeRelationAnchorPoint::fromString($res['relationanchorpoint']);
$relationAnchorPoint = NodeRelationAnchorPoint::fromInteger($res['relationanchorpoint']);
$this->updateNodeRecordWithCopyOnWrite(
$event->contentStreamId,
$relationAnchorPoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function buildSchema(AbstractSchemaManager $schemaManager): Schema
private function createNodeTable(): Table
{
$table = new Table($this->tableNamePrefix . '_node', [
DbalSchemaFactory::columnForNodeAnchorPoint('relationanchorpoint'),
DbalSchemaFactory::columnForNodeAnchorPoint('relationanchorpoint')->setAutoincrement(true),
DbalSchemaFactory::columnForNodeAggregateId('nodeaggregateid')->setNotnull(false),
DbalSchemaFactory::columnForDimensionSpacePoint('origindimensionspacepoint')->setNotnull(false),
DbalSchemaFactory::columnForDimensionSpacePointHash('origindimensionspacepointhash')->setNotnull(false),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,32 +45,6 @@ public function __construct(
) {
}

/**
* @param Connection $databaseConnection
* @throws \Doctrine\DBAL\DBALException
*/
public function addToDatabase(Connection $databaseConnection, string $tableNamePrefix): void
{
$databaseConnection->insert($tableNamePrefix . '_node', [
'relationanchorpoint' => $this->relationAnchorPoint->value,
'nodeaggregateid' => $this->nodeAggregateId->value,
'origindimensionspacepoint' => json_encode($this->originDimensionSpacePoint),
'origindimensionspacepointhash' => $this->originDimensionSpacePointHash,
'properties' => json_encode($this->properties),
'nodetypename' => $this->nodeTypeName->value,
'classification' => $this->classification->value,
'created' => $this->timestamps->created,
'originalcreated' => $this->timestamps->originalCreated,
'lastmodified' => $this->timestamps->lastModified,
'originallastmodified' => $this->timestamps->originalLastModified,
], [
'created' => Types::DATETIME_IMMUTABLE,
'originalcreated' => Types::DATETIME_IMMUTABLE,
'lastmodified' => Types::DATETIME_IMMUTABLE,
'originallastmodified' => Types::DATETIME_IMMUTABLE,
]);
}

/**
* @param Connection $databaseConnection
* @throws \Doctrine\DBAL\DBALException
Expand Down Expand Up @@ -112,13 +86,13 @@ public function removeFromDatabase(Connection $databaseConnection, string $table
}

/**
* @param array<string,string> $databaseRow
* @param array<string,mixed> $databaseRow
* @throws \Exception
*/
public static function fromDatabaseRow(array $databaseRow): self
{
return new self(
NodeRelationAnchorPoint::fromString($databaseRow['relationanchorpoint']),
NodeRelationAnchorPoint::fromInteger($databaseRow['relationanchorpoint']),
NodeAggregateId::fromString($databaseRow['nodeaggregateid']),
json_decode($databaseRow['origindimensionspacepoint'], true),
$databaseRow['origindimensionspacepointhash'],
Expand All @@ -135,6 +109,96 @@ public static function fromDatabaseRow(array $databaseRow): self
);
}

/**
* Insert a node record with the given data and return it.
*
* @param Connection $databaseConnection
* @param string $tableNamePrefix
* @param NodeAggregateId $nodeAggregateId
* @param array<string,string> $originDimensionSpacePoint
* @param string $originDimensionSpacePointHash
* @param SerializedPropertyValues $properties
* @param NodeTypeName $nodeTypeName
* @param NodeAggregateClassification $classification
* @param NodeName|null $nodeName
* @param Timestamps $timestamps
* @return self
* @throws \Doctrine\DBAL\Exception
*/
public static function createNewInDatabase(
Connection $databaseConnection,
string $tableNamePrefix,
NodeAggregateId $nodeAggregateId,
array $originDimensionSpacePoint,
string $originDimensionSpacePointHash,
SerializedPropertyValues $properties,
NodeTypeName $nodeTypeName,
NodeAggregateClassification $classification,
/** Transient node name to store a node name after fetching a node with hierarchy (not always available) */
?NodeName $nodeName,
Timestamps $timestamps,
): self {
$databaseConnection->insert($tableNamePrefix . '_node', [
'nodeaggregateid' => $nodeAggregateId->value,
'origindimensionspacepoint' => json_encode($originDimensionSpacePoint),
'origindimensionspacepointhash' => $originDimensionSpacePointHash,
'properties' => json_encode($properties),
'nodetypename' => $nodeTypeName->value,
'classification' => $classification->value,
'created' => $timestamps->created,
'originalcreated' => $timestamps->originalCreated,
'lastmodified' => $timestamps->lastModified,
'originallastmodified' => $timestamps->originalLastModified,
], [
'created' => Types::DATETIME_IMMUTABLE,
'originalcreated' => Types::DATETIME_IMMUTABLE,
'lastmodified' => Types::DATETIME_IMMUTABLE,
'originallastmodified' => Types::DATETIME_IMMUTABLE,
]);

$relationAnchorPoint = NodeRelationAnchorPoint::fromInteger((int)$databaseConnection->lastInsertId());

return new self(
$relationAnchorPoint,
$nodeAggregateId,
$originDimensionSpacePoint,
$originDimensionSpacePointHash,
$properties,
$nodeTypeName,
$classification,
$nodeName,
$timestamps
);
}

/**
* Creates a copy of this NodeRecord with a new anchor point.
*
* @param Connection $databaseConnection
* @param string $tableNamePrefix
* @param NodeRecord $copyFrom
* @return self
* @throws \Doctrine\DBAL\Exception
*/
public static function createCopyFromNodeRecord(
Connection $databaseConnection,
string $tableNamePrefix,
NodeRecord $copyFrom
): self {
return self::createNewInDatabase(
$databaseConnection,
$tableNamePrefix,
$copyFrom->nodeAggregateId,
$copyFrom->originDimensionSpacePoint,
$copyFrom->originDimensionSpacePointHash,
$copyFrom->properties,
$copyFrom->nodeTypeName,
$copyFrom->classification,
$copyFrom->nodeName,
$copyFrom->timestamps
);
}

private static function parseDateTimeString(string $string): \DateTimeImmutable
{
$result = \DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $string);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,37 @@

namespace Neos\ContentGraph\DoctrineDbalAdapter\Domain\Projection;

use Neos\ContentRepository\Core\SharedModel\Id\UuidFactory;

/**
* The node relation anchor value object
*
* @internal
*/
class NodeRelationAnchorPoint implements \JsonSerializable
{
private function __construct(
public readonly string $value
) {
}
public readonly int $value;

public static function create(): self
private function __construct(int $value)
{
return new self(UuidFactory::create());
if ($value < 0) {
throw new \InvalidArgumentException('A NodeRelationAnchorPoint cannot be negative, got %d', $value);
}

$this->value = $value;
}

public static function forRootEdge(): self
{
return new self('00000000-0000-0000-0000-000000000000');
return new self(0);
}

public static function fromString(string $value): self
public static function fromInteger(int $value): self
{
return new self($value);
}

public function jsonSerialize(): string
{
return $this->value;
return (string)$this->value;
}

public function equals(self $other): bool
Expand Down
Loading

0 comments on commit 76937c3

Please sign in to comment.