diff --git a/src/Illuminate/Database/Connection.php b/src/Illuminate/Database/Connection.php index e920e8fa4918..b1aedfb9015e 100755 --- a/src/Illuminate/Database/Connection.php +++ b/src/Illuminate/Database/Connection.php @@ -791,24 +791,28 @@ protected function tryAgainIfCausedByLostConnection(QueryException $e, $query, $ /** * Disconnect from the underlying PDO connection. * + * @param bool $force + * * @return void */ - public function disconnect() + public function disconnect($force = false) { - $this->setPdo(null)->setReadPdo(null); + $this->setPdo(null, $force)->setReadPdo(null); } /** * Reconnect to the database. * + * @param bool $force + * * @return void * * @throws \LogicException */ - public function reconnect() + public function reconnect($force = false) { if (is_callable($this->reconnector)) { - return call_user_func($this->reconnector, $this); + return call_user_func($this->reconnector, $this, $force); } throw new LogicException('Lost connection and no reconnector available.'); @@ -981,16 +985,19 @@ public function getReadPdo() * Set the PDO connection. * * @param \PDO|null $pdo + * @param bool $force * @return $this * * @throws \RuntimeException */ - public function setPdo($pdo) + public function setPdo($pdo, $force = false) { - if ($this->transactions >= 1) { + if ($this->transactions >= 1 && ! $force) { throw new RuntimeException("Can't swap PDO instance while within transaction."); } + $this->transactions = 0; + $this->pdo = $pdo; return $this; diff --git a/src/Illuminate/Database/DatabaseManager.php b/src/Illuminate/Database/DatabaseManager.php index 1021507c1416..f492a68ab447 100755 --- a/src/Illuminate/Database/DatabaseManager.php +++ b/src/Illuminate/Database/DatabaseManager.php @@ -106,12 +106,13 @@ public function purge($name = null) * Disconnect from the given database. * * @param string $name + * @param bool $force * @return void */ - public function disconnect($name = null) + public function disconnect($name = null, $force = true) { if (isset($this->connections[$name = $name ?: $this->getDefaultConnection()])) { - $this->connections[$name]->disconnect(); + $this->connections[$name]->disconnect($force); } } @@ -119,11 +120,12 @@ public function disconnect($name = null) * Reconnect to the given database. * * @param string $name + * @param bool $force * @return \Illuminate\Database\Connection */ - public function reconnect($name = null) + public function reconnect($name = null, $force = false) { - $this->disconnect($name = $name ?: $this->getDefaultConnection()); + $this->disconnect($name = $name ?: $this->getDefaultConnection(), $force); if (! isset($this->connections[$name])) { return $this->connection($name); @@ -193,8 +195,8 @@ protected function prepare(Connection $connection) // Here we'll set a reconnector callback. This reconnector can be any callable // so we will set a Closure to reconnect from this manager with the name of // the connection, which will allow us to reconnect from the connections. - $connection->setReconnector(function ($connection) { - $this->reconnect($connection->getName()); + $connection->setReconnector(function ($connection, $force = false) { + $this->reconnect($connection->getName(), $force); }); return $connection; diff --git a/tests/Database/DatabaseConnectionTest.php b/tests/Database/DatabaseConnectionTest.php index 71b74c1b2049..89d32040e99a 100755 --- a/tests/Database/DatabaseConnectionTest.php +++ b/tests/Database/DatabaseConnectionTest.php @@ -135,6 +135,15 @@ public function testCantSwapPDOWithOpenTransaction() $connection->disconnect(); } + public function testCanForceSwapPDOWithOpenTransaction() + { + $pdo = $this->createMock('DatabaseConnectionTestMockPDO'); + $pdo->expects($this->once())->method('beginTransaction')->will($this->returnValue(true)); + $connection = $this->getMockConnection([], $pdo); + $connection->beginTransaction(); + $connection->disconnect(true); + } + public function testBeganTransactionFiresEventsIfSet() { $pdo = $this->createMock('DatabaseConnectionTestMockPDO');