Commit c1c6fab8 authored by Jeremy Mikola's avatar Jeremy Mikola

PHPLIB-157: Improve _id extraction for Serializable objects

parent 6663cf70
...@@ -239,8 +239,7 @@ class BulkWrite implements Executable ...@@ -239,8 +239,7 @@ class BulkWrite implements Executable
if ($insertedId !== null) { if ($insertedId !== null) {
$insertedIds[$i] = $insertedId; $insertedIds[$i] = $insertedId;
} else { } else {
// TODO: This may be removed if PHPC-382 is implemented $insertedIds[$i] = \MongoDB\extract_id_from_inserted_document($args[0]);
$insertedIds[$i] = is_array($args[0]) ? $args[0]['_id'] : $args[0]->_id;
} }
break; break;
......
...@@ -109,8 +109,7 @@ class InsertMany implements Executable ...@@ -109,8 +109,7 @@ class InsertMany implements Executable
if ($insertedId !== null) { if ($insertedId !== null) {
$insertedIds[$i] = $insertedId; $insertedIds[$i] = $insertedId;
} else { } else {
// TODO: This may be removed if PHPC-382 is implemented $insertedIds[$i] = \MongoDB\extract_id_from_inserted_document($document);
$insertedIds[$i] = is_array($document) ? $document['_id'] : $document->_id;
} }
} }
......
...@@ -79,8 +79,7 @@ class InsertOne implements Executable ...@@ -79,8 +79,7 @@ class InsertOne implements Executable
$insertedId = $bulk->insert($this->document); $insertedId = $bulk->insert($this->document);
if ($insertedId === null) { if ($insertedId === null) {
// TODO: This may be removed if PHPC-382 is implemented $insertedId = \MongoDB\extract_id_from_inserted_document($this->document);
$insertedId = is_array($this->document) ? $this->document['_id'] : $this->document->_id;
} }
$writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null; $writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null;
......
...@@ -2,11 +2,33 @@ ...@@ -2,11 +2,33 @@
namespace MongoDB; namespace MongoDB;
use MongoDB\BSON\Serializable;
use MongoDB\Driver\ReadConcern; use MongoDB\Driver\ReadConcern;
use MongoDB\Driver\Server; use MongoDB\Driver\Server;
use MongoDB\Exception\InvalidArgumentTypeException; use MongoDB\Exception\InvalidArgumentTypeException;
use stdClass; use stdClass;
/**
* Extracts an ID from an inserted document.
*
* This function is used when BulkWrite::insert() does not return a generated
* ID, which means that the ID should be fetched from an array offset, public
* property, or in the data returned by bsonSerialize().
*
* @internal
* @see https://jira.mongodb.org/browse/PHPC-382
* @param array|object $document Inserted document
* @return mixed
*/
function extract_id_from_inserted_document($document)
{
if ($document instanceof Serializable) {
return extract_id_from_inserted_document($document->bsonSerialize());
}
return is_array($document) ? $document['_id'] : $document->_id;
}
/** /**
* Generate an index name from a key specification. * Generate an index name from a key specification.
* *
......
...@@ -5,6 +5,7 @@ namespace MongoDB\Tests\Collection; ...@@ -5,6 +5,7 @@ namespace MongoDB\Tests\Collection;
use MongoDB\BulkWriteResult; use MongoDB\BulkWriteResult;
use MongoDB\Driver\BulkWrite as Bulk; use MongoDB\Driver\BulkWrite as Bulk;
use MongoDB\Driver\WriteConcern; use MongoDB\Driver\WriteConcern;
use MongoDB\Model\BSONDocument;
use MongoDB\Operation\BulkWrite; use MongoDB\Operation\BulkWrite;
class BulkWriteFunctionalTest extends FunctionalTestCase class BulkWriteFunctionalTest extends FunctionalTestCase
...@@ -23,21 +24,27 @@ class BulkWriteFunctionalTest extends FunctionalTestCase ...@@ -23,21 +24,27 @@ class BulkWriteFunctionalTest extends FunctionalTestCase
$ops = [ $ops = [
['insertOne' => [['_id' => 1, 'x' => 11]]], ['insertOne' => [['_id' => 1, 'x' => 11]]],
['insertOne' => [['x' => 22]]], ['insertOne' => [['x' => 22]]],
['insertOne' => [(object) ['_id' => 'foo', 'x' => 33]]],
['insertOne' => [new BSONDocument(['_id' => 'bar', 'x' => 44])]],
]; ];
$operation = new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), $ops); $operation = new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), $ops);
$result = $operation->execute($this->getPrimaryServer()); $result = $operation->execute($this->getPrimaryServer());
$this->assertInstanceOf('MongoDB\BulkWriteResult', $result); $this->assertInstanceOf('MongoDB\BulkWriteResult', $result);
$this->assertSame(2, $result->getInsertedCount()); $this->assertSame(4, $result->getInsertedCount());
$insertedIds = $result->getInsertedIds(); $insertedIds = $result->getInsertedIds();
$this->assertSame(1, $insertedIds[0]); $this->assertSame(1, $insertedIds[0]);
$this->assertInstanceOf('MongoDB\BSON\ObjectId', $insertedIds[1]); $this->assertInstanceOf('MongoDB\BSON\ObjectId', $insertedIds[1]);
$this->assertSame('foo', $insertedIds[2]);
$this->assertSame('bar', $insertedIds[3]);
$expected = [ $expected = [
['_id' => $insertedIds[0], 'x' => 11], ['_id' => 1, 'x' => 11],
['_id' => $insertedIds[1], 'x' => 22], ['_id' => $insertedIds[1], 'x' => 22],
['_id' => 'foo', 'x' => 33],
['_id' => 'bar', 'x' => 44],
]; ];
$this->assertSameDocuments($expected, $this->collection->find()); $this->assertSameDocuments($expected, $this->collection->find());
......
...@@ -4,6 +4,7 @@ namespace MongoDB\Tests\Collection; ...@@ -4,6 +4,7 @@ namespace MongoDB\Tests\Collection;
use MongoDB\InsertManyResult; use MongoDB\InsertManyResult;
use MongoDB\Driver\WriteConcern; use MongoDB\Driver\WriteConcern;
use MongoDB\Model\BSONDocument;
use MongoDB\Operation\InsertMany; use MongoDB\Operation\InsertMany;
class InsertManyFunctionalTest extends FunctionalTestCase class InsertManyFunctionalTest extends FunctionalTestCase
...@@ -13,24 +14,27 @@ class InsertManyFunctionalTest extends FunctionalTestCase ...@@ -13,24 +14,27 @@ class InsertManyFunctionalTest extends FunctionalTestCase
$documents = [ $documents = [
['_id' => 'foo', 'x' => 11], ['_id' => 'foo', 'x' => 11],
['x' => 22], ['x' => 22],
['_id' => 'bar', 'x' => 22], (object) ['_id' => 'bar', 'x' => 33],
new BSONDocument(['_id' => 'baz', 'x' => 44]),
]; ];
$operation = new InsertMany($this->getDatabaseName(), $this->getCollectionName(), $documents); $operation = new InsertMany($this->getDatabaseName(), $this->getCollectionName(), $documents);
$result = $operation->execute($this->getPrimaryServer()); $result = $operation->execute($this->getPrimaryServer());
$this->assertInstanceOf('MongoDB\InsertManyResult', $result); $this->assertInstanceOf('MongoDB\InsertManyResult', $result);
$this->assertSame(3, $result->getInsertedCount()); $this->assertSame(4, $result->getInsertedCount());
$insertedIds = $result->getInsertedIds(); $insertedIds = $result->getInsertedIds();
$this->assertSame('foo', $insertedIds[0]); $this->assertSame('foo', $insertedIds[0]);
$this->assertInstanceOf('MongoDB\BSON\ObjectId', $insertedIds[1]); $this->assertInstanceOf('MongoDB\BSON\ObjectId', $insertedIds[1]);
$this->assertSame('bar', $insertedIds[2]); $this->assertSame('bar', $insertedIds[2]);
$this->assertSame('baz', $insertedIds[3]);
$expected = [ $expected = [
['_id' => 'foo', 'x' => 11], ['_id' => 'foo', 'x' => 11],
['_id' => $insertedIds[1], 'x' => 22], ['_id' => $insertedIds[1], 'x' => 22],
['_id' => 'bar', 'x' => 22], ['_id' => 'bar', 'x' => 33],
['_id' => 'baz', 'x' => 44],
]; ];
$this->assertSameDocuments($expected, $this->collection->find()); $this->assertSameDocuments($expected, $this->collection->find());
......
...@@ -4,14 +4,16 @@ namespace MongoDB\Tests\Collection; ...@@ -4,14 +4,16 @@ namespace MongoDB\Tests\Collection;
use MongoDB\InsertOneResult; use MongoDB\InsertOneResult;
use MongoDB\Driver\WriteConcern; use MongoDB\Driver\WriteConcern;
use MongoDB\Model\BSONDocument;
use MongoDB\Operation\InsertOne; use MongoDB\Operation\InsertOne;
class InsertOneFunctionalTest extends FunctionalTestCase class InsertOneFunctionalTest extends FunctionalTestCase
{ {
public function testInsertOneWithExistingId() /**
* @dataProvider provideDocumentWithExistingId
*/
public function testInsertOneWithExistingId($document)
{ {
$document = ['_id' => 'foo', 'x' => 11];
$operation = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), $document); $operation = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), $document);
$result = $operation->execute($this->getPrimaryServer()); $result = $operation->execute($this->getPrimaryServer());
...@@ -26,6 +28,15 @@ class InsertOneFunctionalTest extends FunctionalTestCase ...@@ -26,6 +28,15 @@ class InsertOneFunctionalTest extends FunctionalTestCase
$this->assertSameDocuments($expected, $this->collection->find()); $this->assertSameDocuments($expected, $this->collection->find());
} }
public function provideDocumentWithExistingId()
{
return [
[['_id' => 'foo', 'x' => 11]],
[(object) ['_id' => 'foo', 'x' => 11]],
[new BSONDocument(['_id' => 'foo', 'x' => 11])],
];
}
public function testInsertOneWithGeneratedId() public function testInsertOneWithGeneratedId()
{ {
$document = ['x' => 11]; $document = ['x' => 11];
......
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