-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Fix dropping in use databases on SQL Server and Oracle #2636
Fix dropping in use databases on SQL Server and Oracle #2636
Conversation
throw $exception; | ||
} | ||
|
||
$this->_execSql($this->_platform->getCloseActiveDatabaseConnectionsSQL($database)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Call on a method not defined on the abstract class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as with PostgreSQL. What shall I do here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@deeky666 one possible solution is to turn the return type into a string[]
, then have a base method always returning an empty array
. array_walk
-ing over the result is sufficient to ensure consistency then.
// because of active connections on the database. | ||
// To force dropping the database, we first have to close all active connections | ||
// on that database and issue the drop database operation again. | ||
if ($exception->getErrorCode() !== 3702) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move it to a constant, please (and document the constant)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree here. It doesn't help anyone and if we start to introduce constants for all error codes and SQL states, we will go crazy. We started with this approach when we implemented driver exception converters and discarded that approach again. This check will disappear as soon as we implement SQL Server driver as driver exception converter drivers (hopefully) as we will be able to catch a dedicated exception type then. Also it is implemented that way for PostgreSQL already and I don't want to do everything that is necessary to make it "perfect" with this PR. First I want to get the SQL Server test suite to be green. We can still improve afterwards. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me, since there is inline documentation. Also, didn't expect you to fix every instance in here.
If/when we move to PHP 7.1, then we should consider private constants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -37,6 +37,31 @@ class SQLServerSchemaManager extends AbstractSchemaManager | |||
/** | |||
* {@inheritdoc} | |||
*/ | |||
public function dropDatabase($database) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code additions here are untested. Can the scenario be replicated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is already a test case that covers this issue in SchemaManagerFunctionalTestCase::testDropsDatabaseWithActiveConnections()
* | ||
* @return string | ||
*/ | ||
public function getCloseActiveDatabaseConnectionsSQL($database) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method should probably land in the parent classes too then (sadly) :-\
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get your point but I do not want to enforce an abstraction here because it probably will be too vendor specific. Another option would be to put the SQL directly into the dropDatabase()
method in the schema manager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly a better solution if the schema manager is platform specific (and won't rely on the platform abstraction anyway).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is a "yes" let's put the SQL directly into the schema manager?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, let's stuff it in the schema manager, and add a comment about the decision
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
*/ | ||
public function getCloseActiveDatabaseConnectionsSQL($database) | ||
{ | ||
return 'ALTER DATABASE ' . $database . ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should $database
be quoted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Identifier
now.
85a2d60
to
10a12b5
Compare
79b449f
to
7b631e7
Compare
@Ocramius marking this as WIP for now as I still need to figure out how to make nasty Oracle pass here. I am testing against version 12 locally and there seem to be some difference to version 11 (CI). |
Documented an issue revealed while testing with Orcale 12c in #2643 |
ece24a2
to
ef736a5
Compare
@Ocramius ok patch is finished from my side now. You can review again. Some remarks: Obviously I had to fix the exact same issue on Oracle to make the tests pass. Approach is the same. I also had to change the privileges when creating a new database (user) on Oracle so that the user is able to see the views used in |
LGTM! 👍 |
…nd-oracledb' into 2.5 Backport #2636 to 2.5.x
Backported into |
This patch follows the same approach as for PostgreSQL. If trying to drop a database with active connections, the database server will refuse with:
The schema manager catches that specific error code now, closes all active connections on that database and executes a
DROP DATABASE
again.I had to fix the
SQLSrvException
to carry around the SQLSTATE and error code information.