Commit c73dbf29 authored by Jeremy Mikola's avatar Jeremy Mikola

PHPLIB-112: Support typeMap option for findAndModify operations

parent e7a5e3ca
...@@ -14,6 +14,12 @@ source: ...@@ -14,6 +14,12 @@ source:
file: apiargs-common-option.yaml file: apiargs-common-option.yaml
ref: maxTimeMS ref: maxTimeMS
--- ---
source:
file: apiargs-MongoDBCollection-common-option.yaml
ref: typeMap
post: |
This will be used for the returned result document.
---
source: source:
file: apiargs-MongoDBCollection-common-option.yaml file: apiargs-MongoDBCollection-common-option.yaml
ref: writeConcern ref: writeConcern
......
...@@ -31,6 +31,12 @@ interface: phpmethod ...@@ -31,6 +31,12 @@ interface: phpmethod
operation: ~ operation: ~
optional: true optional: true
--- ---
source:
file: apiargs-MongoDBCollection-common-option.yaml
ref: typeMap
post: |
This will be used for the returned result document.
---
source: source:
file: apiargs-MongoDBCollection-common-option.yaml file: apiargs-MongoDBCollection-common-option.yaml
ref: upsert ref: upsert
......
...@@ -31,6 +31,12 @@ interface: phpmethod ...@@ -31,6 +31,12 @@ interface: phpmethod
operation: ~ operation: ~
optional: true optional: true
--- ---
source:
file: apiargs-MongoDBCollection-common-option.yaml
ref: typeMap
post: |
This will be used for the returned result document.
---
source: source:
file: apiargs-MongoDBCollection-common-option.yaml file: apiargs-MongoDBCollection-common-option.yaml
ref: upsert ref: upsert
......
ref: _bson-deserialization
content: |
.. note::
{{method}} does not yet support a ``typeMap`` option for BSON
deserialization of the returned document.
Classes implementing
:php:`MongoDB\\BSON\\Persistable <class.mongodb-bson-persistable>`
are deserialized according to the :php:`persistance
<mongodb.persistance>` specification.
...
ref: bson-deserialization-findOneAndDelete
source:
file: extracts-bson-deserialization-base.yaml
ref: _bson-deserialization
replacement:
method: ":phpmethod:`MongoDB\\Collection::findOneAndDelete()`"
---
ref: bson-deserialization-findOneAndReplace
source:
file: extracts-bson-deserialization-base.yaml
ref: _bson-deserialization
replacement:
method: ":phpmethod:`MongoDB\\Collection::findOneAndReplace()`"
---
ref: bson-deserialization-findOneAndUpdate
source:
file: extracts-bson-deserialization-base.yaml
ref: _bson-deserialization
replacement:
method: ":phpmethod:`MongoDB\\Collection::findOneAndUpdate()`"
...
...@@ -29,13 +29,11 @@ Definition ...@@ -29,13 +29,11 @@ Definition
.. include:: /includes/apiargs/MongoDBCollection-method-findOneAndDelete-option.rst .. include:: /includes/apiargs/MongoDBCollection-method-findOneAndDelete-option.rst
.. include:: /includes/extracts/bson-deserialization-findOneAndDelete.rst
Return Values Return Values
------------- -------------
An object for the document that was deleted, or ``null`` if no document matched An array or object for the document that was deleted, or ``null`` if no document
the query. matched the query. The return type will depend on the ``typeMap`` option.
Errors/Exceptions Errors/Exceptions
----------------- -----------------
......
...@@ -29,14 +29,13 @@ Definition ...@@ -29,14 +29,13 @@ Definition
.. include:: /includes/apiargs/MongoDBCollection-method-findOneAndReplace-option.rst .. include:: /includes/apiargs/MongoDBCollection-method-findOneAndReplace-option.rst
.. include:: /includes/extracts/bson-deserialization-findOneAndReplace.rst
Return Values Return Values
------------- -------------
An object for either the original or the replaced document, depending on the An array object for either the original or the replaced document, depending on
specified value of the ``returnDocument`` option. By default, the original the specified value of the ``returnDocument`` option. By default, the original
document is returned. If no document matched the query, ``null`` is returned. document is returned. If no document matched the query, ``null`` is returned.
The return type will depend on the ``typeMap`` option.
Errors/Exceptions Errors/Exceptions
----------------- -----------------
......
...@@ -29,14 +29,13 @@ Definition ...@@ -29,14 +29,13 @@ Definition
.. include:: /includes/apiargs/MongoDBCollection-method-findOneAndUpdate-option.rst .. include:: /includes/apiargs/MongoDBCollection-method-findOneAndUpdate-option.rst
.. include:: /includes/extracts/bson-deserialization-findOneAndUpdate.rst
Return Values Return Values
------------- -------------
An object for either the original or the updated document, depending on the An array or object for either the original or the updated document, depending on
specified value of the ``returnDocument`` option. By default, the original the specified value of the ``returnDocument`` option. By default, the original
document is returned. If no document matched the query, ``null`` is returned. document is returned. If no document matched the query, ``null`` is returned.
The return type will depend on the ``typeMap`` option.
Errors/Exceptions Errors/Exceptions
----------------- -----------------
......
...@@ -553,14 +553,11 @@ class Collection ...@@ -553,14 +553,11 @@ class Collection
* *
* The document to return may be null if no document matched the filter. * The document to return may be null if no document matched the filter.
* *
* Note: BSON deserialization of the returned document does not yet support
* a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
*
* @see FindOneAndDelete::__construct() for supported options * @see FindOneAndDelete::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/ * @see http://docs.mongodb.org/manual/reference/command/findAndModify/
* @param array|object $filter Query by which to filter documents * @param array|object $filter Query by which to filter documents
* @param array $options Command options * @param array $options Command options
* @return object|null * @return array|object|null
* @throws UnexpectedValueException if the command response was malformed * @throws UnexpectedValueException if the command response was malformed
* @throws UnsupportedException if options are not supported by the selected server * @throws UnsupportedException if options are not supported by the selected server
* @throws InvalidArgumentException for parameter/option parsing errors * @throws InvalidArgumentException for parameter/option parsing errors
...@@ -574,6 +571,10 @@ class Collection ...@@ -574,6 +571,10 @@ class Collection
$options['writeConcern'] = $this->writeConcern; $options['writeConcern'] = $this->writeConcern;
} }
if ( ! isset($options['typeMap'])) {
$options['typeMap'] = $this->typeMap;
}
$operation = new FindOneAndDelete($this->databaseName, $this->collectionName, $filter, $options); $operation = new FindOneAndDelete($this->databaseName, $this->collectionName, $filter, $options);
return $operation->execute($server); return $operation->execute($server);
...@@ -588,15 +589,12 @@ class Collection ...@@ -588,15 +589,12 @@ class Collection
* FindOneAndReplace::RETURN_DOCUMENT_AFTER for the "returnDocument" option * FindOneAndReplace::RETURN_DOCUMENT_AFTER for the "returnDocument" option
* to return the updated document. * to return the updated document.
* *
* Note: BSON deserialization of the returned document does not yet support
* a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
*
* @see FindOneAndReplace::__construct() for supported options * @see FindOneAndReplace::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/ * @see http://docs.mongodb.org/manual/reference/command/findAndModify/
* @param array|object $filter Query by which to filter documents * @param array|object $filter Query by which to filter documents
* @param array|object $replacement Replacement document * @param array|object $replacement Replacement document
* @param array $options Command options * @param array $options Command options
* @return object|null * @return array|object|null
* @throws UnexpectedValueException if the command response was malformed * @throws UnexpectedValueException if the command response was malformed
* @throws UnsupportedException if options are not supported by the selected server * @throws UnsupportedException if options are not supported by the selected server
* @throws InvalidArgumentException for parameter/option parsing errors * @throws InvalidArgumentException for parameter/option parsing errors
...@@ -610,6 +608,10 @@ class Collection ...@@ -610,6 +608,10 @@ class Collection
$options['writeConcern'] = $this->writeConcern; $options['writeConcern'] = $this->writeConcern;
} }
if ( ! isset($options['typeMap'])) {
$options['typeMap'] = $this->typeMap;
}
$operation = new FindOneAndReplace($this->databaseName, $this->collectionName, $filter, $replacement, $options); $operation = new FindOneAndReplace($this->databaseName, $this->collectionName, $filter, $replacement, $options);
return $operation->execute($server); return $operation->execute($server);
...@@ -624,15 +626,12 @@ class Collection ...@@ -624,15 +626,12 @@ class Collection
* FindOneAndUpdate::RETURN_DOCUMENT_AFTER for the "returnDocument" option * FindOneAndUpdate::RETURN_DOCUMENT_AFTER for the "returnDocument" option
* to return the updated document. * to return the updated document.
* *
* Note: BSON deserialization of the returned document does not yet support
* a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
*
* @see FindOneAndReplace::__construct() for supported options * @see FindOneAndReplace::__construct() for supported options
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/ * @see http://docs.mongodb.org/manual/reference/command/findAndModify/
* @param array|object $filter Query by which to filter documents * @param array|object $filter Query by which to filter documents
* @param array|object $update Update to apply to the matched document * @param array|object $update Update to apply to the matched document
* @param array $options Command options * @param array $options Command options
* @return object|null * @return array|object|null
* @throws UnexpectedValueException if the command response was malformed * @throws UnexpectedValueException if the command response was malformed
* @throws UnsupportedException if options are not supported by the selected server * @throws UnsupportedException if options are not supported by the selected server
* @throws InvalidArgumentException for parameter/option parsing errors * @throws InvalidArgumentException for parameter/option parsing errors
...@@ -646,6 +645,10 @@ class Collection ...@@ -646,6 +645,10 @@ class Collection
$options['writeConcern'] = $this->writeConcern; $options['writeConcern'] = $this->writeConcern;
} }
if ( ! isset($options['typeMap'])) {
$options['typeMap'] = $this->typeMap;
}
$operation = new FindOneAndUpdate($this->databaseName, $this->collectionName, $filter, $update, $options); $operation = new FindOneAndUpdate($this->databaseName, $this->collectionName, $filter, $update, $options);
return $operation->execute($server); return $operation->execute($server);
......
...@@ -60,6 +60,8 @@ class FindAndModify implements Executable ...@@ -60,6 +60,8 @@ class FindAndModify implements Executable
* * sort (document): Determines which document the operation modifies if * * sort (document): Determines which document the operation modifies if
* the query selects multiple documents. * the query selects multiple documents.
* *
* * typeMap (array): Type map for BSON deserialization.
*
* * update (document): Update or replacement to apply to the matched * * update (document): Update or replacement to apply to the matched
* document. This option cannot be set if the remove option is true. * document. This option cannot be set if the remove option is true.
* *
...@@ -117,6 +119,10 @@ class FindAndModify implements Executable ...@@ -117,6 +119,10 @@ class FindAndModify implements Executable
throw InvalidArgumentException::invalidType('"sort" option', $options['sort'], 'array or object'); throw InvalidArgumentException::invalidType('"sort" option', $options['sort'], 'array or object');
} }
if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
}
if (isset($options['update']) && ! is_array($options['update']) && ! is_object($options['update'])) { if (isset($options['update']) && ! is_array($options['update']) && ! is_object($options['update'])) {
throw InvalidArgumentException::invalidType('"update" option', $options['update'], 'array or object'); throw InvalidArgumentException::invalidType('"update" option', $options['update'], 'array or object');
} }
...@@ -143,7 +149,7 @@ class FindAndModify implements Executable ...@@ -143,7 +149,7 @@ class FindAndModify implements Executable
* *
* @see Executable::execute() * @see Executable::execute()
* @param Server $server * @param Server $server
* @return object|null * @return array|object|null
* @throws UnexpectedValueException if the command response was malformed * @throws UnexpectedValueException if the command response was malformed
* @throws UnsupportedException if collation or write concern is used and unsupported * @throws UnsupportedException if collation or write concern is used and unsupported
* @throws DriverRuntimeException for other driver errors (e.g. connection errors) * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
...@@ -180,6 +186,10 @@ class FindAndModify implements Executable ...@@ -180,6 +186,10 @@ class FindAndModify implements Executable
throw new UnexpectedValueException('findAndModify command did not return a "value" document'); throw new UnexpectedValueException('findAndModify command did not return a "value" document');
} }
if (isset($this->options['typeMap'])) {
return \MongoDB\apply_type_map_to_document($result->value, $this->options['typeMap']);
}
return $result->value; return $result->value;
} }
......
...@@ -37,6 +37,8 @@ class FindOneAndDelete implements Executable ...@@ -37,6 +37,8 @@ class FindOneAndDelete implements Executable
* * sort (document): Determines which document the operation modifies if * * sort (document): Determines which document the operation modifies if
* the query selects multiple documents. * the query selects multiple documents.
* *
* * typeMap (array): Type map for BSON deserialization.
*
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern. * * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
* *
* This is not supported for server versions < 3.2 and will result in an * This is not supported for server versions < 3.2 and will result in an
...@@ -76,7 +78,7 @@ class FindOneAndDelete implements Executable ...@@ -76,7 +78,7 @@ class FindOneAndDelete implements Executable
* *
* @see Executable::execute() * @see Executable::execute()
* @param Server $server * @param Server $server
* @return object|null * @return array|object|null
* @throws UnsupportedException if collation or write concern is used and unsupported * @throws UnsupportedException if collation or write concern is used and unsupported
* @throws DriverRuntimeException for other driver errors (e.g. connection errors) * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
*/ */
......
...@@ -49,6 +49,8 @@ class FindOneAndReplace implements Executable ...@@ -49,6 +49,8 @@ class FindOneAndReplace implements Executable
* * sort (document): Determines which document the operation modifies if * * sort (document): Determines which document the operation modifies if
* the query selects multiple documents. * the query selects multiple documents.
* *
* * typeMap (array): Type map for BSON deserialization.
*
* * upsert (boolean): When true, a new document is created if no document * * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false. * matches the query. The default is false.
* *
...@@ -116,7 +118,7 @@ class FindOneAndReplace implements Executable ...@@ -116,7 +118,7 @@ class FindOneAndReplace implements Executable
* *
* @see Executable::execute() * @see Executable::execute()
* @param Server $server * @param Server $server
* @return object|null * @return array|object|null
* @throws UnsupportedException if collation or write concern is used and unsupported * @throws UnsupportedException if collation or write concern is used and unsupported
* @throws DriverRuntimeException for other driver errors (e.g. connection errors) * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
*/ */
......
...@@ -49,6 +49,8 @@ class FindOneAndUpdate implements Executable ...@@ -49,6 +49,8 @@ class FindOneAndUpdate implements Executable
* * sort (document): Determines which document the operation modifies if * * sort (document): Determines which document the operation modifies if
* the query selects multiple documents. * the query selects multiple documents.
* *
* * typeMap (array): Type map for BSON deserialization.
*
* * upsert (boolean): When true, a new document is created if no document * * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false. * matches the query. The default is false.
* *
...@@ -116,7 +118,7 @@ class FindOneAndUpdate implements Executable ...@@ -116,7 +118,7 @@ class FindOneAndUpdate implements Executable
* *
* @see Executable::execute() * @see Executable::execute()
* @param Server $server * @param Server $server
* @return object|null * @return array|object|null
* @throws UnsupportedException if collation or write concern is used and unsupported * @throws UnsupportedException if collation or write concern is used and unsupported
* @throws DriverRuntimeException for other driver errors (e.g. connection errors) * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
*/ */
......
<?php
namespace MongoDB\Tests\Operation;
use MongoDB\Driver\BulkWrite;
use MongoDB\Model\BSONDocument;
use MongoDB\Operation\FindAndModify;
class FindAndModifyFunctionalTest extends FunctionalTestCase
{
/**
* @dataProvider provideTypeMapOptionsAndExpectedDocument
*/
public function testTypeMapOption(array $typeMap = null, $expectedDocument)
{
$this->createFixtures(1);
$operation = new FindAndModify(
$this->getDatabaseName(),
$this->getCollectionName(),
[
'remove' => true,
'typeMap' => $typeMap,
]
);
$document = $operation->execute($this->getPrimaryServer());
$this->assertEquals($expectedDocument, $document);
}
public function provideTypeMapOptionsAndExpectedDocument()
{
return [
[
null,
(object) ['_id' => 1, 'x' => (object) ['foo' => 'bar']],
],
[
['root' => 'array', 'document' => 'array'],
['_id' => 1, 'x' => ['foo' => 'bar']],
],
[
['root' => 'object', 'document' => 'array'],
(object) ['_id' => 1, 'x' => ['foo' => 'bar']],
],
[
['root' => 'array', 'document' => 'stdClass'],
['_id' => 1, 'x' => (object) ['foo' => 'bar']],
],
[
['root' => 'MongoDB\Model\BSONDocument', 'document' => 'object'],
new BSONDocument(['_id' => 1, 'x' => (object) ['foo' => 'bar']]),
],
];
}
/**
* Create data fixtures.
*
* @param integer $n
*/
private function createFixtures($n)
{
$bulkWrite = new BulkWrite(['ordered' => true]);
for ($i = 1; $i <= $n; $i++) {
$bulkWrite->insert([
'_id' => $i,
'x' => (object) ['foo' => 'bar'],
]);
}
$result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
$this->assertEquals($n, $result->getInsertedCount());
}
}
...@@ -51,6 +51,10 @@ class FindAndModifyTest extends TestCase ...@@ -51,6 +51,10 @@ class FindAndModifyTest extends TestCase
$options[][] = ['sort' => $value]; $options[][] = ['sort' => $value];
} }
foreach ($this->getInvalidArrayValues() as $value) {
$options[][] = ['typeMap' => $value];
}
foreach ($this->getInvalidDocumentValues() as $value) { foreach ($this->getInvalidDocumentValues() as $value) {
$options[][] = ['update' => $value]; $options[][] = ['update' => $value];
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment