pictcode / lib / Cake / Model / ConnectionManager.php @ 635eef61
履歴 | 表示 | アノテート | ダウンロード (7.376 KB)
1 | 635eef61 | spyder1211 | <?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 | |||
21 | App::uses('DataSource', 'Model/Datasource'); |
||
22 | |||
23 | /**
|
||
24 | * Manages loaded instances of DataSource objects
|
||
25 | *
|
||
26 | * Provides an interface for loading and enumerating connections defined in
|
||
27 | * app/Config/database.php
|
||
28 | *
|
||
29 | * @package Cake.Model
|
||
30 | */
|
||
31 | class ConnectionManager { |
||
32 | |||
33 | /**
|
||
34 | * Holds a loaded instance of the Connections object
|
||
35 | *
|
||
36 | * @var DATABASE_CONFIG
|
||
37 | */
|
||
38 | public static $config = null; |
||
39 | |||
40 | /**
|
||
41 | * Holds instances DataSource objects
|
||
42 | *
|
||
43 | * @var array
|
||
44 | */
|
||
45 | protected static $_dataSources = array(); |
||
46 | |||
47 | /**
|
||
48 | * Contains a list of all file and class names used in Connection settings
|
||
49 | *
|
||
50 | * @var array
|
||
51 | */
|
||
52 | protected static $_connectionsEnum = array(); |
||
53 | |||
54 | /**
|
||
55 | * Indicates if the init code for this class has already been executed
|
||
56 | *
|
||
57 | * @var bool
|
||
58 | */
|
||
59 | protected static $_init = false; |
||
60 | |||
61 | /**
|
||
62 | * Loads connections configuration.
|
||
63 | *
|
||
64 | * @return void
|
||
65 | */
|
||
66 | protected static function _init() { |
||
67 | include_once APP . 'Config' . DS . 'database.php'; |
||
68 | if (class_exists('DATABASE_CONFIG')) { |
||
69 | static::$config = new DATABASE_CONFIG(); |
||
70 | } |
||
71 | static::$_init = true; |
||
72 | } |
||
73 | |||
74 | /**
|
||
75 | * Gets a reference to a DataSource object
|
||
76 | *
|
||
77 | * @param string $name The name of the DataSource, as defined in app/Config/database.php
|
||
78 | * @return DataSource Instance
|
||
79 | * @throws MissingDatasourceException
|
||
80 | */
|
||
81 | public static function getDataSource($name) { |
||
82 | if (empty(static::$_init)) { |
||
83 | static::_init();
|
||
84 | } |
||
85 | |||
86 | if (!empty(static::$_dataSources[$name])) { |
||
87 | return static::$_dataSources[$name]; |
||
88 | } |
||
89 | |||
90 | if (empty(static::$_connectionsEnum[$name])) { |
||
91 | static::_getConnectionObject($name); |
||
92 | } |
||
93 | |||
94 | static::loadDataSource($name); |
||
95 | $conn = static::$_connectionsEnum[$name]; |
||
96 | $class = $conn['classname']; |
||
97 | |||
98 | if (strpos(App::location($class), 'Datasource') === false) { |
||
99 | throw new MissingDatasourceException(array( |
||
100 | 'class' => $class, |
||
101 | 'plugin' => null, |
||
102 | 'message' => 'Datasource is not found in Model/Datasource package.' |
||
103 | )); |
||
104 | } |
||
105 | static::$_dataSources[$name] = new $class(static::$config->{$name}); |
||
106 | static::$_dataSources[$name]->configKeyName = $name; |
||
107 | |||
108 | return static::$_dataSources[$name]; |
||
109 | } |
||
110 | |||
111 | /**
|
||
112 | * Gets the list of available DataSource connections
|
||
113 | * This will only return the datasources instantiated by this manager
|
||
114 | * It differs from enumConnectionObjects, since the latter will return all configured connections
|
||
115 | *
|
||
116 | * @return array List of available connections
|
||
117 | */
|
||
118 | public static function sourceList() { |
||
119 | if (empty(static::$_init)) { |
||
120 | static::_init();
|
||
121 | } |
||
122 | return array_keys(static::$_dataSources); |
||
123 | } |
||
124 | |||
125 | /**
|
||
126 | * Gets a DataSource name from an object reference.
|
||
127 | *
|
||
128 | * @param DataSource $source DataSource object
|
||
129 | * @return string|null Datasource name, or null if source is not present
|
||
130 | * in the ConnectionManager.
|
||
131 | */
|
||
132 | public static function getSourceName($source) { |
||
133 | if (empty(static::$_init)) { |
||
134 | static::_init();
|
||
135 | } |
||
136 | foreach (static::$_dataSources as $name => $ds) { |
||
137 | if ($ds === $source) { |
||
138 | return $name; |
||
139 | } |
||
140 | } |
||
141 | return null; |
||
142 | } |
||
143 | |||
144 | /**
|
||
145 | * Loads the DataSource class for the given connection name
|
||
146 | *
|
||
147 | * @param string|array $connName A string name of the connection, as defined in app/Config/database.php,
|
||
148 | * or an array containing the filename (without extension) and class name of the object,
|
||
149 | * to be found in app/Model/Datasource/ or lib/Cake/Model/Datasource/.
|
||
150 | * @return bool True on success, null on failure or false if the class is already loaded
|
||
151 | * @throws MissingDatasourceException
|
||
152 | */
|
||
153 | public static function loadDataSource($connName) { |
||
154 | if (empty(static::$_init)) { |
||
155 | static::_init();
|
||
156 | } |
||
157 | |||
158 | if (is_array($connName)) { |
||
159 | $conn = $connName; |
||
160 | } else {
|
||
161 | $conn = static::$_connectionsEnum[$connName]; |
||
162 | } |
||
163 | |||
164 | if (class_exists($conn['classname'], false)) { |
||
165 | return false; |
||
166 | } |
||
167 | |||
168 | $plugin = $package = null; |
||
169 | if (!empty($conn['plugin'])) { |
||
170 | $plugin = $conn['plugin'] . '.'; |
||
171 | } |
||
172 | if (!empty($conn['package'])) { |
||
173 | $package = '/' . $conn['package']; |
||
174 | } |
||
175 | |||
176 | App::uses($conn['classname'], $plugin . 'Model/Datasource' . $package); |
||
177 | if (!class_exists($conn['classname'])) { |
||
178 | throw new MissingDatasourceException(array( |
||
179 | 'class' => $conn['classname'], |
||
180 | 'plugin' => substr($plugin, 0, -1) |
||
181 | )); |
||
182 | } |
||
183 | return true; |
||
184 | } |
||
185 | |||
186 | /**
|
||
187 | * Returns a list of connections
|
||
188 | *
|
||
189 | * @return array An associative array of elements where the key is the connection name
|
||
190 | * (as defined in Connections), and the value is an array with keys 'filename' and 'classname'.
|
||
191 | */
|
||
192 | public static function enumConnectionObjects() { |
||
193 | if (empty(static::$_init)) { |
||
194 | static::_init();
|
||
195 | } |
||
196 | return (array)static::$config; |
||
197 | } |
||
198 | |||
199 | /**
|
||
200 | * Dynamically creates a DataSource object at runtime, with the given name and settings
|
||
201 | *
|
||
202 | * @param string $name The DataSource name
|
||
203 | * @param array $config The DataSource configuration settings
|
||
204 | * @return DataSource|null A reference to the DataSource object, or null if creation failed
|
||
205 | */
|
||
206 | public static function create($name = '', $config = array()) { |
||
207 | if (empty(static::$_init)) { |
||
208 | static::_init();
|
||
209 | } |
||
210 | |||
211 | if (empty($name) || empty($config) || array_key_exists($name, static::$_connectionsEnum)) { |
||
212 | return null; |
||
213 | } |
||
214 | static::$config->{$name} = $config; |
||
215 | static::$_connectionsEnum[$name] = static::_connectionData($config); |
||
216 | $return = static::getDataSource($name); |
||
217 | return $return; |
||
218 | } |
||
219 | |||
220 | /**
|
||
221 | * Removes a connection configuration at runtime given its name
|
||
222 | *
|
||
223 | * @param string $name the connection name as it was created
|
||
224 | * @return bool success if connection was removed, false if it does not exist
|
||
225 | */
|
||
226 | public static function drop($name) { |
||
227 | if (empty(static::$_init)) { |
||
228 | static::_init();
|
||
229 | } |
||
230 | |||
231 | if (!isset(static::$config->{$name})) { |
||
232 | return false; |
||
233 | } |
||
234 | unset(static::$_connectionsEnum[$name], static::$_dataSources[$name], static::$config->{$name}); |
||
235 | return true; |
||
236 | } |
||
237 | |||
238 | /**
|
||
239 | * Gets a list of class and file names associated with the user-defined DataSource connections
|
||
240 | *
|
||
241 | * @param string $name Connection name
|
||
242 | * @return void
|
||
243 | * @throws MissingDatasourceConfigException
|
||
244 | */
|
||
245 | protected static function _getConnectionObject($name) { |
||
246 | if (!empty(static::$config->{$name})) { |
||
247 | static::$_connectionsEnum[$name] = static::_connectionData(static::$config->{$name}); |
||
248 | } else {
|
||
249 | throw new MissingDatasourceConfigException(array('config' => $name)); |
||
250 | } |
||
251 | } |
||
252 | |||
253 | /**
|
||
254 | * Returns the file, class name, and parent for the given driver.
|
||
255 | *
|
||
256 | * @param array $config Array with connection configuration. Key 'datasource' is required
|
||
257 | * @return array An indexed array with: filename, classname, plugin and parent
|
||
258 | */
|
||
259 | protected static function _connectionData($config) { |
||
260 | $package = $classname = $plugin = null; |
||
261 | |||
262 | list($plugin, $classname) = pluginSplit($config['datasource']); |
||
263 | if (strpos($classname, '/') !== false) { |
||
264 | $package = dirname($classname); |
||
265 | $classname = basename($classname); |
||
266 | } |
||
267 | return compact('package', 'classname', 'plugin'); |
||
268 | } |
||
269 | |||
270 | } |