Skip to content
Merged
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 @@ -85,11 +85,12 @@
use FreeDSx\Ldap\Server\Backend\Write\Operation\ComputeUpdateHandler;
use FreeDSx\Ldap\Server\Backend\Write\Operation\DeleteEntryHandler;
use FreeDSx\Ldap\Server\Backend\Write\Operation\DeleteSubtreeHandler;
use FreeDSx\Ldap\Server\Backend\Write\Operation\SubtreeChunkRemover;
use FreeDSx\Ldap\Server\Backend\Write\Operation\SubtreeDelete\SubtreeChunkRemover;
use FreeDSx\Ldap\Server\Backend\Write\Operation\EntryMutation;
use FreeDSx\Ldap\Server\Backend\Write\Operation\EntryPlacementGuard;
use FreeDSx\Ldap\Server\Backend\Write\Operation\MoveEntryHandler;
use FreeDSx\Ldap\Server\Backend\Write\Operation\LinkedChanges;
use FreeDSx\Ldap\Server\Backend\Write\Operation\Linked\LinkedChangeReplay;
use FreeDSx\Ldap\Server\Backend\Write\Operation\Linked\LinkedChanges;
use FreeDSx\Ldap\Server\Backend\Write\Operation\UpdateEntryHandler;
use FreeDSx\Ldap\Server\Backend\Write\Schema\SchemaViolationGate;
use FreeDSx\Ldap\Server\Subentry\SubentryPlacementGuard;
Expand Down Expand Up @@ -439,6 +440,7 @@ private function makeUpdateEntryHandler(Container $container): UpdateEntryHandle
mutation: $container->get(EntryMutation::class),
placement: $container->get(EntryPlacementGuard::class),
linkedChanges: $container->get(LinkedChanges::class),
replay: $container->get(LinkedChangeReplay::class),
);
}

Expand Down
13 changes: 10 additions & 3 deletions src/FreeDSx/Ldap/Container/Provider/StorageContainerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
use FreeDSx\Ldap\Server\Backend\Storage\Adapter\EntryIndexReindexer;
use FreeDSx\Ldap\Server\Backend\Storage\Adapter\InMemoryStorage;
use FreeDSx\Ldap\Schema\Matching\EqualityComparatorResolver;
use FreeDSx\Ldap\Schema\Validation\SchemaValidator;
use FreeDSx\Ldap\Schema\Validation\Syntax\AttributeSyntaxResolver;
use FreeDSx\Ldap\Server\Backend\Storage\Adapter\Pdo\Query\EntryLister;
use FreeDSx\Ldap\Server\Backend\Storage\Adapter\Pdo\Query\EntryReader;
Expand All @@ -33,7 +32,8 @@
use FreeDSx\Ldap\Server\Backend\Storage\Capability\RowLockableInterface;
use FreeDSx\Ldap\Server\Backend\Storage\Capability\UnlockedRows;
use FreeDSx\Ldap\Server\Backend\Storage\Filter\LinkedLeafWitness;
use FreeDSx\Ldap\Server\Backend\Write\Operation\LinkedChanges;
use FreeDSx\Ldap\Server\Backend\Write\Operation\Linked\LinkedChangeReplay;
use FreeDSx\Ldap\Server\Backend\Write\Operation\Linked\LinkedChanges;
use FreeDSx\Ldap\Server\Backend\Storage\Contract\ListEntryInterface;
use FreeDSx\Ldap\Server\Backend\Storage\Contract\ReadEntryInterface;
use FreeDSx\Ldap\Server\Backend\Storage\Contract\TransactionalWriteInterface;
Expand Down Expand Up @@ -76,6 +76,7 @@ public function factories(): array
LinkedValueLookupInterface::class => $this->makeLinkedValueLookup(...),
LinkedLeafWitness::class => $this->makeLinkedLeafWitness(...),
LinkedChanges::class => $this->makeLinkedChanges(...),
LinkedChangeReplay::class => $this->makeLinkedChangeReplay(...),
EntryIndexReindexer::class => $this->makeEntryIndexReindexer(...),
ChangeJournalInterface::class => $this->makeChangeJournal(...),
];
Expand Down Expand Up @@ -146,10 +147,16 @@ private function makeLinkedChanges(Container $container): LinkedChanges
{
return new LinkedChanges(
$container->get(LinkedAttributes::class),
$container->get(ServerOptions::class)->getSchema(),
);
}

private function makeLinkedChangeReplay(Container $container): LinkedChangeReplay
{
return new LinkedChangeReplay(
$this->isPdo($container)
? $container->get(EntryLinkWriter::class)
: $container->get(InMemoryStorage::class),
$container->get(SchemaValidator::class),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,28 @@ private function linkedValuesOf(
)));
}

