Skip to content

Commit 183ab6c

Browse files
author
Alexander Miertsch
authored
Merge pull request #16 from internalsystemerror/feature-replace-doc
feature: add replaceDoc and replaceMany methods
2 parents e9721e2 + 5a179ea commit 183ab6c

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

src/PostgresDocumentStore.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use EventEngine\DocumentStore\Postgres\Exception\InvalidArgumentException;
2020
use EventEngine\DocumentStore\Postgres\Exception\RuntimeException;
2121
use EventEngine\Util\VariableType;
22+
2223
use function implode;
2324
use function is_string;
2425
use function json_decode;
@@ -433,6 +434,80 @@ public function upsertDoc(string $collectionName, string $docId, array $docOrSub
433434
}
434435
}
435436

437+
/**
438+
* @param string $collectionName
439+
* @param string $docId
440+
* @param array $doc
441+
* @throws \Throwable if updating did not succeed
442+
*/
443+
public function replaceDoc(string $collectionName, string $docId, array $doc): void
444+
{
445+
$metadataStr = '';
446+
$metadata = [];
447+
448+
if($this->useMetadataColumns && array_key_exists('metadata', $doc)) {
449+
$metadata = $doc['metadata'];
450+
unset($doc['metadata']);
451+
452+
453+
foreach ($metadata as $k => $v) {
454+
$metadataStr .= ', '.$k.' = :'.$k;
455+
}
456+
}
457+
458+
$cmd = <<<EOT
459+
UPDATE {$this->schemaName($collectionName)}.{$this->tableName($collectionName)}
460+
SET doc = :doc{$metadataStr}
461+
WHERE id = :id
462+
;
463+
EOT;
464+
$this->transactional(function () use ($cmd, $docId, $doc, $metadata) {
465+
$this->connection->prepare($cmd)->execute(array_merge([
466+
'id' => $docId,
467+
'doc' => json_encode($doc)
468+
], $metadata));
469+
});
470+
}
471+
472+
/**
473+
* @param string $collectionName
474+
* @param Filter $filter
475+
* @param array $set
476+
* @throws \Throwable in case of connection error or other issues
477+
*/
478+
public function replaceMany(string $collectionName, Filter $filter, array $set): void
479+
{
480+
[$filterStr, $args] = $this->filterToWhereClause($filter);
481+
482+
$where = $filterStr? "WHERE $filterStr" : '';
483+
484+
$metadataStr = '';
485+
$metadata = [];
486+
487+
if($this->useMetadataColumns && array_key_exists('metadata', $set)) {
488+
$metadata = $set['metadata'];
489+
unset($set['metadata']);
490+
491+
492+
foreach ($metadata as $k => $v) {
493+
$metadataStr .= ', '.$k.' = :'.$k;
494+
}
495+
}
496+
497+
$cmd = <<<EOT
498+
UPDATE {$this->schemaName($collectionName)}.{$this->tableName($collectionName)}
499+
SET doc = :doc{$metadataStr}
500+
$where;
501+
EOT;
502+
503+
$args['doc'] = json_encode($set);
504+
$args = array_merge($args, $metadata);
505+
506+
$this->transactional(function () use ($cmd, $args) {
507+
$this->connection->prepare($cmd)->execute($args);
508+
});
509+
}
510+
436511
/**
437512
* @param string $collectionName
438513
* @param string $docId

tests/PostgresDocumentStoreTest.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,64 @@ public function it_adds_collection_with_multi_field_index_unique(): void
151151
$this->assertStringStartsWith('CREATE UNIQUE INDEX', $indexes[1]['indexdef']);
152152
}
153153

154+
/**
155+
* @test
156+
*/
157+
public function it_replaces_a_doc()
158+
{
159+
$collectionName = 'test_replaces_a_doc';
160+
$this->documentStore->addCollection($collectionName);
161+
162+
$doc = [
163+
'some' => [
164+
'prop' => 'foo',
165+
'other' => [
166+
'nested' => 42
167+
]
168+
],
169+
'baz' => 'bat',
170+
];
171+
172+
$docId = Uuid::uuid4()->toString();
173+
$this->documentStore->addDoc($collectionName, $docId, $doc);
174+
175+
$doc = ['baz' => 'changed val'];
176+
177+
$this->documentStore->replaceDoc($collectionName, $docId, $doc);
178+
179+
$filter = new EqFilter('baz', 'changed val');
180+
181+
$filteredDocs = $this->documentStore->findDocs($collectionName, $filter);
182+
183+
$this->assertCount(1, $filteredDocs);
184+
}
185+
186+
/**
187+
* @test
188+
*/
189+
public function it_replaces_many()
190+
{
191+
$collectionName = 'test_replaces_many';
192+
$this->documentStore->addCollection($collectionName);
193+
194+
$this->documentStore->addDoc($collectionName, Uuid::uuid4()->toString(), ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat']]]);
195+
$this->documentStore->addDoc($collectionName, Uuid::uuid4()->toString(), ['some' => ['prop' => 'bar', 'other' => ['prop' => 'bat']]]);
196+
$this->documentStore->addDoc($collectionName, Uuid::uuid4()->toString(), ['some' => ['prop' => 'bar']]);
197+
198+
$doc = ['some' => ['prop' => 'fuzz']];
199+
$this->documentStore->replaceMany(
200+
$collectionName,
201+
new EqFilter('some.other.prop', 'bat'),
202+
$doc
203+
);
204+
205+
$filteredDocs = array_values(iterator_to_array($this->documentStore->findDocs($collectionName, new EqFilter('some.prop', 'fuzz'))));
206+
207+
$this->assertCount(2, $filteredDocs);
208+
$this->assertEquals($doc, $filteredDocs[0]);
209+
$this->assertEquals($doc, $filteredDocs[1]);
210+
}
211+
154212
/**
155213
* @test
156214
*/

0 commit comments

Comments
 (0)