Skip to content

Commit

Permalink
PHPLIB-1182: Support codec option in operation classes (#1140)
Browse files Browse the repository at this point in the history
* Add Codec support to find operations

* Add codec support to insert operations

* Add codec support to replace operation

* Add codec support to aggregate operation

* Add codec support to BulkWrite operation

* Add codec support to findAndModify operations

* Add codec support to Watch operation

* Support passing default codec to collection class

* Remove temporary variable usage in operations

* Enforce iterator type when creating ChangeStreamIterator

* Remove unnecessary null-coalesce

* Ensure operation-level type map gets precedence over collection-level codec

* Reference psalm issue regarding unions and assert-if type annotations

* Add iterator type in ReadableStream

* Assume _id property will be present in change stream result document.

* Prohibit specifying typeMap and codec options for operations

This commit also refactors the logic of inheriting collection-level options to operations to reduce code duplication.

* Defer server selection until executing operation

* Remove useless assertion

* Assert iterator type in ChangeStreamIterator::getInnerIterator

* Make assertions on encoded result conditional

* Extract factory to created decoded fixtures

* Split document creation for legibility

* Insert fixture through factory in test object

* Trigger warning when calling CodecCursor::setTypeMap

* Encode documents before type checks

This commit also changes the behaviour to use encode() instead of encodeIfSupported(), requiring documents to be encodable by the given codec in order to be inserted/updated.

* Use more descriptive value in failing tests

* Add clarifying comment on skipping validation

* Simplify double isset check

* Split chained calls when inheriting options

* Defer server selection in Collection::drop()

* Split inheritReadOptions method

* Use decode() instead of decodeIfSupported()

* Add explanatory comment for ID filling behaviour

* Handle null values in findAndModify responses

* Update comment regarding missing identifiers in tests

* Use intersection type for change streams

* Prohibit specifying codec and typeMap options to Watch
  • Loading branch information
alcaeus authored Aug 25, 2023
1 parent 2fcce89 commit 3cd7091
Show file tree
Hide file tree
Showing 47 changed files with 2,161 additions and 554 deletions.
39 changes: 39 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
<code><![CDATA[$reply->cursor->nextBatch]]></code>
</MixedArgument>
<MixedAssignment>
<code>$resumeToken</code>
<code><![CDATA[$this->postBatchResumeToken]]></code>
</MixedAssignment>
<MixedPropertyFetch>
Expand Down Expand Up @@ -170,6 +171,7 @@
</file>
<file src="src/Operation/Aggregate.php">
<MixedArgument>
<code><![CDATA[$this->options['codec']]]></code>
<code><![CDATA[$this->options['typeMap']]]></code>
</MixedArgument>
<MixedAssignment>
Expand All @@ -191,6 +193,8 @@
<code>$args[0]</code>
<code>$args[0]</code>
<code>$args[0]</code>
<code>$args[0]</code>
<code>$args[1]</code>
<code>$args[1]</code>
<code>$args[1]</code>
<code>$args[1]</code>
Expand All @@ -205,6 +209,8 @@
<code>$args[0]</code>
<code>$args[0]</code>
<code>$args[0]</code>
<code>$args[0]</code>
<code>$args[1]</code>
<code>$args[1]</code>
<code>$args[1]</code>
<code>$args[1]</code>
Expand Down Expand Up @@ -244,6 +250,8 @@
<code>$args[2]</code>
<code><![CDATA[$args[2]['multi']]]></code>
<code><![CDATA[$args[2]['multi']]]></code>
<code>$operations[$i][$type][0]</code>
<code>$operations[$i][$type][1]</code>
<code>$operations[$i][$type][1]</code>
<code>$operations[$i][$type][2]</code>
<code>$operations[$i][$type][2]</code>
Expand Down Expand Up @@ -401,6 +409,7 @@
</file>
<file src="src/Operation/Find.php">
<MixedArgument>
<code><![CDATA[$this->options['codec']]]></code>
<code><![CDATA[$this->options['typeMap']]]></code>
</MixedArgument>
<MixedArrayAccess>
Expand All @@ -427,18 +436,34 @@
<code><![CDATA[$cmd['upsert']]]></code>
<code><![CDATA[$options['session']]]></code>
<code><![CDATA[$options['writeConcern']]]></code>
<code>$value</code>
</MixedAssignment>
<MixedInferredReturnType>
<code>array|object|null</code>
</MixedInferredReturnType>
<MixedMethodCall>
<code>decode</code>
<code>isInTransaction</code>
</MixedMethodCall>
<MixedReturnStatement>
<code><![CDATA[$value === null ? $value : $this->options['codec']->decode($value)]]></code>
<code><![CDATA[$value === null ? $value : $this->options['codec']->decode($value)]]></code>
<code><![CDATA[is_object($result) ? ($result->value ?? null) : null]]></code>
<code><![CDATA[is_object($result) ? ($result->value ?? null) : null]]></code>
</MixedReturnStatement>
</file>
<file src="src/Operation/FindOne.php">
<MixedAssignment>
<code>$document</code>
</MixedAssignment>
<MixedInferredReturnType>
<code>array|object|null</code>
</MixedInferredReturnType>
<MixedReturnStatement>
<code>$document === false ? null : $document</code>
<code>$document === false ? null : $document</code>
</MixedReturnStatement>
</file>
<file src="src/Operation/FindOneAndDelete.php">
<MixedAssignment>
<code><![CDATA[$options['fields']]]></code>
Expand All @@ -448,6 +473,9 @@
<MixedAssignment>
<code><![CDATA[$options['fields']]]></code>
</MixedAssignment>
<PossiblyInvalidArgument>
<code>$replacement</code>
</PossiblyInvalidArgument>
</file>
<file src="src/Operation/FindOneAndUpdate.php">
<MixedAssignment>
Expand All @@ -464,6 +492,9 @@
<MixedMethodCall>
<code>isInTransaction</code>
</MixedMethodCall>
<PossiblyInvalidArgument>
<code>$document</code>
</PossiblyInvalidArgument>
</file>
<file src="src/Operation/InsertOne.php">
<MixedAssignment>
Expand All @@ -475,6 +506,9 @@
<MixedMethodCall>
<code>isInTransaction</code>
</MixedMethodCall>
<PossiblyInvalidArgument>
<code>$document</code>
</PossiblyInvalidArgument>
</file>
<file src="src/Operation/ListIndexes.php">
<MixedAssignment>
Expand Down Expand Up @@ -522,6 +556,11 @@
<code>isInTransaction</code>
</MixedMethodCall>
</file>
<file src="src/Operation/ReplaceOne.php">
<PossiblyInvalidArgument>
<code>$replacement</code>
</PossiblyInvalidArgument>
</file>
<file src="src/Operation/Update.php">
<MixedArgument>
<code><![CDATA[$this->options['writeConcern']]]></code>
Expand Down
26 changes: 24 additions & 2 deletions src/ChangeStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
namespace MongoDB;

use Iterator;
use MongoDB\BSON\Document;
use MongoDB\Codec\DocumentCodec;
use MongoDB\Driver\CursorId;
use MongoDB\Driver\Exception\ConnectionException;
use MongoDB\Driver\Exception\RuntimeException;
Expand All @@ -27,6 +29,7 @@
use MongoDB\Model\ChangeStreamIterator;
use ReturnTypeWillChange;

use function assert;
use function call_user_func;
use function in_array;

Expand Down Expand Up @@ -82,15 +85,22 @@ class ChangeStream implements Iterator
*/
private bool $hasAdvanced = false;

private ?DocumentCodec $codec;

/**
* @internal
*
* @param ResumeCallable $resumeCallable
*/
public function __construct(ChangeStreamIterator $iterator, callable $resumeCallable)
public function __construct(ChangeStreamIterator $iterator, callable $resumeCallable, ?DocumentCodec $codec = null)
{
$this->iterator = $iterator;
$this->resumeCallable = $resumeCallable;
$this->codec = $codec;

if ($codec) {
$this->iterator->getInnerIterator()->setTypeMap(['root' => 'bson']);
}
}

/**
Expand All @@ -100,7 +110,15 @@ public function __construct(ChangeStreamIterator $iterator, callable $resumeCall
#[ReturnTypeWillChange]
public function current()
{
return $this->iterator->current();
$value = $this->iterator->current();

if (! $this->codec) {
return $value;
}

assert($value instanceof Document);

return $this->codec->decode($value);
}

/** @return CursorId */
Expand Down Expand Up @@ -252,6 +270,10 @@ private function resume(): void

$this->iterator->rewind();

if ($this->codec) {
$this->iterator->getInnerIterator()->setTypeMap(['root' => 'bson']);
}

$this->onIteration($this->hasAdvanced);
}

Expand Down
Loading

0 comments on commit 3cd7091

Please sign in to comment.