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 2 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
59 changes: 54 additions & 5 deletions src/Illuminate/Database/DatabaseManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,50 @@ 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 .
deleugpn marked this conversation as resolved.
Show resolved Hide resolved
*
* @param string $name
* @param array $config
* @return ConnectionInterface
deleugpn marked this conversation as resolved.
Show resolved Hide resolved
*/
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.
*
Expand Down Expand Up @@ -209,6 +243,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.
*
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 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 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);
}
}