diff --git a/lib/Doctrine/ORM/Id/SequenceGenerator.php b/lib/Doctrine/ORM/Id/SequenceGenerator.php index a27edae90..9d8e9eb75 100644 --- a/lib/Doctrine/ORM/Id/SequenceGenerator.php +++ b/lib/Doctrine/ORM/Id/SequenceGenerator.php @@ -76,7 +76,8 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable $conn = $em->getConnection(); $sql = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName); - $this->_nextValue = (int) $conn->fetchColumn($sql); + // Using `query` to force usage of the master server in MasterSlaveConnection + $this->_nextValue = (int) $conn->query($sql)->fetchColumn(); $this->_maxValue = $this->_nextValue + $this->_allocationSize; } diff --git a/tests/Doctrine/Tests/Mocks/ConnectionMock.php b/tests/Doctrine/Tests/Mocks/ConnectionMock.php index 5a28ffa5a..af8fc252e 100644 --- a/tests/Doctrine/Tests/Mocks/ConnectionMock.php +++ b/tests/Doctrine/Tests/Mocks/ConnectionMock.php @@ -1,7 +1,9 @@ _fetchOneException) { + throw $this->_fetchOneException; + } + return $this->_fetchOneResult; } + /** + * {@inheritdoc} + */ + public function query() : Statement + { + return $this->_queryResult; + } + /** * {@inheritdoc} */ @@ -112,6 +136,16 @@ class ConnectionMock extends Connection $this->_fetchOneResult = $fetchOneResult; } + /** + * @param \Exception|null $exception + * + * @return void + */ + public function setFetchOneException(\Exception $exception = null) + { + $this->_fetchOneException = $exception; + } + /** * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform * @@ -132,6 +166,14 @@ class ConnectionMock extends Connection $this->_lastInsertId = $id; } + /** + * @param Statement $result + */ + public function setQueryResult(Statement $result) + { + $this->_queryResult = $result; + } + /** * @return array */ diff --git a/tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php b/tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php index 5d7f7a59b..5e4247715 100644 --- a/tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php +++ b/tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php @@ -2,38 +2,58 @@ namespace Doctrine\Tests\ORM\Id; +use Doctrine\ORM\EntityManager; use Doctrine\ORM\Id\SequenceGenerator; +use Doctrine\Tests\Mocks\ConnectionMock; +use Doctrine\Tests\Mocks\StatementArrayMock; use Doctrine\Tests\OrmTestCase; -/** - * Description of SequenceGeneratorTest - * - * @author robo - */ class SequenceGeneratorTest extends OrmTestCase { - private $_em; - private $_seqGen; + /** + * @var EntityManager + */ + private $entityManager; - protected function setUp() + /** + * @var SequenceGenerator + */ + private $sequenceGenerator; + + /** + * @var ConnectionMock + */ + private $connection; + + protected function setUp() : void { - $this->_em = $this->_getTestEntityManager(); - $this->_seqGen = new SequenceGenerator('seq', 10); + parent::setUp(); + + $this->entityManager = $this->_getTestEntityManager(); + $this->sequenceGenerator = new SequenceGenerator('seq', 10); + $this->connection = $this->entityManager->getConnection(); + + self::assertInstanceOf(ConnectionMock::class, $this->connection); } - public function testGeneration() + public function testGeneration() : void { - for ($i=0; $i < 42; ++$i) { + $this->connection->setFetchOneException(new \BadMethodCallException( + 'Fetch* method used. Query method should be used instead, ' + . 'as NEXTVAL should be run on a master server in master-slave setup.' + )); + + for ($i = 0; $i < 42; ++$i) { if ($i % 10 == 0) { - $this->_em->getConnection()->setFetchOneResult((int)($i / 10) * 10); + $this->connection->setQueryResult(new StatementArrayMock([[(int)($i / 10) * 10]])); } - $id = $this->_seqGen->generate($this->_em, null); - $this->assertEquals($i, $id); - $this->assertEquals((int)($i / 10) * 10 + 10, $this->_seqGen->getCurrentMaxValue()); - $this->assertEquals($i + 1, $this->_seqGen->getNextValue()); + + $id = $this->sequenceGenerator->generate($this->entityManager, null); + + self::assertSame($i, $id); + self::assertSame((int)($i / 10) * 10 + 10, $this->sequenceGenerator->getCurrentMaxValue()); + self::assertSame($i + 1, $this->sequenceGenerator->getNextValue()); } - - } }