connection_manager.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: connection__manager_8php-source.html 675 2008-12-26 00:27:14Z gwoo $ */
00003 
00004 /**
00005  * Short description for file.
00006  *
00007  * Long description for file
00008  *
00009  * PHP versions 4 and 5
00010  *
00011  * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
00012  * Copyright 2005-2008, Cake Software Foundation, Inc.
00013  *                              1785 E. Sahara Avenue, Suite 490-204
00014  *                              Las Vegas, Nevada 89104
00015  *
00016  * Licensed under The MIT License
00017  * Redistributions of files must retain the above copyright notice.
00018  *
00019  * @filesource
00020  * @copyright       Copyright 2005-2008, Cake Software Foundation, Inc.
00021  * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00022  * @package         cake
00023  * @subpackage      cake.cake.libs.model
00024  * @since           CakePHP(tm) v 0.10.x.1402
00025  * @version         $Revision: 675 $
00026  * @modifiedby      $LastChangedBy: gwoo $
00027  * @lastmodified    $Date: 2008-12-25 18:27:14 -0600 (Thu, 25 Dec 2008) $
00028  * @license         http://www.opensource.org/licenses/mit-license.php The MIT License
00029  */
00030 
00031 /**
00032  * Manages loaded instances of DataSource objects
00033  *
00034  * Long description for file
00035  *
00036  * @package     cake
00037  * @subpackage  cake.cake.libs.model
00038  */
00039 
00040 uses ('model' . DS . 'datasources' . DS . 'datasource');
00041 config('database');
00042 
00043 class ConnectionManager extends Object {
00044 
00045 /**
00046  * Holds a loaded instance of the Connections object
00047  *
00048  * @var class:Connections
00049  * @access public
00050  */
00051     var $config = null;
00052 /**
00053  * Holds instances DataSource objects
00054  *
00055  * @var array
00056  * @access private
00057  */
00058     var $_dataSources = array();
00059 /**
00060  * Contains a list of all file and class names used in Connection settings
00061  *
00062  * @var array
00063  * @access private
00064  */
00065     var $_connectionsEnum = array();
00066 /**
00067  * Constructor.
00068  *
00069  */
00070     function __construct() {
00071         if (class_exists('DATABASE_CONFIG')) {
00072             $this->config = new DATABASE_CONFIG();
00073         }
00074     }
00075 /**
00076  * Gets a reference to the ConnectionManger object instance
00077  *
00078  * @return object
00079  */
00080     function &getInstance() {
00081         static $instance = array();
00082 
00083         if (!isset($instance[0]) || !$instance[0]) {
00084             $instance[0] = &new ConnectionManager();
00085         }
00086 
00087         return $instance[0];
00088     }
00089 /**
00090  * Gets a reference to a DataSource object
00091  *
00092  * @param string $name The name of the DataSource, as defined in app/config/connections
00093  * @return object
00094  */
00095     function &getDataSource($name) {
00096         $_this =& ConnectionManager::getInstance();
00097 
00098         if (in_array($name, array_keys($_this->_dataSources))) {
00099             return $_this->_dataSources[$name];
00100         }
00101 
00102         $connections = $_this->enumConnectionObjects();
00103         if (in_array($name, array_keys($connections))) {
00104             $conn = $connections[$name];
00105             $class = $conn['classname'];
00106             $_this->loadDataSource($name);
00107             $_this->_dataSources[$name] =& new $class($_this->config->{$name});
00108             $_this->_dataSources[$name]->configKeyName = $name;
00109         } else {
00110             trigger_error(sprintf(__("ConnectionManager::getDataSource - Non-existent data source %s", true), $name), E_USER_ERROR);
00111             return null;
00112         }
00113 
00114         return $_this->_dataSources[$name];
00115     }
00116 /**
00117  * Gets a DataSource name from an object reference
00118  *
00119  * @param object $source
00120  * @return string
00121  */
00122     function getSourceName(&$source) {
00123         $_this =& ConnectionManager::getInstance();
00124 
00125         $names = array_keys($_this->_dataSources);
00126         for ($i = 0; $i < count($names); $i++) {
00127             if ($_this->_dataSources[$names[$i]] === $source) {
00128                 return $names[$i];
00129             }
00130         }
00131         return null;
00132     }
00133 /**
00134  * Loads the DataSource class for the given connection name
00135  *
00136  * @param mixed $connName A string name of the connection, as defined in Connections config,
00137  *                        or an array containing the file and class name of the object.
00138  * @return boolean True on success, null on failure or false if the class is already loaded
00139  */
00140     function loadDataSource($connName) {
00141         $_this =& ConnectionManager::getInstance();
00142 
00143         if (is_array($connName)) {
00144             $conn = $connName;
00145         } else {
00146             $connections = $_this->enumConnectionObjects();
00147             $conn = $connections[$connName];
00148         }
00149 
00150         if (isset($conn['parent']) && !empty($conn['parent'])) {
00151             $_this->loadDataSource($conn['parent']);
00152         }
00153 
00154         if (class_exists($conn['classname'])) {
00155             return false;
00156         }
00157 
00158         if (file_exists(MODELS . DS . $conn['filename'] . '.php')) {
00159             require (MODELS . DS . $conn['filename'] . '.php');
00160         } elseif (fileExistsInPath(LIBS . 'model' . DS . $conn['filename'] . '.php')) {
00161             require (LIBS . 'model' . DS . $conn['filename'] . '.php');
00162         } else {
00163             trigger_error(sprintf(__('Unable to load DataSource file %s.php', true), $conn['filename']), E_USER_ERROR);
00164             return null;
00165         }
00166     }
00167 /**
00168  * Gets a list of class and file names associated with the user-defined DataSource connections
00169  *
00170  * @return array An associative array of elements where the key is the connection name
00171  *               (as defined in Connections), and the value is an array with keys 'filename' and 'classname'.
00172  */
00173     function enumConnectionObjects() {
00174         $_this =& ConnectionManager::getInstance();
00175 
00176         if (!empty($_this->_connectionsEnum)) {
00177             return $_this->_connectionsEnum;
00178         }
00179         $connections = get_object_vars($_this->config);
00180 
00181         if ($connections != null) {
00182             foreach ($connections as $name => $config) {
00183                 $_this->_connectionsEnum[$name] = $_this->__getDriver($config);
00184             }
00185             return $_this->_connectionsEnum;
00186         } else {
00187             $_this->cakeError('missingConnection', array(array('className' => 'ConnectionManager')));
00188         }
00189     }
00190 /**
00191  * Dynamically creates a DataSource object at runtime, with the given name and settings
00192  *
00193  * @param string $name The DataSource name
00194  * @param array $config The DataSource configuration settings
00195  * @return object A reference to the DataSource object, or null if creation failed
00196  */
00197     function &create($name = '', $config = array()) {
00198         $_this =& ConnectionManager::getInstance();
00199 
00200         if (empty($name) || empty($config) || array_key_exists($name, $_this->_connectionsEnum)) {
00201             $null = null;
00202             return $null;
00203         }
00204 
00205         $_this->config->{$name} = $config;
00206         $_this->_connectionsEnum[$name] = $_this->__getDriver($config);
00207         return $_this->getDataSource($name);
00208     }
00209 /**
00210  * Private method
00211  *
00212  * Returns the file and class name for the given driver
00213  */
00214     function __getDriver($config) {
00215         $_this =& ConnectionManager::getInstance();
00216 
00217         if (!isset($config['datasource'])) {
00218             $config['datasource'] = 'dbo';
00219         }
00220 
00221         if (isset($config['driver']) && $config['driver'] != null && !empty($config['driver'])) {
00222             $filename = $config['datasource'] . DS . $config['datasource'] . '_' . $config['driver'];
00223             $classname = Inflector::camelize(strtolower($config['datasource'] . '_' . $config['driver']));
00224             $parent = $_this->__getDriver(array('datasource' => $config['datasource']));
00225         } else {
00226             $filename = 'datasources'  . DS .  $config['datasource'] . '_source';
00227             $classname = Inflector::camelize(strtolower($config['datasource'] . '_source'));
00228             $parent = null;
00229         }
00230         return array('filename'  => $filename, 'classname' => $classname, 'parent' => $parent);
00231     }
00232 /**
00233  * Destructor.
00234  *
00235  */
00236     function __destruct() {
00237         if (CAKE_SESSION_SAVE == 'database' && function_exists('session_write_close')) {
00238             session_write_close();
00239         }
00240     }
00241 }
00242 
00243 ?>