Skip to content

Commit

Permalink
Merge pull request #11 from bitExpert-forks/inmemory-fix-unique-const…
Browse files Browse the repository at this point in the history
…raints-on-update

Fix unique contraint checks on updates
  • Loading branch information
codeliner authored Jan 10, 2020
2 parents bd64355 + 3a57b53 commit e2ec385
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 4 deletions.
20 changes: 16 additions & 4 deletions src/InMemoryDocumentStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,15 @@ private function assertUniqueFieldConstraint(string $collectionName, string $doc

$check = new EqFilter($index->field(), $value);

$existingDocs = $this->filterDocs($collectionName, $check);
foreach ($this->inMemoryConnection['documents'][$collectionName] as $existingDocId => $existingDoc) {
if (!$check->match($existingDoc, (string)$existingDocId)) {
continue;
}

if ((string)$existingDocId === $docId) {
continue;
}

foreach ($existingDocs as $existingDoc) {
throw new RuntimeException(
$errMsg ?? "Unique constraint violation. Cannot insert or update document with id $docId, because a document with same value for field: {$index->field()} exists already!"
);
Expand Down Expand Up @@ -434,9 +440,15 @@ private function assertMultiFieldUniqueConstraint(string $collectionName, string
$checkList = $checkList[0];
}

$existingDocs = $this->filterDocs($collectionName, $checkList);
foreach ($this->inMemoryConnection['documents'][$collectionName] as $existingDocId => $existingDoc) {
if (!$checkList->match($existingDoc, (string)$existingDocId)) {
continue;
}

if ((string)$existingDocId === $docId) {
continue;
}

foreach ($existingDocs as $existingDoc) {
$fieldNamesStr = implode(", ", $fieldNames);
throw new RuntimeException(
$errMsg ?? "Unique constraint violation. Cannot insert or update document with id $docId, because a document with same values for fields: {$fieldNamesStr} exists already!"
Expand Down
56 changes: 56 additions & 0 deletions tests/InMemoryDocumentStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,32 @@ public function it_ensures_unique_constraints_for_a_field()
$this->store->addDoc('test', '3', ['some' => ['prop' => 'foo']]);
}

/**
* @test
*/
public function it_ensures_unique_constraints_for_a_field_for_update()
{
$this->store->addCollection('test', FieldIndex::namedIndexForField('unique_prop_idx', 'some.prop', FieldIndex::SORT_ASC, true));

$this->store->addDoc('test', '1', ['some' => ['prop' => 'foo']]);
$this->store->addDoc('test', '2', ['some' => ['prop' => 'bar']]);

$this->expectExceptionMessageRegExp('/^Unique constraint violation/');
$this->store->updateDoc('test', '2', ['some' => ['prop' => 'foo']]);
}

/**
* @test
* @doesNotPerformAssertions
*/
public function it_allows_updating_with_unique_constraints_for_a_field()
{
$this->store->addCollection('test', FieldIndex::namedIndexForField('unique_prop_idx', 'some.prop', FieldIndex::SORT_ASC, true));

$this->store->addDoc('test', '1', ['some' => ['prop' => 'foo']]);

$this->store->updateDoc('test', '1', ['some' => ['prop' => 'foo', 'new' => 'prop']]);
}

/**
* @test
Expand All @@ -130,6 +155,22 @@ public function it_ensures_unique_constraints_for_multiple_fields()

$this->store->addCollection('test', $multiFieldIndex);

$this->store->addDoc('test', '1', ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat']]]);
$this->store->addDoc('test', '2', ['some' => ['prop' => 'bar', 'other' => ['prop' => 'bat']]]);

$this->expectExceptionMessageRegExp('/^Unique constraint violation/');
$this->store->addDoc('test', '4', ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat']]]);
}

/**
* @test
*/
public function it_ensures_unique_constraints_for_multiple_fields_for_update()
{
$multiFieldIndex = MultiFieldIndex::forFields(['some.prop', 'some.other.prop'], true);

$this->store->addCollection('test', $multiFieldIndex);

$this->store->addDoc('test', '1', ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat']]]);
$this->store->addDoc('test', '2', ['some' => ['prop' => 'bar', 'other' => ['prop' => 'bat']]]);
$this->store->addDoc('test', '3', ['some' => ['prop' => 'bar']]);
Expand All @@ -138,6 +179,21 @@ public function it_ensures_unique_constraints_for_multiple_fields()
$this->store->updateDoc('test', '2', ['some' => ['prop' => 'foo']]);
}

/**
* @test
* @doesNotPerformAssertions
*/
public function it_allows_updating_with_unique_constraints_for_multiple_fields()
{
$multiFieldIndex = MultiFieldIndex::forFields(['some.prop', 'some.other.prop'], true);

$this->store->addCollection('test', $multiFieldIndex);

$this->store->addDoc('test', '1', ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat']]]);

$this->store->updateDoc('test', '1', ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat'], 'new' => 'prop']]);
}

/**
* @test
*/
Expand Down

0 comments on commit e2ec385

Please sign in to comment.