浏览代码

Add aliasing to ConnectionManager.

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.
mark_story 12 年之前
父节点
当前提交
147cad4014
共有 2 个文件被更改,包括 87 次插入4 次删除
  1. 58 2
      Cake/Database/ConnectionManager.php
  2. 29 2
      Cake/Test/TestCase/Database/ConnectionManagerTest.php

+ 58 - 2
Cake/Database/ConnectionManager.php

@@ -46,6 +46,13 @@ class ConnectionManager {
 	protected static $_config = [];
 
 /**
+ * A map of connection aliases.
+ *
+ * @var array
+ */
+	protected static $_aliasMap = [];
+
+/**
  * The ConnectionRegistry used by the manager.
  *
  * @var Cake\Database\ConnectionRegistry
@@ -72,22 +79,71 @@ class ConnectionManager {
 	}
 
 /**
+ * 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};
 		}

+ 29 - 2
Cake/Test/TestCase/Database/ConnectionManagerTest.php

@@ -33,6 +33,7 @@ class ConnectionManagerTest extends TestCase {
 		parent::tearDown();
 		Plugin::unload();
 		ConnectionManager::drop('test_variant');
+		ConnectionManager::dropAlias('other_name');
 	}
 
 /**
@@ -156,8 +157,8 @@ class ConnectionManagerTest extends TestCase {
  */
 	public function testDrop() {
 		ConnectionManager::config('test_variant', [
-			'datasource' => 'Sqlite',
-			'database' => 'memory'
+			'className' => 'Sqlite',
+			'database' => ':memory:'
 		]);
 		$result = ConnectionManager::configured();
 		$this->assertContains('test_variant', $result);
@@ -169,4 +170,30 @@ class ConnectionManagerTest extends TestCase {
 		$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');
+	}
+
 }