Skip to content

Commit e19dfe3

Browse files
committed
Merge pull request #300
2 parents 1b20707 + 3b6b96e commit e19dfe3

23 files changed

+274
-93
lines changed

docs/includes/apiargs-MongoDBCollection-method-aggregate-option.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,6 @@ source:
4949
source:
5050
file: apiargs-MongoDBCollection-common-option.yaml
5151
ref: typeMap
52-
post: |
53-
.. note::
54-
55-
This is not supported for inline aggregation results (i.e. ``useCursor``
56-
option is ``false`` or the server version is < 2.6).
5752
---
5853
arg_name: option
5954
name: useCursor

docs/includes/apiargs-MongoDBCollection-method-findOneAndDelete-option.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ source:
1414
file: apiargs-common-option.yaml
1515
ref: maxTimeMS
1616
---
17+
source:
18+
file: apiargs-MongoDBCollection-common-option.yaml
19+
ref: typeMap
20+
post: |
21+
This will be used for the returned result document.
22+
---
1723
source:
1824
file: apiargs-MongoDBCollection-common-option.yaml
1925
ref: writeConcern

docs/includes/apiargs-MongoDBCollection-method-findOneAndReplace-option.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ interface: phpmethod
3131
operation: ~
3232
optional: true
3333
---
34+
source:
35+
file: apiargs-MongoDBCollection-common-option.yaml
36+
ref: typeMap
37+
post: |
38+
This will be used for the returned result document.
39+
---
3440
source:
3541
file: apiargs-MongoDBCollection-common-option.yaml
3642
ref: upsert

docs/includes/apiargs-MongoDBCollection-method-findOneAndUpdate-option.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ interface: phpmethod
3131
operation: ~
3232
optional: true
3333
---
34+
source:
35+
file: apiargs-MongoDBCollection-common-option.yaml
36+
ref: typeMap
37+
post: |
38+
This will be used for the returned result document.
39+
---
3440
source:
3541
file: apiargs-MongoDBCollection-common-option.yaml
3642
ref: upsert

docs/includes/extracts-bson-deserialization-base.yaml

Lines changed: 0 additions & 12 deletions
This file was deleted.

docs/includes/extracts-bson-deserialization.yaml

Lines changed: 0 additions & 21 deletions
This file was deleted.

docs/reference/method/MongoDBCollection-aggregate.txt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,6 @@ MongoDB server version and whether the ``useCursor`` option is specified. If
5858
``result`` array from the command response document. In both cases, the return
5959
value will be :php:`Traversable <traversable>`.
6060

61-
.. note::
62-
63-
BSON deserialization of inline aggregation results (i.e. not using a command
64-
cursor) does not yet support a ``typeMap`` option. Classes implementing
65-
:php:`MongoDB\\BSON\\Persistable <mongodb-bson-persistable>` will still be
66-
deserialized according to the
67-
:php:`Persistence <mongodb.persistence.deserialization>` specification.
68-
6961
.. todo: add examples
7062

7163
See Also

docs/reference/method/MongoDBCollection-findOneAndDelete.txt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@ Definition
2929

3030
.. include:: /includes/apiargs/MongoDBCollection-method-findOneAndDelete-option.rst
3131

32-
.. include:: /includes/extracts/bson-deserialization-findOneAndDelete.rst
33-
3432
Return Values
3533
-------------
3634

37-
An object for the document that was deleted, or ``null`` if no document matched
38-
the query.
35+
An array or object for the document that was deleted, or ``null`` if no document
36+
matched the query. The return type will depend on the ``typeMap`` option.
3937

4038
Errors/Exceptions
4139
-----------------

docs/reference/method/MongoDBCollection-findOneAndReplace.txt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,13 @@ Definition
2929

3030
.. include:: /includes/apiargs/MongoDBCollection-method-findOneAndReplace-option.rst
3131

32-
.. include:: /includes/extracts/bson-deserialization-findOneAndReplace.rst
33-
3432
Return Values
3533
-------------
3634

37-
An object for either the original or the replaced document, depending on the
38-
specified value of the ``returnDocument`` option. By default, the original
35+
An array object for either the original or the replaced document, depending on
36+
the specified value of the ``returnDocument`` option. By default, the original
3937
document is returned. If no document matched the query, ``null`` is returned.
38+
The return type will depend on the ``typeMap`` option.
4039

4140
Errors/Exceptions
4241
-----------------

docs/reference/method/MongoDBCollection-findOneAndUpdate.txt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,13 @@ Definition
2929

3030
.. include:: /includes/apiargs/MongoDBCollection-method-findOneAndUpdate-option.rst
3131

32-
.. include:: /includes/extracts/bson-deserialization-findOneAndUpdate.rst
33-
3432
Return Values
3533
-------------
3634

37-
An object for either the original or the updated document, depending on the
38-
specified value of the ``returnDocument`` option. By default, the original
35+
An array or object for either the original or the updated document, depending on
36+
the specified value of the ``returnDocument`` option. By default, the original
3937
document is returned. If no document matched the query, ``null`` is returned.
38+
The return type will depend on the ``typeMap`` option.
4039

