Skip to content

Commit d424ce7

Browse files
deleugpndriesvintstaylorotwell
authored
[10.x] Ability to establish connection without using Config Repository (#49527)
* Ability to establish connection without using Config Repository * StyleCI * Update src/Illuminate/Database/DatabaseManager.php Co-authored-by: Dries Vints <[email protected]> * FQN * FQN * FQN on tests as well * FQN * formatting --------- Co-authored-by: Dries Vints <[email protected]> Co-authored-by: Taylor Otwell <[email protected]>
1 parent 29a96eb commit d424ce7

File tree

2 files changed

+152
-5
lines changed

2 files changed

+152
-5
lines changed

src/Illuminate/Database/DatabaseManager.php

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,16 +101,39 @@ public function connection($name = null)
101101
$this->makeConnection($database), $type
102102
);
103103

104-
if ($this->app->bound('events')) {
105-
$this->app['events']->dispatch(
106-
new ConnectionEstablished($this->connections[$name])
107-
);
108-
}
104+
$this->dispatchConnectionEstablishedEvent($this->connections[$name]);
109105
}
110106

111107
return $this->connections[$name];
112108
}
113109

110+
/**
111+
* Get a database connection instance from the given configuration.
112+
*
113+
* @param string $name
114+
* @param array $config
115+
* @param bool $force
116+
* @return \Illuminate\Database\ConnectionInterface
117+
*/
118+
public function connectUsing(string $name, array $config, bool $force = false)
119+
{
120+
if ($force) {
121+
$this->purge($name);
122+
}
123+
124+
if (isset($this->connections[$name])) {
125+
throw new RuntimeException("Cannot establish connection [$name] because another connection with that name already exists.");
126+
}
127+
128+
$connection = $this->configure(
129+
$this->factory->make($config, $name), null
130+
);
131+
132+
$this->dispatchConnectionEstablishedEvent($connection);
133+
134+
return tap($connection, fn ($connection) => $this->connections[$name] = $connection);
135+
}
136+
114137
/**
115138
* Parse the connection into an array of the name and read / write type.
116139
*
@@ -209,6 +232,23 @@ protected function configure(Connection $connection, $type)
209232
return $connection;
210233
}
211234

235+
/**
236+
* Dispatch the ConnectionEstablished event if the event dispatcher is available.
237+
*
238+
* @param \Illuminate\Database\Connection $connection
239+
* @return void
240+
*/
241+
protected function dispatchConnectionEstablishedEvent(Connection $connection)
242+
{
243+
if (! $this->app->bound('events')) {
244+
return;
245+
}
246+
247+
$this->app['events']->dispatch(
248+
new ConnectionEstablished($connection)
249+
);
250+
}
251+
212252
/**
213253
* Prepare the read / write mode for database connection instance.
214254
*
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Illuminate\Tests\Integration\Database;
6+
7+
use Illuminate\Database\DatabaseManager;
8+
use Illuminate\Database\Events\ConnectionEstablished;
9+
use Illuminate\Events\Dispatcher;
10+
use RuntimeException;
11+
12+
class DatabaseConnectionsTest extends DatabaseTestCase
13+
{
14+
public function testEstablishDatabaseConnection()
15+
{
16+
/** @var \Illuminate\Database\DatabaseManager $manager */
17+
$manager = $this->app->make(DatabaseManager::class);
18+
19+
$connection = $manager->connectUsing('my-phpunit-connection', [
20+
'driver' => 'sqlite',
21+
'database' => ':memory:',
22+
]);
23+
24+
$connection->statement('CREATE TABLE test_1 (id INTEGER PRIMARY KEY)');
25+
26+
$connection->statement('INSERT INTO test_1 (id) VALUES (1)');
27+
28+
$result = $connection->selectOne('SELECT COUNT(*) as total FROM test_1');
29+
30+
self::assertSame(1, $result->total);
31+
}
32+
33+
public function testThrowExceptionIfConnectionAlreadyExists()
34+
{
35+
/** @var \Illuminate\Database\DatabaseManager $manager */
36+
$manager = $this->app->make(DatabaseManager::class);
37+
38+
$manager->connectUsing('my-phpunit-connection', [
39+
'driver' => 'sqlite',
40+
'database' => ':memory:',
41+
]);
42+
43+
$this->expectException(RuntimeException::class);
44+
45+
$manager->connectUsing('my-phpunit-connection', [
46+
'driver' => 'sqlite',
47+
'database' => ':memory:',
48+
]);
49+
}
50+
51+
public function testOverrideExistingConnection()
52+
{
53+
/** @var \Illuminate\Database\DatabaseManager $manager */
54+
$manager = $this->app->make(DatabaseManager::class);
55+
56+
$connection = $manager->connectUsing('my-phpunit-connection', [
57+
'driver' => 'sqlite',
58+
'database' => ':memory:',
59+
]);
60+
61+
$connection->statement('CREATE TABLE test_1 (id INTEGER PRIMARY KEY)');
62+
63+
$resultBeforeOverride = $connection->select("SELECT name FROM sqlite_master WHERE type='table';");
64+
65+
$connection = $manager->connectUsing('my-phpunit-connection', [
66+
'driver' => 'sqlite',
67+
'database' => ':memory:',
68+
], force: true);
69+
70+
// After purging a connection of a :memory: SQLite database
71+
// anything that was created before the override will no
72+
// longer be available. It's a new and fresh database
73+
$resultAfterOverride = $connection->select("SELECT name FROM sqlite_master WHERE type='table';");
74+
75+
self::assertSame('test_1', $resultBeforeOverride[0]->name);
76+
77+
self::assertEmpty($resultAfterOverride);
78+
}
79+
80+
public function testEstablishingAConnectionWillDispatchAnEvent()
81+
{
82+
/** @var \Illuminate\Events\Dispatcher $dispatcher */
83+
$dispatcher = $this->app->make(Dispatcher::class);
84+
85+
$event = null;
86+
87+
$dispatcher->listen(ConnectionEstablished::class, function (ConnectionEstablished $e) use (&$event) {
88+
$event = $e;
89+
});
90+
91+
/** @var \Illuminate\Database\DatabaseManager $manager */
92+
$manager = $this->app->make(DatabaseManager::class);
93+
94+
$manager->connectUsing('my-phpunit-connection', [
95+
'driver' => 'sqlite',
96+
'database' => ':memory:',
97+
]);
98+
99+
self::assertInstanceOf(
100+
ConnectionEstablished::class,
101+
$event,
102+
'Expected the ConnectionEstablished event to be dispatched when establishing a connection.'
103+
);
104+
105+
self::assertSame('my-phpunit-connection', $event->connectionName);
106+
}
107+
}

0 commit comments

Comments
 (0)