ConnectionManager.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 0.10.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Datasource;
  16. use Cake\Core\StaticConfigTrait;
  17. use Cake\Datasource\Exception\MissingDatasourceConfigException;
  18. /**
  19. * Manages and loads instances of Connection
  20. *
  21. * Provides an interface to loading and creating connection objects. Acts as
  22. * a registry for the connections defined in an application.
  23. *
  24. * Provides an interface for loading and enumerating connections defined in
  25. * config/app.php
  26. */
  27. class ConnectionManager
  28. {
  29. use StaticConfigTrait {
  30. setConfig as protected _setConfig;
  31. parseDsn as protected _parseDsn;
  32. }
  33. /**
  34. * A map of connection aliases.
  35. *
  36. * @var array
  37. */
  38. protected static $_aliasMap = [];
  39. /**
  40. * An array mapping url schemes to fully qualified driver class names
  41. *
  42. * @return array
  43. */
  44. protected static $_dsnClassMap = [
  45. 'mysql' => 'Cake\Database\Driver\Mysql',
  46. 'postgres' => 'Cake\Database\Driver\Postgres',
  47. 'sqlite' => 'Cake\Database\Driver\Sqlite',
  48. 'sqlserver' => 'Cake\Database\Driver\Sqlserver',
  49. ];
  50. /**
  51. * The ConnectionRegistry used by the manager.
  52. *
  53. * @var \Cake\Datasource\ConnectionRegistry
  54. */
  55. protected static $_registry;
  56. /**
  57. * Configure a new connection object.
  58. *
  59. * The connection will not be constructed until it is first used.
  60. *
  61. * @param string|array $key The name of the connection config, or an array of multiple configs.
  62. * @param array|null $config An array of name => config data for adapter.
  63. * @return void
  64. * @throws \Cake\Core\Exception\Exception When trying to modify an existing config.
  65. * @see \Cake\Core\StaticConfigTrait::config()
  66. */
  67. public static function setConfig($key, $config = null)
  68. {
  69. if (is_array($config)) {
  70. $config['name'] = $key;
  71. }
  72. static::_setConfig($key, $config);
  73. }
  74. /**
  75. * Parses a DSN into a valid connection configuration
  76. *
  77. * This method allows setting a DSN using formatting similar to that used by PEAR::DB.
  78. * The following is an example of its usage:
  79. *
  80. * ```
  81. * $dsn = 'mysql://user:pass@localhost/database';
  82. * $config = ConnectionManager::parseDsn($dsn);
  83. *
  84. * $dsn = 'Cake\Database\Driver\Mysql://localhost:3306/database?className=Cake\Database\Connection';
  85. * $config = ConnectionManager::parseDsn($dsn);
  86. *
  87. * $dsn = 'Cake\Database\Connection://localhost:3306/database?driver=Cake\Database\Driver\Mysql';
  88. * $config = ConnectionManager::parseDsn($dsn);
  89. * ```
  90. *
  91. * For all classes, the value of `scheme` is set as the value of both the `className` and `driver`
  92. * unless they have been otherwise specified.
  93. *
  94. * Note that query-string arguments are also parsed and set as values in the returned configuration.
  95. *
  96. * @param string|null $config The DSN string to convert to a configuration array
  97. * @return array The configuration array to be stored after parsing the DSN
  98. */
  99. public static function parseDsn($config = null)
  100. {
  101. $config = static::_parseDsn($config);
  102. if (isset($config['path']) && empty($config['database'])) {
  103. $config['database'] = substr($config['path'], 1);
  104. }
  105. if (empty($config['driver'])) {
  106. $config['driver'] = $config['className'];
  107. $config['className'] = 'Cake\Database\Connection';
  108. }
  109. unset($config['path']);
  110. return $config;
  111. }
  112. /**
  113. * Set one or more connection aliases.
  114. *
  115. * Connection aliases allow you to rename active connections without overwriting
  116. * the aliased connection. This is most useful in the test-suite for replacing
  117. * connections with their test variant.
  118. *
  119. * Defined aliases will take precedence over normal connection names. For example,
  120. * if you alias 'default' to 'test', fetching 'default' will always return the 'test'
  121. * connection as long as the alias is defined.
  122. *
  123. * You can remove aliases with ConnectionManager::dropAlias().
  124. *
  125. * ### Usage
  126. *
  127. * ```
  128. * // Make 'things' resolve to 'test_things' connection
  129. * ConnectionManager::alias('test_things', 'things');
  130. * ```
  131. *
  132. * @param string $alias The alias to add. Fetching $source will return $alias when loaded with get.
  133. * @param string $source The connection to add an alias to.
  134. * @return void
  135. * @throws \Cake\Datasource\Exception\MissingDatasourceConfigException When aliasing a
  136. * connection that does not exist.
  137. */
  138. public static function alias($alias, $source)
  139. {
  140. if (empty(static::$_config[$source]) && empty(static::$_config[$alias])) {
  141. throw new MissingDatasourceConfigException(
  142. sprintf('Cannot create alias of "%s" as it does not exist.', $alias)
  143. );
  144. }
  145. static::$_aliasMap[$source] = $alias;
  146. }
  147. /**
  148. * Drop an alias.
  149. *
  150. * Removes an alias from ConnectionManager. Fetching the aliased
  151. * connection may fail if there is no other connection with that name.
  152. *
  153. * @param string $name The connection name to remove aliases for.
  154. * @return void
  155. */
  156. public static function dropAlias($name)
  157. {
  158. unset(static::$_aliasMap[$name]);
  159. }
  160. /**
  161. * Get a connection.
  162. *
  163. * If the connection has not been constructed an instance will be added
  164. * to the registry. This method will use any aliases that have been
  165. * defined. If you want the original unaliased connections pass `false`
  166. * as second parameter.
  167. *
  168. * @param string $name The connection name.
  169. * @param bool $useAliases Set to false to not use aliased connections.
  170. * @return \Cake\Datasource\ConnectionInterface A connection object.
  171. * @throws \Cake\Datasource\Exception\MissingDatasourceConfigException When config
  172. * data is missing.
  173. */
  174. public static function get($name, $useAliases = true)
  175. {
  176. if ($useAliases && isset(static::$_aliasMap[$name])) {
  177. $name = static::$_aliasMap[$name];
  178. }
  179. if (empty(static::$_config[$name])) {
  180. throw new MissingDatasourceConfigException(['name' => $name]);
  181. }
  182. if (empty(static::$_registry)) {
  183. static::$_registry = new ConnectionRegistry();
  184. }
  185. if (isset(static::$_registry->{$name})) {
  186. return static::$_registry->{$name};
  187. }
  188. return static::$_registry->load($name, static::$_config[$name]);
  189. }
  190. }