4140
Errors/Exceptions
4241
-----------------

src/Collection.php

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,6 @@ public function __toString()
153153
* returned; otherwise, an ArrayIterator is returned, which wraps the
154154
* "result" array from the command response document.
155155
*
156-
* Note: BSON deserialization of inline aggregation results (i.e. not using
157-
* a command cursor) does not yet support a custom type map
158-
* (depends on: https://jira.mongodb.org/browse/PHPC-314).
159-
*
160156
* @see Aggregate::__construct() for supported options
161157
* @param array $pipeline List of pipeline operations
162158
* @param array $options Command options
@@ -553,14 +549,11 @@ public function findOne($filter = [], array $options = [])
553549
*
554550
* The document to return may be null if no document matched the filter.
555551
*
556-
* Note: BSON deserialization of the returned document does not yet support
557-
* a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
558-
*
559552
* @see FindOneAndDelete::__construct() for supported options
560553
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
561554
* @param array|object $filter Query by which to filter documents
562555
* @param array $options Command options
563-
* @return object|null
556+
* @return array|object|null
564557
* @throws UnexpectedValueException if the command response was malformed
565558
* @throws UnsupportedException if options are not supported by the selected server
566559
* @throws InvalidArgumentException for parameter/option parsing errors
@@ -574,6 +567,10 @@ public function findOneAndDelete($filter, array $options = [])
574567
$options['writeConcern'] = $this->writeConcern;
575568
}
576569

570+
if ( ! isset($options['typeMap'])) {
571+
$options['typeMap'] = $this->typeMap;
572+
}
573+
577574
$operation = new FindOneAndDelete($this->databaseName, $this->collectionName, $filter, $options);
578575

579576
return $operation->execute($server);
@@ -588,15 +585,12 @@ public function findOneAndDelete($filter, array $options = [])
588585
* FindOneAndReplace::RETURN_DOCUMENT_AFTER for the "returnDocument" option
589586
* to return the updated document.
590587
*
591-
* Note: BSON deserialization of the returned document does not yet support
592-
* a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
593-
*
594588
* @see FindOneAndReplace::__construct() for supported options
595589
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
596590
* @param array|object $filter Query by which to filter documents
597591
* @param array|object $replacement Replacement document
598592
* @param array $options Command options
599-
* @return object|null
593+
* @return array|object|null
600594
* @throws UnexpectedValueException if the command response was malformed
601595
* @throws UnsupportedException if options are not supported by the selected server
602596
* @throws InvalidArgumentException for parameter/option parsing errors
@@ -610,6 +604,10 @@ public function findOneAndReplace($filter, $replacement, array $options = [])
610604
$options['writeConcern'] = $this->writeConcern;
611605
}
612606

607+
if ( ! isset($options['typeMap'])) {
608+
$options['typeMap'] = $this->typeMap;
609+
}
610+
613611
$operation = new FindOneAndReplace($this->databaseName, $this->collectionName, $filter, $replacement, $options);
614612

615613
return $operation->execute($server);
@@ -624,15 +622,12 @@ public function findOneAndReplace($filter, $replacement, array $options = [])
624622
* FindOneAndUpdate::RETURN_DOCUMENT_AFTER for the "returnDocument" option
625623
* to return the updated document.
626624
*
627-
* Note: BSON deserialization of the returned document does not yet support
628-
* a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
629-
*
630625
* @see FindOneAndReplace::__construct() for supported options
631626
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
632627
* @param array|object $filter Query by which to filter documents
633628
* @param array|object $update Update to apply to the matched document
634629
* @param array $options Command options
635-
* @return object|null
630+
* @return array|object|null
636631
* @throws UnexpectedValueException if the command response was malformed
637632
* @throws UnsupportedException if options are not supported by the selected server
638633
* @throws InvalidArgumentException for parameter/option parsing errors
@@ -646,6 +641,10 @@ public function findOneAndUpdate($filter, $update, array $options = [])
646641
$options['writeConcern'] = $this->writeConcern;
647642
}
648643

644+
if ( ! isset($options['typeMap'])) {
645+
$options['typeMap'] = $this->typeMap;
646+
}
647+
649648
$operation = new FindOneAndUpdate($this->databaseName, $this->collectionName, $filter, $update, $options);
650649

651650
return $operation->execute($server);

src/GridFS/Bucket.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ public function getFileDocumentForStream($stream)
282282
$file = $this->getRawFileDocumentForStream($stream);
283283

284284
// Filter the raw document through the specified type map
285-
return \MongoDB\BSON\toPHP(\MongoDB\BSON\fromPHP($file), $this->typeMap);
285+
return \MongoDB\apply_type_map_to_document($file, $this->typeMap);
286286
}
287287

