Commit 08d83140 authored by Jeremy Mikola's avatar Jeremy Mikola

PHPLIB-314: Make mapReduce inline check more robust

parent da5fb0c3
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
namespace MongoDB; namespace MongoDB;
use MongoDB\BSON\JavascriptInterface; use MongoDB\BSON\JavascriptInterface;
use MongoDB\BSON\Serializable;
use MongoDB\ChangeStream as ChangeStreamResult; use MongoDB\ChangeStream as ChangeStreamResult;
use MongoDB\Driver\Cursor; use MongoDB\Driver\Cursor;
use MongoDB\Driver\Manager; use MongoDB\Driver\Manager;
...@@ -830,7 +831,7 @@ class Collection ...@@ -830,7 +831,7 @@ class Collection
*/ */
public function mapReduce(JavascriptInterface $map, JavascriptInterface $reduce, $out, array $options = []) public function mapReduce(JavascriptInterface $map, JavascriptInterface $reduce, $out, array $options = [])
{ {
$hasOutputCollection = ! $this->isOutInline($out); $hasOutputCollection = ! $this->isMapReduceOutputInline($out);
if ( ! isset($options['readPreference'])) { if ( ! isset($options['readPreference'])) {
$options['readPreference'] = $this->readPreference; $options['readPreference'] = $this->readPreference;
...@@ -984,14 +985,37 @@ class Collection ...@@ -984,14 +985,37 @@ class Collection
return new Collection($this->manager, $this->databaseName, $this->collectionName, $options); return new Collection($this->manager, $this->databaseName, $this->collectionName, $options);
} }
private function isOutInline($out) /**
* Return whether the "out" option for a mapReduce operation is "inline".
*
* This is used to determine if a mapReduce command requires a primary.
*
* @see https://docs.mongodb.com/manual/reference/command/mapReduce/#output-inline
* @param string|array|object $out Output specification
* @return boolean
* @throws InvalidArgumentException
*/
private function isMapReduceOutputInline($out)
{ {
if ( ! is_array($out) && ! is_object($out)) { if ( ! is_array($out) && ! is_object($out)) {
return false; return false;
} }
$out = (array) $out; if ($out instanceof Serializable) {
$out = $out->bsonSerialize();
}
if (is_object($out)) {
$out = get_object_vars($out);
}
if ( ! is_array($out)) {
throw InvalidArgumentException::invalidType('$out', $out, 'array or object');
}
reset($out);
$firstKey = (string) key($out);
return key($out) === 'inline'; return $firstKey === 'inline';
} }
} }
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