Skip to content

Commit

Permalink
Add aliasing to ConnectionManager.
Browse files Browse the repository at this point in the history
This will be useful in the testsuite for converting production
connections into the testing ones. This provides a useful feature of the
testsuite in 2.x.
  • Loading branch information
markstory committed Oct 20, 2013
1 parent 34f0c01 commit 147cad4
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 4 deletions.
60 changes: 58 additions & 2 deletions Cake/Database/ConnectionManager.php
Expand Up @@ -45,6 +45,13 @@ class ConnectionManager {
*/
protected static $_config = [];

/**
* A map of connection aliases.
*
* @var array
*/
protected static $_aliasMap = [];

/**
* The ConnectionRegistry used by the manager.
*
Expand All @@ -71,23 +78,72 @@ public static function config($key, $config = null) {
return static::_config($key, $config);
}

/**
* Set one or more connection aliases.
*
* Connection aliases allow you to rename active connections without overwriting
* the aliased connection. This is most useful in the testsuite for replacing
* connections with their test variant.
*
* Defined aliases will take precedence over normal connection names. For example,
* if you alias 'default' to 'test', fetching 'default' will always return the 'test'
* connection as long as the alias is defined.
*
* You can remove aliases with ConnectionManager::dropAlias().
*
* @param string|array $from The connection to rename. Can also be a map of multiple
* aliases to set.
* @param string $to The connection $from should return when loaded with get().
* @return void
*/
public static function alias($from, $to = null) {
if (is_array($from)) {
foreach ($from as $source => $dest) {
static::alias($source, $dest);
}
}
if (empty(static::$_config[$from])) {
throw new Error\MissingDatasourceConfigException(
__d('cake_dev', 'Cannot alias connection "%s" as it does not exist.', $from)
);
}
static::$_aliasMap[$to] = $from;
}

/**
* Drop an alias.
*
* Removes an alias from ConnectionManager. Fetching the aliased
* connection may fail if there is no other connection with that name.
*
* @param string $name The connection name to remove aliases for.
* @return void
*/
public static function dropAlias($name) {
unset(static::$_aliasMap[$name]);
}

/**
* Get a connection.
*
* If the connection has not been constructed an instance will be added
* to the registry.
* to the registry. This method will use any aliases that have been
* defined. If you want the original unaliased connections use getOriginal()
*
* @param string $name The connection name.
* @return Connection A connection object.
* @throws Cake\Error\MissingDatasourceConfigException When config data is missing.
*/
public static function get($name) {
if (empty(static::$_config[$name])) {
if (empty(static::$_config[$name]) && empty(static::$_aliasMap[$name])) {
throw new Error\MissingDatasourceConfigException(['name' => $name]);
}
if (empty(static::$_registry)) {
static::$_registry = new ConnectionRegistry();
}
if (isset(static::$_aliasMap[$name])) {
$name = static::$_aliasMap[$name];
}
if (isset(static::$_registry->{$name})) {
return static::$_registry->{$name};
}
Expand Down
31 changes: 29 additions & 2 deletions Cake/Test/TestCase/Database/ConnectionManagerTest.php
Expand Up @@ -33,6 +33,7 @@ public function tearDown() {
parent::tearDown();
Plugin::unload();
ConnectionManager::drop('test_variant');
ConnectionManager::dropAlias('other_name');
}

/**
Expand Down Expand Up @@ -156,8 +157,8 @@ public function testGetPluginDataSource() {
*/
public function testDrop() {
ConnectionManager::config('test_variant', [
'datasource' => 'Sqlite',
'database' => 'memory'
'className' => 'Sqlite',
'database' => ':memory:'
]);
$result = ConnectionManager::configured();
$this->assertContains('test_variant', $result);
Expand All @@ -169,4 +170,30 @@ public function testDrop() {
$this->assertFalse(ConnectionManager::drop('probably_does_not_exist'), 'Should return false on failure.');
}

/**
* Test aliasing connections.
*
* @return void
*/
public function testAlias() {
ConnectionManager::config('test_variant', [
'className' => 'Sqlite',
'database' => ':memory:'
]);
ConnectionManager::alias('test_variant', 'other_name');
$result = ConnectionManager::get('test_variant');
$this->assertSame($result, ConnectionManager::get('other_name'));
}

/**
* Test alias() raises an error when aliasing an undefined connection.
*
* @expectedException Cake\Error\MissingDatasourceConfigException
* @return void
*/
public function testAliasError() {
$this->assertNotContains('test_kaboom', ConnectionManager::configured());
ConnectionManager::alias('test_kaboom', 'other_name');
}

}

0 comments on commit 147cad4

Please sign in to comment.