288288
/**
@@ -302,7 +302,7 @@ public function getFileIdForStream($stream)
302302
* the root type so we can reliably access the ID.
303303
*/
304304
$typeMap = ['root' => 'stdClass'] + $this->typeMap;
305-
$file = \MongoDB\BSON\toPHP(\MongoDB\BSON\fromPHP($file), $typeMap);
305+
$file = \MongoDB\apply_type_map_to_document($file, $typeMap);
306306

307307
if ( ! isset($file->_id) && ! property_exists($file, '_id')) {
308308
throw new CorruptFileException('file._id does not exist');

src/Model/TypeMapArrayIterator.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace MongoDB\Model;
4+
5+
use ArrayIterator;
6+
7+
/**
8+
* Iterator for applying a type map to documents in inline command results.
9+
*
10+
* This iterator may be used to apply a type map to an array of documents
11+
* returned by a database command (e.g. aggregate on servers < 2.6) and allows
12+
* for functional equivalence with commands that return their results via a
13+
* cursor (e.g. aggregate on servers >= 2.6).
14+
*
15+
* @internal
16+
*/
17+
class TypeMapArrayIterator extends ArrayIterator
18+
{
19+
private $typeMap;
20+
21+
/**
22+
* Constructor.
23+
*
24+
* @param array $documents
25+
* @param array $typeMap
26+
*/
27+
public function __construct(array $documents = [], array $typeMap)
28+
{
29+
parent::__construct($documents);
30+
31+
$this->typeMap = $typeMap;
32+
}
33+
34+
/**
35+
* Return the current element with the type map applied to it.
36+
*
37+
* @see http://php.net/arrayiterator.current
38+
* @return array|object
39+
*/
40+
public function current()
41+
{
42+
return \MongoDB\apply_type_map_to_document(parent::current(), $this->typeMap);
43+
}
44+
}

src/Operation/Aggregate.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use MongoDB\Exception\InvalidArgumentException;
1212
use MongoDB\Exception\UnexpectedValueException;
1313
use MongoDB\Exception\UnsupportedException;
14+
use MongoDB\Model\TypeMapArrayIterator;
1415
use ArrayIterator;
1516
use stdClass;
1617
use Traversable;
@@ -72,9 +73,6 @@ class Aggregate implements Executable
7273
* * typeMap (array): Type map for BSON deserialization. This will be
7374
* applied to the returned Cursor (it is not sent to the server).
7475
*
75-
* This is not supported for inline aggregation results (i.e. useCursor
76-
* option is false or the server version is < 2.6).
77-
*
7876
* * useCursor (boolean): Indicates whether the command will request that
7977
* the server provide results using a cursor. The default is true.
8078
*
@@ -206,9 +204,6 @@ public function execute(Server $server)
206204
$cursor = $server->executeCommand($this->databaseName, $command, $readPreference);
207205

208206
if ($isCursorSupported && $this->options['useCursor']) {
209-
/* The type map can only be applied to command cursors until
210-
* https://jira.mongodb.org/browse/PHPC-314 is implemented.
211-
*/
212207
if (isset($this->options['typeMap'])) {
213208
$cursor->setTypeMap($this->options['typeMap']);
214209
}
@@ -222,6 +217,10 @@ public function execute(Server $server)
222217
throw new UnexpectedValueException('aggregate command did not return a "result" array');
223218
}
224219

220+
if (isset($this->options['typeMap'])) {
221+
return new TypeMapArrayIterator($result->result, $this->options['typeMap']);
222+
}
223+
225224
return new ArrayIterator($result->result);
226225
}
227226

src/Operation/FindAndModify.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ class FindAndModify implements Executable
6060
* * sort (document): Determines which document the operation modifies if
6161
* the query selects multiple documents.
6262
*
63+
* * typeMap (array): Type map for BSON deserialization.
64+
*
6365
* * update (document): Update or replacement to apply to the matched
6466
* document. This option cannot be set if the remove option is true.
6567
*
@@ -117,6 +119,10 @@ public function __construct($databaseName, $collectionName, array $options)
117119
throw InvalidArgumentException::invalidType('"sort" option', $options['sort'], 'array or object');
118120
}
119121

122+
if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
123+
throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
124+
}
125+
120126
if (isset($options['update']) && ! is_array($options['update']) && ! is_object($options['update'])) {
121127
throw InvalidArgumentException::invalidType('"update" option', $options['update'], 'array or object');
122128
}
@@ -143,7 +149,7 @@ public function __construct($databaseName, $collectionName, array $options)
143149
*
144150
* @see Executable::execute()
145151
* @param Server $server
146-
* @return object|null
152+
* @return array|object|null
147153
* @throws UnexpectedValueException if the command response was malformed
148154
* @throws UnsupportedException if collation or write concern is used and unsupported
149155
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
@@ -180,6 +186,10 @@ public function execute(Server $server)
180186
throw new UnexpectedValueException('findAndModify command did not return a "value" document');
181187
}
182188

189+
if (isset($this->options['typeMap'])) {
190+
return \MongoDB\apply_type_map_to_document($result->value, $this->options['typeMap']);
191+
}
192+
183193
return $result->value;
184194
}
185195

0 commit comments

Comments
 (0)