From 853bf7eace83f0a0db868ad3a80295ea4ce5bb0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Aur=C3=A9lio=20Deleu?= Date: Sat, 30 Dec 2023 15:31:20 -0300 Subject: [PATCH 1/8] Ability to establish connection without using Config Repository --- src/Illuminate/Database/DatabaseManager.php | 60 +++++++++- .../Database/DatabaseConnectionsTest.php | 105 ++++++++++++++++++ 2 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 tests/Integration/Database/DatabaseConnectionsTest.php diff --git a/src/Illuminate/Database/DatabaseManager.php b/src/Illuminate/Database/DatabaseManager.php index 84602917ea1a..a7b087598f55 100755 --- a/src/Illuminate/Database/DatabaseManager.php +++ b/src/Illuminate/Database/DatabaseManager.php @@ -101,16 +101,51 @@ public function connection($name = null) $this->makeConnection($database), $type ); - if ($this->app->bound('events')) { - $this->app['events']->dispatch( - new ConnectionEstablished($this->connections[$name]) - ); - } + $this->dispatchConnectionEstablishedEvent($this->connections[$name]); } return $this->connections[$name]; } + /** + * Get a database connection instance without using the Config Repository. + * + * @param string $name + * @param array $config + * @return \Illuminate\Database\ConnectionInterface + */ + + public function connectUsing(string $name, array $config): ConnectionInterface + { + if (isset($this->connections[$name])) { + throw new RuntimeException("Cannot establish connection [$name] because another connection already exists."); + } + + $connection = $this->factory->make($config, $name); + + $connection = $this->configure($connection, null); + + $this->dispatchConnectionEstablishedEvent($connection); + + $this->connections[$name] = $connection; + + return $this->connections[$name]; + } + + /** + * Establish a fresh connection . + * + * @param string $name + * @param array $config + * @return ConnectionInterface + */ + public function overrideUsing(string $name, array $config): ConnectionInterface + { + $this->purge($name); + + return $this->connectUsing($name, $config); + } + /** * Parse the connection into an array of the name and read / write type. * @@ -209,6 +244,21 @@ protected function configure(Connection $connection, $type) return $connection; } + /** + * If the event dispatcher is available dispatches the ConnectionEstablished event. + * + * @param Connection $connection + * @return void + */ + protected function dispatchConnectionEstablishedEvent(Connection $connection): void + { + if (! $this->app->bound('events')) { + return; + } + + $this->app['events']->dispatch(new ConnectionEstablished($connection)); + } + /** * Prepare the read / write mode for database connection instance. * diff --git a/tests/Integration/Database/DatabaseConnectionsTest.php b/tests/Integration/Database/DatabaseConnectionsTest.php new file mode 100644 index 000000000000..60bacfd20582 --- /dev/null +++ b/tests/Integration/Database/DatabaseConnectionsTest.php @@ -0,0 +1,105 @@ +app->make(DatabaseManager::class); + + $connection = $manager->connectUsing('my-phpunit-connection', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + ]); + + $connection->statement('CREATE TABLE test_1 (id INTEGER PRIMARY KEY)'); + + $connection->statement('INSERT INTO test_1 (id) VALUES (1)'); + + $result = $connection->selectOne('SELECT COUNT(*) as total FROM test_1'); + + self::assertSame(1, $result->total); + } + + public function testThrowExceptionIfConnectionAlreadyExists() + { + /** @var DatabaseManager $manager */ + $manager = $this->app->make(DatabaseManager::class); + + $manager->connectUsing('my-phpunit-connection', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + ]); + + $this->expectException(RuntimeException::class); + + $manager->connectUsing('my-phpunit-connection', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + ]); + } + + public function testOverrideExistingConnection() + { + /** @var DatabaseManager $manager */ + $manager = $this->app->make(DatabaseManager::class); + + $connection = $manager->connectUsing('my-phpunit-connection', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + ]); + + $connection->statement('CREATE TABLE test_1 (id INTEGER PRIMARY KEY)'); + + $resultBeforeOverride = $connection->select("SELECT name FROM sqlite_master WHERE type='table';"); + + $connection = $manager->overrideUsing('my-phpunit-connection', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + ]); + + // After purging a connection of a :memory: SQLite database + // anything that was created before the override will no + // longer be available. It's a new and fresh database + $resultAfterOverride = $connection->select("SELECT name FROM sqlite_master WHERE type='table';"); + + self::assertSame('test_1', $resultBeforeOverride[0]->name); + + self::assertEmpty($resultAfterOverride); + } + + public function testEstablishingAConnectionWillDispatchAnEvent() + { + /** @var Dispatcher $dispatcher */ + $dispatcher = $this->app->make(Dispatcher::class); + + $event = null; + + $dispatcher->listen(ConnectionEstablished::class, function (ConnectionEstablished $e) use (&$event) { + $event = $e; + }); + + /** @var DatabaseManager $manager */ + $manager = $this->app->make(DatabaseManager::class); + + $manager->connectUsing('my-phpunit-connection', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + ]); + + self::assertInstanceOf( + ConnectionEstablished::class, + $event, + 'Expected the ConnectionEstablished event to be dispatched when establishing a connection.' + ); + + self::assertSame('my-phpunit-connection', $event->connectionName); + } +} From 4ede364bbe93ceef70d309390062e6cfa188b78b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Aur=C3=A9lio=20Deleu?= Date: Sat, 30 Dec 2023 15:39:27 -0300 Subject: [PATCH 2/8] StyleCI --- src/Illuminate/Database/DatabaseManager.php | 3 +-- tests/Integration/Database/DatabaseConnectionsTest.php | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Database/DatabaseManager.php b/src/Illuminate/Database/DatabaseManager.php index a7b087598f55..996fb99264f6 100755 --- a/src/Illuminate/Database/DatabaseManager.php +++ b/src/Illuminate/Database/DatabaseManager.php @@ -114,7 +114,6 @@ public function connection($name = null) * @param array $config * @return \Illuminate\Database\ConnectionInterface */ - public function connectUsing(string $name, array $config): ConnectionInterface { if (isset($this->connections[$name])) { @@ -247,7 +246,7 @@ protected function configure(Connection $connection, $type) /** * If the event dispatcher is available dispatches the ConnectionEstablished event. * - * @param Connection $connection + * @param Connection $connection * @return void */ protected function dispatchConnectionEstablishedEvent(Connection $connection): void diff --git a/tests/Integration/Database/DatabaseConnectionsTest.php b/tests/Integration/Database/DatabaseConnectionsTest.php index 60bacfd20582..6d46d1b123e8 100644 --- a/tests/Integration/Database/DatabaseConnectionsTest.php +++ b/tests/Integration/Database/DatabaseConnectionsTest.php @@ -1,4 +1,6 @@ - Date: Mon, 1 Jan 2024 21:11:03 -0300 Subject: [PATCH 3/8] Update src/Illuminate/Database/DatabaseManager.php Co-authored-by: Dries Vints --- src/Illuminate/Database/DatabaseManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Database/DatabaseManager.php b/src/Illuminate/Database/DatabaseManager.php index 996fb99264f6..d8a0c373c227 100755 --- a/src/Illuminate/Database/DatabaseManager.php +++ b/src/Illuminate/Database/DatabaseManager.php @@ -132,7 +132,7 @@ public function connectUsing(string $name, array $config): ConnectionInterface } /** - * Establish a fresh connection . + * Establish a fresh connection. * * @param string $name * @param array $config From a7902f4e396fc46167013f29c91fbee05c820aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Aur=C3=A9lio=20Deleu?= Date: Mon, 1 Jan 2024 21:12:27 -0300 Subject: [PATCH 4/8] FQN --- src/Illuminate/Database/DatabaseManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Database/DatabaseManager.php b/src/Illuminate/Database/DatabaseManager.php index d8a0c373c227..329c0c358db4 100755 --- a/src/Illuminate/Database/DatabaseManager.php +++ b/src/Illuminate/Database/DatabaseManager.php @@ -246,7 +246,7 @@ protected function configure(Connection $connection, $type) /** * If the event dispatcher is available dispatches the ConnectionEstablished event. * - * @param Connection $connection + * @param \Illuminate\Database\Connection $connection * @return void */ protected function dispatchConnectionEstablishedEvent(Connection $connection): void From 19e02746273b29691372a66cb32834d33c6af96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Aur=C3=A9lio=20Deleu?= Date: Mon, 1 Jan 2024 21:13:31 -0300 Subject: [PATCH 5/8] FQN --- src/Illuminate/Database/DatabaseManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Database/DatabaseManager.php b/src/Illuminate/Database/DatabaseManager.php index 329c0c358db4..d1ca425a1e2b 100755 --- a/src/Illuminate/Database/DatabaseManager.php +++ b/src/Illuminate/Database/DatabaseManager.php @@ -136,7 +136,7 @@ public function connectUsing(string $name, array $config): ConnectionInterface * * @param string $name * @param array $config - * @return ConnectionInterface + * @return \Illuminate\Database\ConnectionInterface */ public function overrideUsing(string $name, array $config): ConnectionInterface { From 869bb6a91013ad56ddd95cb52938f3b9dc23e6fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Aur=C3=A9lio=20Deleu?= Date: Mon, 1 Jan 2024 21:15:15 -0300 Subject: [PATCH 6/8] FQN on tests as well --- tests/Integration/Database/DatabaseConnectionsTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Integration/Database/DatabaseConnectionsTest.php b/tests/Integration/Database/DatabaseConnectionsTest.php index 6d46d1b123e8..001c18a5afd8 100644 --- a/tests/Integration/Database/DatabaseConnectionsTest.php +++ b/tests/Integration/Database/DatabaseConnectionsTest.php @@ -13,7 +13,7 @@ class DatabaseConnectionsTest extends DatabaseTestCase { public function testEstablishDatabaseConnection() { - /** @var DatabaseManager $manager */ + /** @var \Illuminate\Database\DatabaseManager $manager */ $manager = $this->app->make(DatabaseManager::class); $connection = $manager->connectUsing('my-phpunit-connection', [ @@ -32,7 +32,7 @@ public function testEstablishDatabaseConnection() public function testThrowExceptionIfConnectionAlreadyExists() { - /** @var DatabaseManager $manager */ + /** @var \Illuminate\Database\DatabaseManager $manager */ $manager = $this->app->make(DatabaseManager::class); $manager->connectUsing('my-phpunit-connection', [ @@ -50,7 +50,7 @@ public function testThrowExceptionIfConnectionAlreadyExists() public function testOverrideExistingConnection() { - /** @var DatabaseManager $manager */ + /** @var \Illuminate\Database\DatabaseManager $manager */ $manager = $this->app->make(DatabaseManager::class); $connection = $manager->connectUsing('my-phpunit-connection', [ @@ -88,7 +88,7 @@ public function testEstablishingAConnectionWillDispatchAnEvent() $event = $e; }); - /** @var DatabaseManager $manager */ + /** @var \Illuminate\Database\DatabaseManager $manager */ $manager = $this->app->make(DatabaseManager::class); $manager->connectUsing('my-phpunit-connection', [ From b7f116651c61ecd7f5ccd4954da5e52ff4357075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Aur=C3=A9lio=20Deleu?= Date: Mon, 1 Jan 2024 21:15:48 -0300 Subject: [PATCH 7/8] FQN --- tests/Integration/Database/DatabaseConnectionsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Integration/Database/DatabaseConnectionsTest.php b/tests/Integration/Database/DatabaseConnectionsTest.php index 001c18a5afd8..48bb7f51792f 100644 --- a/tests/Integration/Database/DatabaseConnectionsTest.php +++ b/tests/Integration/Database/DatabaseConnectionsTest.php @@ -79,7 +79,7 @@ public function testOverrideExistingConnection() public function testEstablishingAConnectionWillDispatchAnEvent() { - /** @var Dispatcher $dispatcher */ + /** @var \Illuminate\Events\Dispatcher $dispatcher */ $dispatcher = $this->app->make(Dispatcher::class); $event = null; From ad269d38de47bf270671aa13ba5226865cdd2670 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Sun, 7 Jan 2024 09:35:28 -0600 Subject: [PATCH 8/8] formatting --- src/Illuminate/Database/DatabaseManager.php | 43 ++++++++----------- .../Database/DatabaseConnectionsTest.php | 4 +- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/Illuminate/Database/DatabaseManager.php b/src/Illuminate/Database/DatabaseManager.php index d1ca425a1e2b..daefffee9f88 100755 --- a/src/Illuminate/Database/DatabaseManager.php +++ b/src/Illuminate/Database/DatabaseManager.php @@ -108,41 +108,30 @@ public function connection($name = null) } /** - * Get a database connection instance without using the Config Repository. + * Get a database connection instance from the given configuration. * * @param string $name * @param array $config + * @param bool $force * @return \Illuminate\Database\ConnectionInterface */ - public function connectUsing(string $name, array $config): ConnectionInterface + public function connectUsing(string $name, array $config, bool $force = false) { - if (isset($this->connections[$name])) { - throw new RuntimeException("Cannot establish connection [$name] because another connection already exists."); + if ($force) { + $this->purge($name); } - $connection = $this->factory->make($config, $name); + if (isset($this->connections[$name])) { + throw new RuntimeException("Cannot establish connection [$name] because another connection with that name already exists."); + } - $connection = $this->configure($connection, null); + $connection = $this->configure( + $this->factory->make($config, $name), null + ); $this->dispatchConnectionEstablishedEvent($connection); - $this->connections[$name] = $connection; - - return $this->connections[$name]; - } - - /** - * Establish a fresh connection. - * - * @param string $name - * @param array $config - * @return \Illuminate\Database\ConnectionInterface - */ - public function overrideUsing(string $name, array $config): ConnectionInterface - { - $this->purge($name); - - return $this->connectUsing($name, $config); + return tap($connection, fn ($connection) => $this->connections[$name] = $connection); } /** @@ -244,18 +233,20 @@ protected function configure(Connection $connection, $type) } /** - * If the event dispatcher is available dispatches the ConnectionEstablished event. + * Dispatch the ConnectionEstablished event if the event dispatcher is available. * * @param \Illuminate\Database\Connection $connection * @return void */ - protected function dispatchConnectionEstablishedEvent(Connection $connection): void + protected function dispatchConnectionEstablishedEvent(Connection $connection) { if (! $this->app->bound('events')) { return; } - $this->app['events']->dispatch(new ConnectionEstablished($connection)); + $this->app['events']->dispatch( + new ConnectionEstablished($connection) + ); } /** diff --git a/tests/Integration/Database/DatabaseConnectionsTest.php b/tests/Integration/Database/DatabaseConnectionsTest.php index 48bb7f51792f..dc6b37aa6db7 100644 --- a/tests/Integration/Database/DatabaseConnectionsTest.php +++ b/tests/Integration/Database/DatabaseConnectionsTest.php @@ -62,10 +62,10 @@ public function testOverrideExistingConnection() $resultBeforeOverride = $connection->select("SELECT name FROM sqlite_master WHERE type='table';"); - $connection = $manager->overrideUsing('my-phpunit-connection', [ + $connection = $manager->connectUsing('my-phpunit-connection', [ 'driver' => 'sqlite', 'database' => ':memory:', - ]); + ], force: true); // After purging a connection of a :memory: SQLite database // anything that was created before the override will no