Skip to content

Commit 45d51d6

Browse files
committed
Test FindAndModify with replacement doc resembling a pipeline
Note that FindAndModify's behavior differs from Update since it is unaffected by libmongoc's pipeline detection for update commands. FindAndModify behaves correctly. Add a comment explaining how the conditional object cast in FindAndModify::createCommandDocument() affects BSON encoding for the update option.
1 parent ae2b853 commit 45d51d6

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

src/Operation/FindAndModify.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,14 @@ private function createCommandDocument(): array
295295
if (isset($this->options['update'])) {
296296
/** @psalm-var array|object */
297297
$update = $this->options['update'];
298+
/* A non-empty pipeline will encode as a BSON array, so leave it
299+
* as-is. Cast anything else to an object since a BSON document is
300+
* likely expected. This includes empty arrays, which historically
301+
* can be used to represent empty replacement documents.
302+
*
303+
* This also allows an empty pipeline expressed as a PackedArray or
304+
* Serializable to still encode as a BSON array, since the object
305+
* cast will have no effect. */
298306
$cmd['update'] = is_pipeline($update) ? $update : (object) $update;
299307
}
300308

tests/Operation/FindAndModifyFunctionalTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public function provideQueryDocuments(): array
5151
* @dataProvider provideReplacementDocuments
5252
* @dataProvider provideUpdateDocuments
5353
* @dataProvider provideUpdatePipelines
54+
* @dataProvider provideReplacementDocumentLikePipeline
5455
*/
5556
public function testUpdateDocuments($update, $expectedUpdate): void
5657
{
@@ -73,6 +74,19 @@ function (array $event) use ($expectedUpdate): void {
7374
);
7475
}
7576

77+
public function provideReplacementDocumentLikePipeline(): array
78+
{
79+
/* Note: this expected value differs from UpdateFunctionalTest because
80+
* FindAndModify is not affected by libmongoc's pipeline detection for
81+
* update commands (see: CDRIVER-4658). */
82+
return [
83+
'replacement_like_pipeline' => [
84+
(object) ['0' => ['$set' => ['x' => 1]]],
85+
(object) ['0' => (object) ['$set' => (object) ['x' => 1]]],
86+
],
87+
];
88+
}
89+
7690
/** @see https://jira.mongodb.org/browse/PHPLIB-344 */
7791
public function testManagerReadConcernIsOmitted(): void
7892
{

tests/Operation/UpdateFunctionalTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ function (array $event) use ($expectedUpdate): void {
7979

8080
public function provideReplacementDocumentLikePipeline(): array
8181
{
82-
/* libmongoc encodes this replacement document as a BSON array because
83-
* it resembles an update pipeline (see: CDRIVER-4658). */
82+
/* Note: libmongoc encodes this replacement document as a BSON array
83+
* because it resembles an update pipeline (see: CDRIVER-4658). */
8484
return [
8585
'replacement_like_pipeline' => [
8686
(object) ['0' => ['$set' => ['x' => 1]]],

0 commit comments

Comments
 (0)