Skip to content

Commit e2ec385

Browse files
author
Alexander Miertsch
authored
Merge pull request #11 from bitExpert-forks/inmemory-fix-unique-constraints-on-update
Fix unique contraint checks on updates
2 parents bd64355 + 3a57b53 commit e2ec385

File tree

2 files changed

+72
-4
lines changed

2 files changed

+72
-4
lines changed

src/InMemoryDocumentStore.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,15 @@ private function assertUniqueFieldConstraint(string $collectionName, string $doc
379379

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

382-
$existingDocs = $this->filterDocs($collectionName, $check);
382+
foreach ($this->inMemoryConnection['documents'][$collectionName] as $existingDocId => $existingDoc) {
383+
if (!$check->match($existingDoc, (string)$existingDocId)) {
384+
continue;
385+
}
386+
387+
if ((string)$existingDocId === $docId) {
388+
continue;
389+
}
383390

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

437-
$existingDocs = $this->filterDocs($collectionName, $checkList);
443+
foreach ($this->inMemoryConnection['documents'][$collectionName] as $existingDocId => $existingDoc) {
444+
if (!$checkList->match($existingDoc, (string)$existingDocId)) {
445+
continue;
446+
}
447+
448+
if ((string)$existingDocId === $docId) {
449+
continue;
450+
}
438451

439-
foreach ($existingDocs as $existingDoc) {
440452
$fieldNamesStr = implode(", ", $fieldNames);
441453
throw new RuntimeException(
442454
$errMsg ?? "Unique constraint violation. Cannot insert or update document with id $docId, because a document with same values for fields: {$fieldNamesStr} exists already!"

tests/InMemoryDocumentStoreTest.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,32 @@ public function it_ensures_unique_constraints_for_a_field()
119119
$this->store->addDoc('test', '3', ['some' => ['prop' => 'foo']]);
120120
}
121121

122+
/**
123+
* @test
124+
*/
125+
public function it_ensures_unique_constraints_for_a_field_for_update()
126+
{
127+
$this->store->addCollection('test', FieldIndex::namedIndexForField('unique_prop_idx', 'some.prop', FieldIndex::SORT_ASC, true));
128+
129+
$this->store->addDoc('test', '1', ['some' => ['prop' => 'foo']]);
130+
$this->store->addDoc('test', '2', ['some' => ['prop' => 'bar']]);
131+
132+
$this->expectExceptionMessageRegExp('/^Unique constraint violation/');
133+
$this->store->updateDoc('test', '2', ['some' => ['prop' => 'foo']]);
134+
}
122135

136+
/**
137+
* @test
138+
* @doesNotPerformAssertions
139+
*/
140+
public function it_allows_updating_with_unique_constraints_for_a_field()
141+
{
142+
$this->store->addCollection('test', FieldIndex::namedIndexForField('unique_prop_idx', 'some.prop', FieldIndex::SORT_ASC, true));
143+
144+
$this->store->addDoc('test', '1', ['some' => ['prop' => 'foo']]);
145+
146+
$this->store->updateDoc('test', '1', ['some' => ['prop' => 'foo', 'new' => 'prop']]);
147+
}
123148

124149
/**
125150
* @test
@@ -130,6 +155,22 @@ public function it_ensures_unique_constraints_for_multiple_fields()
130155

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

158+
$this->store->addDoc('test', '1', ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat']]]);
159+
$this->store->addDoc('test', '2', ['some' => ['prop' => 'bar', 'other' => ['prop' => 'bat']]]);
160+
161+
$this->expectExceptionMessageRegExp('/^Unique constraint violation/');
162+
$this->store->addDoc('test', '4', ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat']]]);
163+
}
164+
165+
/**
166+
* @test
167+
*/
168+
public function it_ensures_unique_constraints_for_multiple_fields_for_update()
169+
{
170+
$multiFieldIndex = MultiFieldIndex::forFields(['some.prop', 'some.other.prop'], true);
171+
172+
$this->store->addCollection('test', $multiFieldIndex);
173+
133174
$this->store->addDoc('test', '1', ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat']]]);
134175
$this->store->addDoc('test', '2', ['some' => ['prop' => 'bar', 'other' => ['prop' => 'bat']]]);
135176
$this->store->addDoc('test', '3', ['some' => ['prop' => 'bar']]);
@@ -138,6 +179,21 @@ public function it_ensures_unique_constraints_for_multiple_fields()
138179
$this->store->updateDoc('test', '2', ['some' => ['prop' => 'foo']]);
139180
}
140181

182+
/**
183+
* @test
184+
* @doesNotPerformAssertions
185+
*/
186+
public function it_allows_updating_with_unique_constraints_for_multiple_fields()
187+
{
188+
$multiFieldIndex = MultiFieldIndex::forFields(['some.prop', 'some.other.prop'], true);
189+
190+
$this->store->addCollection('test', $multiFieldIndex);
191+
192+
$this->store->addDoc('test', '1', ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat']]]);
193+
194+
$this->store->updateDoc('test', '1', ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat'], 'new' => 'prop']]);
195+
}
196+
141197
/**
142198
* @test
143199
*/

0 commit comments

Comments
 (0)