Skip to content

Commit

Permalink
Merge pull request #1661 from alcaeus/increment-generator-custom-star…
Browse files Browse the repository at this point in the history
…t-value

Enable a custom starting id
  • Loading branch information
alcaeus committed Oct 22, 2017
2 parents 87af93d + 3a8ce1a commit 7bfeaf4
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 9 deletions.
45 changes: 36 additions & 9 deletions lib/Doctrine/ODM/MongoDB/Id/IncrementGenerator.php
Expand Up @@ -38,6 +38,7 @@ class IncrementGenerator extends AbstractIdGenerator
{
protected $collection = null;
protected $key = null;
protected $startingId = 1;

public function setCollection($collection)
{
Expand All @@ -49,6 +50,11 @@ public function setKey($key)
$this->key = $key;
}

public function setStartingId($startingId)
{
$this->startingId = $startingId;
}

/** @inheritDoc */
public function generate(DocumentManager $dm, $document)
{
Expand All @@ -58,16 +64,37 @@ public function generate(DocumentManager $dm, $document)
$coll = $this->collection ?: 'doctrine_increment_ids';
$key = $this->key ?: $dm->getDocumentCollection($className)->getName();

$query = array('_id' => $key);
$newObj = array('$inc' => array('current_id' => 1));

$command = array();
$command['findandmodify'] = $coll;
$command['query'] = $query;
$command['update'] = $newObj;
$command['upsert'] = true;
$command['new'] = true;
/*
* Unable to use '$inc' and '$setOnInsert' together due to known bug.
* @see https://jira.mongodb.org/browse/SERVER-10711
* Results in error: Cannot update 'current_id' and 'current_id' at the same time
*/
$command = [
'findAndModify' => $coll,
'query' => ['_id' => $key, 'current_id' => ['$exists' => true]],
'update' => ['$inc' => ['current_id' => 1]],
'upsert' => false,
'new' => true,
];
$result = $db->command($command);

/*
* Updated nothing - counter doesn't exist, creating new counter.
* Not bothering with {$exists: false} in the criteria as that won't avoid
* an exception during a possible race condition.
*/
if (array_key_exists('value', $result) && ! isset($result['value'])) {
$command = [
'findAndModify' => $coll,
'query' => ['_id' => $key],
'update' => ['$inc' => ['current_id' => $this->startingId]],
'upsert' => true,
'new' => true,
];
$db->command($command);
return $this->startingId;
}

return $result['value']['current_id'];
}
}
3 changes: 3 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataFactory.php
Expand Up @@ -230,6 +230,9 @@ private function completeIdGeneratorMapping(ClassMetadataInfo $class)
if (isset($idGenOptions['collection'])) {
$incrementGenerator->setCollection($idGenOptions['collection']);
}
if (isset($idGenOptions['startingId'])) {
$incrementGenerator->setStartingId((int) $idGenOptions['startingId']);
}
$class->setIdGenerator($incrementGenerator);
break;
case ClassMetadata::GENERATOR_TYPE_UUID:
Expand Down
35 changes: 35 additions & 0 deletions tests/Doctrine/ODM/MongoDB/Tests/Functional/IdTest.php
Expand Up @@ -86,6 +86,20 @@ public function testCollectionId()

}

public function testCollectionIdWithStartingId()
{
$user1 = new CollectionIdUserWithStartingId('Jonathan H. Wage');
$user2 = new CollectionIdUserWithStartingId('Jonathan H. Wage');

$this->dm->persist($user1);
$this->dm->persist($user2);
$this->dm->flush();
$this->dm->clear();

$this->assertEquals($user1->id, 10);
$this->assertEquals($user2->id, 11);
}

public function testEmbeddedDocumentWithId()
{
$user1 = new CollectionIdUser('Jonathan H. Wage');
Expand Down Expand Up @@ -390,6 +404,27 @@ public function __construct($name)
}
}

/** @ODM\Document */
class CollectionIdUserWithStartingId
{
/** @ODM\Id(strategy="increment", options={"startingId"=10}) */
public $id;

/** @ODM\Field(name="t", type="string") */
public $name;

/** @ODM\ReferenceOne(targetDocument="ReferencedCollectionId", cascade={"persist"}) */
public $reference;

/** @ODM\EmbedMany(targetDocument="EmbeddedCollectionId") */
public $embedded = array();

public function __construct($name)
{
$this->name = $name;
}
}

/** @ODM\Document */
class ReferencedCollectionId
{
Expand Down
36 changes: 36 additions & 0 deletions tests/Doctrine/ODM/MongoDB/Tests/Id/IncrementGeneratorTest.php
@@ -0,0 +1,36 @@
<?php

namespace Doctrine\ODM\MongoDB\Tests\Id;

use Doctrine\ODM\MongoDB\Id\IncrementGenerator;
use Documents\User;

class IncrementGeneratorTest extends \Doctrine\ODM\MongoDB\Tests\BaseTest
{
public function testIdGeneratorWithStartingValue()
{
$generator = new IncrementGenerator();
$generator->setStartingId(10);

$collection = $this->dm->getConnection()->selectCollection(DOCTRINE_MONGODB_DATABASE, 'doctrine_increment_ids');

$this->assertSame(10, $generator->generate($this->dm, new User()));
$result = $collection->findOne(['_id' => 'users']);
self::assertSame(10, $result['current_id']);

$this->assertSame(11, $generator->generate($this->dm, new User()));
$result = $collection->findOne(['_id' => 'users']);
self::assertSame(11, $result['current_id']);
}

public function testUsesOneAsStartingValueIfNotOverridden()
{
$generator = new IncrementGenerator();

$this->assertSame(1, $generator->generate($this->dm, new User()));

$collection = $this->dm->getConnection()->selectCollection(DOCTRINE_MONGODB_DATABASE, 'doctrine_increment_ids');
$result = $collection->findOne(['_id' => 'users']);
self::assertSame(1, $result['current_id']);
}
}

0 comments on commit 7bfeaf4

Please sign in to comment.