Merge branch 'fix/#6168-#6167-force-nextval-selection-on-the-master-server'
Close #6167 Close #6168
This commit is contained in:
commit
07a9b10f36
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Mocks;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
|
||||
/**
|
||||
* Mock class for Connection.
|
||||
@ -13,6 +15,16 @@ class ConnectionMock extends Connection
|
||||
*/
|
||||
private $_fetchOneResult;
|
||||
|
||||
/**
|
||||
* @var \Exception|null
|
||||
*/
|
||||
private $_fetchOneException;
|
||||
|
||||
/**
|
||||
* @var Statement|null
|
||||
*/
|
||||
private $_queryResult;
|
||||
|
||||
/**
|
||||
* @var DatabasePlatformMock
|
||||
*/
|
||||
@ -86,9 +98,21 @@ class ConnectionMock extends Connection
|
||||
*/
|
||||
public function fetchColumn($statement, array $params = [], $colnum = 0, array $types = [])
|
||||
{
|
||||
if (null !== $this->_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
|
||||
*/
|
||||
|
@ -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
|
||||
{
|
||||
$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);
|
||||
}
|
||||
$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());
|
||||
$this->connection->setQueryResult(new StatementArrayMock([[(int)($i / 10) * 10]]));
|
||||
}
|
||||
|
||||
$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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user