/**
* @param array<string> $held
* @param list<string> $removed
*
* @return list<string>
*/
private static function withoutLinkValues(
array $held,
array $removed,
): array {
$gone = [];

foreach ($removed as $value) {
$gone[Dn::normalizedOrNull($value) ?? $value] = true;
}

return array_values(array_filter(
$held,
static fn(string $value): bool => !isset($gone[Dn::normalizedOrNull($value) ?? $value]),
));
}

/**
* The entry carrying the linked values the one it replaces held.
*/
Expand Down Expand Up @@ -479,7 +501,7 @@ private function withLinks(

foreach ($links->names() as $name) {
$values = array_merge(
array_diff(
self::withoutLinkValues(
$previous?->get($name, true)?->getValues() ?? [],
$links->removed($name),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,25 @@ public function heldLinkValues(
return [];
}
$held = [];
$params = [
$owner->normalizedString(),
Attribute::normalizeName($attribute),
...array_keys($asked),
];

foreach ($this->rowsOf($this->dialect->queryHeldLinkValues(count($asked)), $params) as $row) {
$held[] = $asked[$this->stringColumn($row['lc_dn'] ?? null)] ?? null;

$chunks = array_chunk(
array_keys($asked),
self::DNS_PER_STATEMENT,
);

foreach ($chunks as $chunk) {
$rows = $this->rowsOf(
$this->dialect->queryHeldLinkValues(count($chunk)),
[
$owner->normalizedString(),
Attribute::normalizeName($attribute),
...$chunk,
],
);

foreach ($rows as $row) {
$held[] = $asked[$this->stringColumn($row['lc_dn'] ?? null)] ?? null;
}
}

return array_values(array_filter($held));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use FreeDSx\Ldap\Entry\Entry;
use FreeDSx\Ldap\Exception\OperationException;
use FreeDSx\Ldap\Server\Backend\Storage\Link\LinkDelta;
use FreeDSx\Ldap\Server\Backend\Write\Command\UpdateCommand;
use FreeDSx\Ldap\Server\Backend\Write\WriteContext;

Expand All @@ -38,11 +39,13 @@ private function updated(
UpdateCommand $command,
WriteContext $context,
Entry $current,
LinkDelta $links = new LinkDelta(),
): Entry {
$updated = $this->mutation->forUpdate(
$current,
$command,
$context,
$links,
);
$this->placement->assertUpdatePlacement(
$updated,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
use FreeDSx\Ldap\Exception\OperationException;
use FreeDSx\Ldap\Operation\ResultCode;
use FreeDSx\Ldap\Server\Backend\Write\Command\DeleteSubtreeCommand;
use FreeDSx\Ldap\Server\Backend\Write\Operation\SubtreeDelete\DeletionQueue;
use FreeDSx\Ldap\Server\Backend\Write\Operation\SubtreeDelete\SubtreeChunkRemover;
use FreeDSx\Ldap\Server\Backend\Write\Operation\SubtreeDelete\SubtreeDeleteProgress;
use FreeDSx\Ldap\Server\Backend\Write\WriteContext;
use FreeDSx\Ldap\Server\Clock\Sleeper\BlockingSleeper;
use FreeDSx\Ldap\Server\Clock\Sleeper\SleeperInterface;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@

namespace FreeDSx\Ldap\Server\Backend\Write\Operation;

use FreeDSx\Ldap\Entry\Attribute;
use FreeDSx\Ldap\Entry\Entry;
use FreeDSx\Ldap\Exception\OperationException;
use FreeDSx\Ldap\Server\Backend\Storage\Adapter\Operation\WriteEntryOperationHandler;
use FreeDSx\Ldap\Server\Backend\Storage\Link\LinkDelta;
use FreeDSx\Ldap\Server\Backend\Write\OperationalAttributeGenerator;
use FreeDSx\Ldap\Server\Backend\Write\Command\MoveCommand;
use FreeDSx\Ldap\Server\Backend\Write\Command\UpdateCommand;
Expand All @@ -36,17 +38,23 @@ public function __construct(
) {}

/**
* @param LinkDelta $links Linked values applied apart from the entry, whose additions are held to the schema with it.
*
* @throws OperationException
*/
public function forUpdate(
Entry $entry,
UpdateCommand $command,
WriteContext $context,
LinkDelta $links = new LinkDelta(),
): Entry {
$updated = $this->entryHandler->apply($entry, $command);
$this->schemaGate->assertModifyAllowed(
$command,
$updated,
self::withLinkedAdditions(
$updated,
$links,
),
$context,
);
$this->operationalAttrs->applyForModify(
Expand Down Expand Up @@ -78,4 +86,29 @@ public function forMove(

return $moved;
}

private static function withLinkedAdditions(
Entry $entry,
LinkDelta $links,
): Entry {
if ($links->isEmpty()) {
return $entry;
}
$copy = $entry->makeCopy();

foreach ($links->names() as $name) {
$added = $links->added($name);

if ($added === []) {
continue;
}

$copy->add(new Attribute(
$name,
...$added,
));
}

return $copy;
}
}
Loading
Loading