PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Cake/Model/ConnectionManager.php

http://github.com/yandod/candycane
PHP | 270 lines | 128 code | 29 blank | 113 comment | 25 complexity | 1d4b043abe0242b3ebd4484433c8f193 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /**
  3. * Datasource connection manager
  4. *
  5. * Provides an interface for loading and enumerating connections defined in app/Config/database.php
  6. *
  7. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * For full copyright and license information, please see the LICENSE.txt
  12. * Redistributions of files must retain the above copyright notice.
  13. *
  14. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  15. * @link http://cakephp.org CakePHP(tm) Project
  16. * @package Cake.Model
  17. * @since CakePHP(tm) v 0.10.x.1402
  18. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  19. */
  20. App::uses('DataSource', 'Model/Datasource');
  21. /**
  22. * Manages loaded instances of DataSource objects
  23. *
  24. * Provides an interface for loading and enumerating connections defined in
  25. * app/Config/database.php
  26. *
  27. * @package Cake.Model
  28. */
  29. class ConnectionManager {
  30. /**
  31. * Holds a loaded instance of the Connections object
  32. *
  33. * @var DATABASE_CONFIG
  34. */
  35. public static $config = null;
  36. /**
  37. * Holds instances DataSource objects
  38. *
  39. * @var array
  40. */
  41. protected static $_dataSources = array();
  42. /**
  43. * Contains a list of all file and class names used in Connection settings
  44. *
  45. * @var array
  46. */
  47. protected static $_connectionsEnum = array();
  48. /**
  49. * Indicates if the init code for this class has already been executed
  50. *
  51. * @var bool
  52. */
  53. protected static $_init = false;
  54. /**
  55. * Loads connections configuration.
  56. *
  57. * @return void
  58. */
  59. protected static function _init() {
  60. include_once APP . 'Config' . DS . 'database.php';
  61. if (class_exists('DATABASE_CONFIG')) {
  62. static::$config = new DATABASE_CONFIG();
  63. }
  64. static::$_init = true;
  65. }
  66. /**
  67. * Gets a reference to a DataSource object
  68. *
  69. * @param string $name The name of the DataSource, as defined in app/Config/database.php
  70. * @return DataSource Instance
  71. * @throws MissingDatasourceException
  72. */
  73. public static function getDataSource($name) {
  74. if (empty(static::$_init)) {
  75. static::_init();
  76. }
  77. if (!empty(static::$_dataSources[$name])) {
  78. return static::$_dataSources[$name];
  79. }
  80. if (empty(static::$_connectionsEnum[$name])) {
  81. static::_getConnectionObject($name);
  82. }
  83. static::loadDataSource($name);
  84. $conn = static::$_connectionsEnum[$name];
  85. $class = $conn['classname'];
  86. if (strpos(App::location($class), 'Datasource') === false) {
  87. throw new MissingDatasourceException(array(
  88. 'class' => $class,
  89. 'plugin' => null,
  90. 'message' => 'Datasource is not found in Model/Datasource package.'
  91. ));
  92. }
  93. static::$_dataSources[$name] = new $class(static::$config->{$name});
  94. static::$_dataSources[$name]->configKeyName = $name;
  95. return static::$_dataSources[$name];
  96. }
  97. /**
  98. * Gets the list of available DataSource connections
  99. * This will only return the datasources instantiated by this manager
  100. * It differs from enumConnectionObjects, since the latter will return all configured connections
  101. *
  102. * @return array List of available connections
  103. */
  104. public static function sourceList() {
  105. if (empty(static::$_init)) {
  106. static::_init();
  107. }
  108. return array_keys(static::$_dataSources);
  109. }
  110. /**
  111. * Gets a DataSource name from an object reference.
  112. *
  113. * @param DataSource $source DataSource object
  114. * @return string|null Datasource name, or null if source is not present
  115. * in the ConnectionManager.
  116. */
  117. public static function getSourceName($source) {
  118. if (empty(static::$_init)) {
  119. static::_init();
  120. }
  121. foreach (static::$_dataSources as $name => $ds) {
  122. if ($ds === $source) {
  123. return $name;
  124. }
  125. }
  126. return null;
  127. }
  128. /**
  129. * Loads the DataSource class for the given connection name
  130. *
  131. * @param string|array $connName A string name of the connection, as defined in app/Config/database.php,
  132. * or an array containing the filename (without extension) and class name of the object,
  133. * to be found in app/Model/Datasource/ or lib/Cake/Model/Datasource/.
  134. * @return bool True on success, null on failure or false if the class is already loaded
  135. * @throws MissingDatasourceException
  136. */
  137. public static function loadDataSource($connName) {
  138. if (empty(static::$_init)) {
  139. static::_init();
  140. }
  141. if (is_array($connName)) {
  142. $conn = $connName;
  143. } else {
  144. $conn = static::$_connectionsEnum[$connName];
  145. }
  146. if (class_exists($conn['classname'], false)) {
  147. return false;
  148. }
  149. $plugin = $package = null;
  150. if (!empty($conn['plugin'])) {
  151. $plugin = $conn['plugin'] . '.';
  152. }
  153. if (!empty($conn['package'])) {
  154. $package = '/' . $conn['package'];
  155. }
  156. App::uses($conn['classname'], $plugin . 'Model/Datasource' . $package);
  157. if (!class_exists($conn['classname'])) {
  158. throw new MissingDatasourceException(array(
  159. 'class' => $conn['classname'],
  160. 'plugin' => substr($plugin, 0, -1)
  161. ));
  162. }
  163. return true;
  164. }
  165. /**
  166. * Returns a list of connections
  167. *
  168. * @return array An associative array of elements where the key is the connection name
  169. * (as defined in Connections), and the value is an array with keys 'filename' and 'classname'.
  170. */
  171. public static function enumConnectionObjects() {
  172. if (empty(static::$_init)) {
  173. static::_init();
  174. }
  175. return (array)static::$config;
  176. }
  177. /**
  178. * Dynamically creates a DataSource object at runtime, with the given name and settings
  179. *
  180. * @param string $name The DataSource name
  181. * @param array $config The DataSource configuration settings
  182. * @return DataSource|null A reference to the DataSource object, or null if creation failed
  183. */
  184. public static function create($name = '', $config = array()) {
  185. if (empty(static::$_init)) {
  186. static::_init();
  187. }
  188. if (empty($name) || empty($config) || array_key_exists($name, static::$_connectionsEnum)) {
  189. return null;
  190. }
  191. static::$config->{$name} = $config;
  192. static::$_connectionsEnum[$name] = static::_connectionData($config);
  193. $return = static::getDataSource($name);
  194. return $return;
  195. }
  196. /**
  197. * Removes a connection configuration at runtime given its name
  198. *
  199. * @param string $name the connection name as it was created
  200. * @return bool success if connection was removed, false if it does not exist
  201. */
  202. public static function drop($name) {
  203. if (empty(static::$_init)) {
  204. static::_init();
  205. }
  206. if (!isset(static::$config->{$name})) {
  207. return false;
  208. }
  209. unset(static::$_connectionsEnum[$name], static::$_dataSources[$name], static::$config->{$name});
  210. return true;
  211. }
  212. /**
  213. * Gets a list of class and file names associated with the user-defined DataSource connections
  214. *
  215. * @param string $name Connection name
  216. * @return void
  217. * @throws MissingDatasourceConfigException
  218. */
  219. protected static function _getConnectionObject($name) {
  220. if (!empty(static::$config->{$name})) {
  221. static::$_connectionsEnum[$name] = static::_connectionData(static::$config->{$name});
  222. } else {
  223. throw new MissingDatasourceConfigException(array('config' => $name));
  224. }
  225. }
  226. /**
  227. * Returns the file, class name, and parent for the given driver.
  228. *
  229. * @param array $config Array with connection configuration. Key 'datasource' is required
  230. * @return array An indexed array with: filename, classname, plugin and parent
  231. */
  232. protected static function _connectionData($config) {
  233. $package = $classname = $plugin = null;
  234. list($plugin, $classname) = pluginSplit($config['datasource']);
  235. if (strpos($classname, '/') !== false) {
  236. $package = dirname($classname);
  237. $classname = basename($classname);
  238. }
  239. return compact('package', 'classname', 'plugin');
  240. }
  241. }