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

Fixes issue (DBAL-1057) use default platform when not connected #783

Conversation

weaverryan
Copy link
Contributor

Hi guys!

This is a fix for http://www.doctrine-project.org/jira/browse/DBAL-1057. It leaves the ability to set the platform and platform version from sha: 3176f51, but does not try to connect if we're not already connected. This is consistent with the previous behavior (again see the linked sha) - before there was never a connection made to determine the platform.

The alternate solution is to connect, but surround this by a try-catch (PDOException, DriverException, Exception?) and return null. in case we have some situation where the database isn't created or the connection information is wrong.

I know this issue is causing a lot of problems around my world (I ran into myself yesterday), so thanks in advance for the attention.

Thanks!

…e an error

For example, if you have no database, then previously, we would try to connect,
causing an error. But in this case, we can simple fall back to the default platform.
This is exactly what the previous version did (see sha: 3176f51),
and thus this adds the nice fallback we had before, without removing the flexibility
of setting your exact server version or determining it once there *is* a connection
@doctrinebot
Copy link

Hello,

thank you for creating this pull request. However did not open it on the "master"
branch. Our Git workflow requires all pull requests to go through "master" branch
and the release masters then merge them back into stable branches, if they are
bug fixes.

Please open the pull request again for the "master" branch and close
this one.

Nevertheless I have opened a Jira ticket for this Pull Request to track this
issue:

http://www.doctrine-project.org/jira/browse/DBAL-1129

We use Jira to track the state of pull requests and the versions they got
included in.

@weaverryan weaverryan closed this Jan 23, 2015
@Ocramius
Copy link
Member

@weaverryan can you inspect testability of this change?

@weaverryan weaverryan reopened this Jan 23, 2015
@weaverryan
Copy link
Contributor Author

@Ocramius yep, let me see about that now. Is this ok that it's against the 2.5 branch? My branch is based off of 2.5.

@Ocramius
Copy link
Member

@weaverryan we can handle merging back int master, yeah: we'd simply cherry pick and rebase

@weaverryan
Copy link
Contributor Author

@Ocramius I've just added a test for this, it's very simple: calling Connection::getDatabasePlatform() in ConnectionTest WAS failing before this patch, because the params passed to Connection in the test are bogus. The fact that we can call this (with bogus params) and not get an exception shows the functionality.

I also removed another test that I think os bogus - see #784.

Thanks!

For me, this makes more sense. Without this, if getDatabasePlatform() is called
consistently before connection(), then the platform will *never* connect to
get the version and use the *best* platform - it will always use the fallback.
This *does* use the connection, but doesn't explode for the edge cases when
the connection information is invalid.
@weaverryan
Copy link
Contributor Author

I just changed the implementation to use try-catch at sha: 2db254d. I can go either way but this makes more sense to me.

Thanks!

@@ -403,13 +403,12 @@ public function testFetchColumn()
$this->assertSame($result, $conn->fetchColumn($statement, $params, $column, $types));
}

public function testConnectionIsClosed()
Copy link
Member

Choose a reason for hiding this comment

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

@weaverryan why was this test actually removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't believe this is a valid test, which is what I'm arguing here: https://github.com/doctrine/dbal/pull/784/files#r23499338. I would like to remove this test - I was using that PR simply to abuse Travis to show how the test was passing for the wrong reason.

@SoboLAN
Copy link

SoboLAN commented Jan 26, 2015

I think surrounding the connection statement with try-catch and returning null if it fails is more of a hack than a fix.

What I mean is... let's have an example:

  • if I have 2 projects in Symfony: project A and project B
  • project A depends on Doctrine/DBAL, project B does not

In this situation, if I only use project B, then there will always be a connection made to the database, even if I never use it. Not really ideal.

@stof
Copy link
Member

stof commented Jan 26, 2015

@SoboLAN if you have 2 projects, you should probably use 2 kernels, so that your project which does not need DBAL does not load it at all. It is not related to this fix at all

@weaverryan
Copy link
Contributor Author

Hi guys!

I just hit this in a room of trainees today as we started a new Symfony 2.6 project. We tried to generate an entity (not a DB-connecting operation), and it bombed out (we hadn't even talked DB credentials yet). This seems small, but in practical terms, it affects all new Symfony 2.6 projects the moment they first interact with Doctrine. I'm happy to make any changes necessary.

@SoboLAN I won't agree or disagree actually :). But regardless, a connection is made currently if you ask for the database platform - that's a fact of this DBAL version (I want to not discuss it here for reasons of focus). This PR simply says: if that existing "open a connection" fails while figuring out the DB platform, don't bomb out, just use the default platform (which is the behavior of the last DBAL version).

Thanks for everyone's time :)

@Ocramius
Copy link
Member

OT: please don't teach entity generation to trainees ;-)

$this->connect();
try {
$this->connect();
} catch (DriverException $e) {
Copy link
Member

Choose a reason for hiding this comment

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

I'm still unhappy silencing all kind of connection errors as it also silences errors for valid credentials when there are other problems such as failing network or whatever.
Returning the default platform in such cases still might be fine 90% of the time but in IMO this is a hack to come around "invalid" (since 2.5) getDatabasePlatform() calls from userland. This really is breaking the feature that was implemented here and might be causing more trouble in the end than it solves.
The question is why do you need the platform at all if not connected? And what advantage do you have by retrieving just "some" platform that might be incompatible with your backend anyways? Before DBAL 2.5 that was just plain wrong IMO.
One might strongly disagree with my opinion here and "just don't care" but then all this platform version specific behaviour stuff that got implemented over the past few years is pretty useless.
I get the problems and the frustration this issue currently creates but we really please should not hack around that feature here. Instead we should fix calling libs to just use DBAL in the right way or revert the whole feature...
Just my 2 cents...

Copy link
Member

Choose a reason for hiding this comment

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

@deeky666 the issue is that many places in Doctrine ORM (and in some places in DBAL too IIRC) are retrieving the platform eagerly in constructors to optimize performance by avoiding to call the platform getter multiple times.

@weaverryan
Copy link
Contributor Author

@Ocramius but if I make them do it by hand the first time, they will kick me out of the room :p

@weaverryan
Copy link
Contributor Author

@deeky666 Thanks very much for the clarification! I don't love the BC break, but I also see that it's well-documented in the UPGRADE log :).

I have opened doctrine/orm#1294, which i believe fixes the biggest "userland" bad use of this method (indeed, it's calling getDatabasePlatform() in situations where it doesn't even need that information).

Thanks!

@weaverryan weaverryan closed this Jan 29, 2015
@deeky666
Copy link
Member

@weaverryan thank you for your patience and help! Fixing the ORM to avoid unneccesary getDatabasePaltform() calls is a good first step. I believe the bigger problem (Symfony-wise) is in the DoctrineBundle here. Registering mapping types requires retrieving the platform currently. We have to find a solution for that so that commands like doctrine:database:create work again. I believe the ConnectionFactory is the biggest problem as it is utilized nearly everywhere in Symfony userland AFAIK.

@stof
Copy link
Member

stof commented Jan 30, 2015

@deeky666 for DoctrineBundle, anyone creating DBAL types with the uptodate ways to mark them as commented or as mapped to DB types (i.e. in the type itself) would not trigger this code anymore (it is the legacy way to register the type mapping). Thus newcomers won't be registering custom types. This is not the cause of their issue.
The bigger issue for Symfony users is because of the issues in the ORM.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants