Skip to content

Commit 7a7b2b9

Browse files
authored
Merge pull request #63 from utopia-php/fix-unique-index-exception-update-document
Throw correct error when updating documents with unique index
2 parents 5b3ed93 + df6c8de commit 7a7b2b9

3 files changed

Lines changed: 54 additions & 7 deletions

File tree

src/Database/Adapter/MariaDB.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ public function createDocument(string $collection, Document $document): Document
375375
case 1062:
376376
case 23000:
377377
$this->getPDO()->rollBack();
378-
throw new Duplicate('Duplicated document: '.$e->getMessage()); // TODO add test for catching this exception
378+
throw new Duplicate('Duplicated document: '.$e->getMessage());
379379
break;
380380

381381
default:
@@ -434,7 +434,21 @@ public function updateDocument(string $collection, Document $document): Document
434434
}
435435

436436
if(!empty($attributes)) {
437-
$stmt->execute();
437+
try {
438+
$stmt->execute();
439+
} catch (PDOException $e) {
440+
switch ($e->getCode()) {
441+
case 1062:
442+
case 23000:
443+
$this->getPDO()->rollBack();
444+
throw new Duplicate('Duplicated document: '.$e->getMessage());
445+
break;
446+
447+
default:
448+
throw $e;
449+
break;
450+
}
451+
}
438452
}
439453

440454
if(!$this->getPDO()->commit()) {

src/Database/Adapter/MongoDB.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,22 @@ public function updateDocument(string $collection, Document $document): Document
376376
$name = $this->filter($collection);
377377
$collection = $this->getDatabase()->$name;
378378

379-
$result = $collection->findOneAndUpdate(
380-
['_uid' => $document->getId()],
381-
['$set' => $this->replaceChars('$', '_', $document->getArrayCopy())],
382-
['returnDocument' => \MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER]
383-
);
379+
try {
380+
$result = $collection->findOneAndUpdate(
381+
['_uid' => $document->getId()],
382+
['$set' => $this->replaceChars('$', '_', $document->getArrayCopy())],
383+
['returnDocument' => \MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER]
384+
);
385+
} catch (\MongoDB\Driver\Exception\CommandException $e) {
386+
switch ($e->getCode()) {
387+
case 11000:
388+
throw new Duplicate('Duplicated document: '.$e->getMessage());
389+
break;
390+
default:
391+
throw $e;
392+
break;
393+
}
394+
}
384395

385396
$result = $this->replaceChars('_', '$', $result);
386397

tests/Database/Base.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,4 +1567,26 @@ public function testUniqueIndexDuplicate()
15671567
'generes' => ['animation', 'kids'],
15681568
]));
15691569
}
1570+
1571+
/**
1572+
* @depends testUniqueIndexDuplicate
1573+
*/
1574+
public function testUniqueIndexDuplicateUpdate()
1575+
{
1576+
// create document then update to conflict with index
1577+
$document = static::getDatabase()->createDocument('movies', new Document([
1578+
'$read' => ['role:all', 'user1', 'user2'],
1579+
'$write' => ['role:all', 'user1x', 'user2x'],
1580+
'name' => 'Frozen 5',
1581+
'director' => 'Chris Buck & Jennifer Lee',
1582+
'year' => 2013,
1583+
'price' => 39.50,
1584+
'active' => true,
1585+
'generes' => ['animation', 'kids'],
1586+
]));
1587+
1588+
$this->expectException(DuplicateException::class);
1589+
1590+
static::getDatabase()->updateDocument('movies', $document->getId(), $document->setAttribute('name', 'Frozen'));
1591+
}
15701592
}

0 commit comments

Comments
 (0)