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
if ($insertedId !== null) {
$insertedIds[$i] = $insertedId;
} else {
// TODO: This may be removed if PHPC-382 is implemented
$insertedIds[$i] = is_array($args[0]) ? $args[0]['_id'] : $args[0]->_id;
$insertedIds[$i] = \MongoDB\extract_id_from_inserted_document($args[0]);
}
break;
......
......@@ -109,8 +109,7 @@ class InsertMany implements Executable
if ($insertedId !== null) {
$insertedIds[$i] = $insertedId;
} else {
// TODO: This may be removed if PHPC-382 is implemented
$insertedIds[$i] = is_array($document) ? $document['_id'] : $document->_id;
$insertedIds[$i] = \MongoDB\extract_id_from_inserted_document($document);
}
}
......
......@@ -79,8 +79,7 @@ class InsertOne implements Executable
$insertedId = $bulk->insert($this->document);
if ($insertedId === null) {
// TODO: This may be removed if PHPC-382 is implemented
$insertedId = is_array($this->document) ? $this->document['_id'] : $this->document->_id;
$insertedId = \MongoDB\extract_id_from_inserted_document($this->document);
}
$writeConcern = isset($this->options['writeConcern']) ? $this->options['writeConcern'] : null;
......
......@@ -2,11 +2,33 @@
namespace MongoDB;
use MongoDB\BSON\Serializable;
use MongoDB\Driver\ReadConcern;
use MongoDB\Driver\Server;
use MongoDB\Exception\InvalidArgumentTypeException;
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.
*
......
......@@ -5,6 +5,7 @@ namespace MongoDB\Tests\Collection;
use MongoDB\BulkWriteResult;
use MongoDB\Driver\BulkWrite as Bulk;
use MongoDB\Driver\WriteConcern;
use MongoDB\Model\BSONDocument;
use MongoDB\Operation\BulkWrite;
class BulkWriteFunctionalTest extends FunctionalTestCase
......@@ -23,21 +24,27 @@ class BulkWriteFunctionalTest extends FunctionalTestCase
$ops = [
['insertOne' => [['_id' => 1, 'x' => 11]]],
['insertOne' => [['x' => 22]]],
['insertOne' => [(object) ['_id' => 'foo', 'x' => 33]]],
['insertOne' => [new BSONDocument(['_id' => 'bar', 'x' => 44])]],
];
$operation = new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), $ops);
$result = $operation->execute($this->getPrimaryServer());
$this->assertInstanceOf('MongoDB\BulkWriteResult', $result);
$this->assertSame(2, $result->getInsertedCount());
$this->assertSame(4, $result->getInsertedCount());
$insertedIds = $result->getInsertedIds();
$this->assertSame(1, $insertedIds[0]);
$this->assertInstanceOf('MongoDB\BSON\ObjectId', $insertedIds[1]);
$this->assertSame('foo', $insertedIds[2]);
$this->assertSame('bar', $insertedIds[3]);
$expected = [
['_id' => $insertedIds[0], 'x' => 11],
['_id' => 1, 'x' => 11],
['_id' => $insertedIds[1], 'x' => 22],
['_id' => 'foo', 'x' => 33],
['_id' => 'bar', 'x' => 44],
];
$this->assertSameDocuments($expected, $this->collection->find());
......
......@@ -4,6 +4,7 @@ namespace MongoDB\Tests\Collection;
use MongoDB\InsertManyResult;
use MongoDB\Driver\WriteConcern;
use MongoDB\Model\BSONDocument;
use MongoDB\Operation\InsertMany;
class InsertManyFunctionalTest extends FunctionalTestCase
......@@ -13,24 +14,27 @@ class InsertManyFunctionalTest extends FunctionalTestCase
$documents = [
['_id' => 'foo', 'x' => 11],
['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);
$result = $operation->execute($this->getPrimaryServer());
$this->assertInstanceOf('MongoDB\InsertManyResult', $result);
$this->assertSame(3, $result->getInsertedCount());
$this->assertSame(4, $result->getInsertedCount());
$insertedIds = $result->getInsertedIds();
$this->assertSame('foo', $insertedIds[0]);
$this->assertInstanceOf('MongoDB\BSON\ObjectId', $insertedIds[1]);
$this->assertSame('bar', $insertedIds[2]);
$this->assertSame('baz', $insertedIds[3]);
$expected = [
['_id' => 'foo', 'x' => 11],
['_id' => $insertedIds[1], 'x' => 22],
['_id' => 'bar', 'x' => 22],
['_id' => 'bar', 'x' => 33],
['_id' => 'baz', 'x' => 44],
];
$this->assertSameDocuments($expected, $this->collection->find());
......
......@@ -4,14 +4,16 @@ namespace MongoDB\Tests\Collection;
use MongoDB\InsertOneResult;
use MongoDB\Driver\WriteConcern;
use MongoDB\Model\BSONDocument;
use MongoDB\Operation\InsertOne;
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);
$result = $operation->execute($this->getPrimaryServer());
......@@ -26,6 +28,15 @@ class InsertOneFunctionalTest extends FunctionalTestCase
$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()
{
$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