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

[10.x] Ability to establish connection without using Config Repository #49527

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 45 additions & 5 deletions src/Illuminate/Database/DatabaseManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,39 @@ 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 from the given configuration.
*
* @param string $name
* @param array $config
* @param bool $force
* @return \Illuminate\Database\ConnectionInterface
*/
public function connectUsing(string $name, array $config, bool $force = false)
{
if ($force) {
$this->purge($name);
}

if (isset($this->connections[$name])) {
throw new RuntimeException("Cannot establish connection [$name] because another connection with that name already exists.");
}

$connection = $this->configure(
$this->factory->make($config, $name), null
);

$this->dispatchConnectionEstablishedEvent($connection);

return tap($connection, fn ($connection) => $this->connections[$name] = $connection);
}

/**
* Parse the connection into an array of the name and read / write type.
*
Expand Down Expand Up @@ -209,6 +232,23 @@ protected function configure(Connection $connection, $type)
return $connection;
}

/**
* Dispatch the ConnectionEstablished event if the event dispatcher is available.
*
* @param \Illuminate\Database\Connection $connection
* @return void
*/
protected function dispatchConnectionEstablishedEvent(Connection $connection)
{
if (! $this->app->bound('events')) {
return;
}

$this->app['events']->dispatch(
new ConnectionEstablished($connection)
);
}

/**
* Prepare the read / write mode for database connection instance.
*
Expand Down
107 changes: 107 additions & 0 deletions tests/Integration/Database/DatabaseConnectionsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

declare(strict_types=1);

namespace Illuminate\Tests\Integration\Database;

use Illuminate\Database\DatabaseManager;
use Illuminate\Database\Events\ConnectionEstablished;
use Illuminate\Events\Dispatcher;
use RuntimeException;

class DatabaseConnectionsTest extends DatabaseTestCase
{
public function testEstablishDatabaseConnection()
{
/** @var \Illuminate\Database\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)');

$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 \Illuminate\Database\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 \Illuminate\Database\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->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
// 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 \Illuminate\Events\Dispatcher $dispatcher */
$dispatcher = $this->app->make(Dispatcher::class);

$event = null;

$dispatcher->listen(ConnectionEstablished::class, function (ConnectionEstablished $e) use (&$event) {
$event = $e;
});

/** @var \Illuminate\Database\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);
}
}