Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #6167 - Forced SELECT NEXTVAL to be run on master #6168

Closed

Conversation

mkurzeja
Copy link
Contributor

@mkurzeja mkurzeja commented Dec 9, 2016

A possible solution for #6167 - Doctrine ORM failing to insert to a master-slave PostgreSQL setup because of running NEXTVAL on a slave.

@Ocramius
Copy link
Member

Ocramius commented Dec 9, 2016

Requires a test case

@mkurzeja
Copy link
Contributor Author

mkurzeja commented Dec 9, 2016

And it seems it broke support for other databases.

@mkurzeja
Copy link
Contributor Author

mkurzeja commented Dec 9, 2016

Ok, so this does not break any DB support, it just does not fit the tests written. I will provide a fix and a new test for this scenario.

@mkurzeja
Copy link
Contributor Author

@Ocramius I have fixed the existing test, but I cannot think about a good test that could be run in CI. Travis does not support master-slave setup, and the whole logic is inside MasterSlaveConnection that I did not touch at all. I would have to write a custom test that wouldn't be run on Travis, or I would have to mock a lot of things just to check that MasterSlaveConnection::query() is run on the master server. Please let me know if I'm missing something and there is a better way to test this case.

@Ocramius
Copy link
Member

@mkurzeja what you could do is writing a test that asserts that query is used, whereas fetchColumn isn't, is sufficient.

Can be done via a mock/spy, and indeed needs some documentation around it.

for ($i=0; $i < 42; ++$i) {
if ($i % 10 == 0) {
$this->_em->getConnection()->setFetchOneResult((int)($i / 10) * 10);
$nextId = array(array((int)($i / 10) * 10));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mkurzeja please use short-array syntax here ;)

Copy link
Contributor

@phansys phansys left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Status: Needs work.

@@ -86,12 +97,24 @@ public function lastInsertId($seqName = null)
*/
public function fetchColumn($statement, array $params = array(), $colnum = 0, array $types = array())
{
if ($this->_fetchOneException != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, use Yoda condition and strict comparison.

@@ -113,6 +136,16 @@ public function setFetchOneResult($fetchOneResult)
}

/**
* @param \Exception $exception
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, update this docblock in order to reflect that this param also accepts null.

@@ -133,6 +166,14 @@ public function setLastInsertId($id)
}

/**
* @param Statement $result
*/
public function setQueryResult($result)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can $result argument be declared as Statement?

@@ -23,17 +24,20 @@ protected function setUp()

public function testGeneration()
{
$this->_em->getConnection()->setFetchOneException(
new \Exception('Fetch* method used. Query method should be used instead, as NEXTVAL should be run on a master server in master-slave setup.')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SPL \LogicException or \RuntimeException could be less generic.

@mkurzeja
Copy link
Contributor Author

Thanks @phansys and @lcobucci for review and @Ocramius for help. Hope this is acceptable now ;)

@@ -86,12 +97,24 @@ public function lastInsertId($seqName = null)
*/
public function fetchColumn($statement, array $params = [], $colnum = 0, array $types = [])
{
if (null !== $this->_fetchOneException) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense, but I'll probably have to change it to use the mocking framework to do this (on merge)

@Ocramius Ocramius added this to the 2.6.0 milestone Dec 12, 2016
@Ocramius Ocramius self-assigned this Dec 12, 2016
Ocramius added a commit that referenced this pull request Jun 21, 2017
Ocramius added a commit that referenced this pull request Jun 21, 2017
@Ocramius Ocramius closed this in 07a9b10 Jun 21, 2017
@Ocramius
Copy link
Member

This has been manually rebased and merged into master via 07a9b10

Thanks @mkurzeja \o/

@wlzch
Copy link

wlzch commented Nov 15, 2017

Hi,

Any reason why is this not merged into 2.5 branch? Also is there a workaround if I want to use it in v2.5? Thanks.

@gigi
Copy link

gigi commented Nov 20, 2017

Hi!
We need this fix in 2.5 too. Any solutions? Thanx

@lcobucci
Copy link
Member

@wlzch @gigi I've just tried to backport this and unfortunately it cannot be done easily, since it has dependencies on things that only exists on v2.6 (and backporting these things might lead us down the rabbit hole).

As stated on every single v2.5.x milestone in repo since 2.5.8, we no longer actively support 2.5.x since we must release v2.6 ASAP. So, sorry but this won't be part of any v2.5.x release.

@gigi
Copy link

gigi commented Nov 24, 2017

@lcobucci
Thanks for answer!
But is it not enough to replace $this->_nextValue = (int)$conn->fetchColumn($sql); with $this->_nextValue = (int) $conn->query($sql)->fetchColumn(); in \Doctrine\ORM\Id\SequenceGenerator::generate?

@lcobucci
Copy link
Member

@gigi not really, we need to get the tests as well to make sure things work and that's the tricky part

@lcobucci
Copy link
Member

@gigi if you have the time and need this really badly (and can't update your stack to use 2.6) you can try to cherry-pick the commits related to the merge commit that @Ocramius mentioned with all the dependencies (ensuring that things are compatible with PHP 5.4) please do it and send us a PR.

gigi pushed a commit to gigi/doctrine2 that referenced this pull request Nov 27, 2017
… is used instead of `fetchColumn`

(cherry picked from commit d2be4a2)
gigi pushed a commit to gigi/doctrine2 that referenced this pull request Nov 27, 2017
…cblocks/return-types

(cherry picked from commit 462481e)
gigi pushed a commit to gigi/doctrine2 that referenced this pull request Nov 27, 2017
…r readability and error messages

(cherry picked from commit a97c265)
@gigi
Copy link

gigi commented Nov 27, 2017

@lcobucci #6852

@lcobucci lcobucci modified the milestones: 2.6.0, 2.5.13 Nov 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Development

Successfully merging this pull request may close these issues.

None yet

6 participants