Skip to content

Commit 354f5a8

Browse files
author
Alexander Miertsch
authored
Merge branch 'master' into test-nested-assoc-value
2 parents 076ee4b + 183ab6c commit 354f5a8

File tree

2 files changed

+134
-1
lines changed

2 files changed

+134
-1
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: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ public function it_adds_collection_with_multi_field_index_unique(): void
150150
);
151151
$this->assertStringStartsWith('CREATE UNIQUE INDEX', $indexes[1]['indexdef']);
152152
}
153-
153+
154154
/**
155155
* @test
156156
*/
@@ -216,6 +216,64 @@ public function it_updates_a_subset_of_a_doc()
216216
$this->assertArrayNotHasKey('other', $filteredDocs[0]['some']);
217217
}
218218

219+
/**
220+
* @test
221+
*/
222+
public function it_replaces_a_doc()
223+
{
224+
$collectionName = 'test_replaces_a_doc';
225+
$this->documentStore->addCollection($collectionName);
226+
227+
$doc = [
228+
'some' => [
229+
'prop' => 'foo',
230+
'other' => [
231+
'nested' => 42
232+
]
233+
],
234+
'baz' => 'bat',
235+
];
236+
237+
$docId = Uuid::uuid4()->toString();
238+
$this->documentStore->addDoc($collectionName, $docId, $doc);
239+
240+
$doc = ['baz' => 'changed val'];
241+
242+
$this->documentStore->replaceDoc($collectionName, $docId, $doc);
243+
244+
$filter = new EqFilter('baz', 'changed val');
245+
246+
$filteredDocs = $this->documentStore->findDocs($collectionName, $filter);
247+
248+
$this->assertCount(1, $filteredDocs);
249+
}
250+
251+
/**
252+
* @test
253+
*/
254+
public function it_replaces_many()
255+
{
256+
$collectionName = 'test_replaces_many';
257+
$this->documentStore->addCollection($collectionName);
258+
259+
$this->documentStore->addDoc($collectionName, Uuid::uuid4()->toString(), ['some' => ['prop' => 'foo', 'other' => ['prop' => 'bat']]]);
260+
$this->documentStore->addDoc($collectionName, Uuid::uuid4()->toString(), ['some' => ['prop' => 'bar', 'other' => ['prop' => 'bat']]]);
261+
$this->documentStore->addDoc($collectionName, Uuid::uuid4()->toString(), ['some' => ['prop' => 'bar']]);
262+
263+
$doc = ['some' => ['prop' => 'fuzz']];
264+
$this->documentStore->replaceMany(
265+
$collectionName,
266+
new EqFilter('some.other.prop', 'bat'),
267+
$doc
268+
);
269+
270+
$filteredDocs = array_values(iterator_to_array($this->documentStore->findDocs($collectionName, new EqFilter('some.prop', 'fuzz'))));
271+
272+
$this->assertCount(2, $filteredDocs);
273+
$this->assertEquals($doc, $filteredDocs[0]);
274+
$this->assertEquals($doc, $filteredDocs[1]);
275+
}
276+
219277
/**
220278
* @test
221279
*/

0 commit comments

Comments
 (0)