pictcode / lib / Cake / Model / Datasource / DataSource.php @ 0b1b8047
履歴 | 表示 | アノテート | ダウンロード (10.239 KB)
1 |
<?php
|
---|---|
2 |
/**
|
3 |
* DataSource base class
|
4 |
*
|
5 |
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
6 |
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
7 |
*
|
8 |
* Licensed under The MIT License
|
9 |
* For full copyright and license information, please see the LICENSE.txt
|
10 |
* Redistributions of files must retain the above copyright notice.
|
11 |
*
|
12 |
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
13 |
* @link http://cakephp.org CakePHP(tm) Project
|
14 |
* @package Cake.Model.Datasource
|
15 |
* @since CakePHP(tm) v 0.10.5.1790
|
16 |
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
17 |
*/
|
18 |
|
19 |
/**
|
20 |
* DataSource base class
|
21 |
*
|
22 |
* DataSources are the link between models and the source of data that models represent.
|
23 |
*
|
24 |
* @link http://book.cakephp.org/2.0/en/models/datasources.html#basic-api-for-datasources
|
25 |
* @package Cake.Model.Datasource
|
26 |
*/
|
27 |
class DataSource extends Object { |
28 |
|
29 |
/**
|
30 |
* Are we connected to the DataSource?
|
31 |
*
|
32 |
* @var bool
|
33 |
*/
|
34 |
public $connected = false; |
35 |
|
36 |
/**
|
37 |
* The default configuration of a specific DataSource
|
38 |
*
|
39 |
* @var array
|
40 |
*/
|
41 |
protected $_baseConfig = array(); |
42 |
|
43 |
/**
|
44 |
* Holds references to descriptions loaded by the DataSource
|
45 |
*
|
46 |
* @var array
|
47 |
*/
|
48 |
protected $_descriptions = array(); |
49 |
|
50 |
/**
|
51 |
* Holds a list of sources (tables) contained in the DataSource
|
52 |
*
|
53 |
* @var array
|
54 |
*/
|
55 |
protected $_sources = null; |
56 |
|
57 |
/**
|
58 |
* The DataSource configuration
|
59 |
*
|
60 |
* @var array
|
61 |
*/
|
62 |
public $config = array(); |
63 |
|
64 |
/**
|
65 |
* Whether or not this DataSource is in the middle of a transaction
|
66 |
*
|
67 |
* @var bool
|
68 |
*/
|
69 |
protected $_transactionStarted = false; |
70 |
|
71 |
/**
|
72 |
* Whether or not source data like available tables and schema descriptions
|
73 |
* should be cached
|
74 |
*
|
75 |
* @var bool
|
76 |
*/
|
77 |
public $cacheSources = true; |
78 |
|
79 |
/**
|
80 |
* Constructor.
|
81 |
*
|
82 |
* @param array $config Array of configuration information for the datasource.
|
83 |
*/
|
84 |
public function __construct($config = array()) { |
85 |
parent::__construct();
|
86 |
$this->setConfig($config); |
87 |
} |
88 |
|
89 |
/**
|
90 |
* Caches/returns cached results for child instances
|
91 |
*
|
92 |
* @param mixed $data Unused in this class.
|
93 |
* @return array|null Array of sources available in this datasource.
|
94 |
*/
|
95 |
public function listSources($data = null) { |
96 |
if ($this->cacheSources === false) { |
97 |
return null; |
98 |
} |
99 |
|
100 |
if ($this->_sources !== null) { |
101 |
return $this->_sources; |
102 |
} |
103 |
|
104 |
$key = ConnectionManager::getSourceName($this) . '_' . $this->config['database'] . '_list'; |
105 |
$key = preg_replace('/[^A-Za-z0-9_\-.+]/', '_', $key); |
106 |
$sources = Cache::read($key, '_cake_model_'); |
107 |
|
108 |
if (empty($sources)) { |
109 |
$sources = $data; |
110 |
Cache::write($key, $data, '_cake_model_'); |
111 |
} |
112 |
|
113 |
return $this->_sources = $sources; |
114 |
} |
115 |
|
116 |
/**
|
117 |
* Returns a Model description (metadata) or null if none found.
|
118 |
*
|
119 |
* @param Model|string $model The model to describe.
|
120 |
* @return array|null Array of Metadata for the $model
|
121 |
*/
|
122 |
public function describe($model) { |
123 |
if ($this->cacheSources === false) { |
124 |
return null; |
125 |
} |
126 |
if (is_string($model)) { |
127 |
$table = $model; |
128 |
} else {
|
129 |
$table = $model->tablePrefix . $model->table; |
130 |
} |
131 |
|
132 |
if (isset($this->_descriptions[$table])) { |
133 |
return $this->_descriptions[$table]; |
134 |
} |
135 |
$cache = $this->_cacheDescription($table); |
136 |
|
137 |
if ($cache !== null) { |
138 |
$this->_descriptions[$table] =& $cache; |
139 |
return $cache; |
140 |
} |
141 |
return null; |
142 |
} |
143 |
|
144 |
/**
|
145 |
* Begin a transaction
|
146 |
*
|
147 |
* @return bool Returns true if a transaction is not in progress
|
148 |
*/
|
149 |
public function begin() { |
150 |
return !$this->_transactionStarted; |
151 |
} |
152 |
|
153 |
/**
|
154 |
* Commit a transaction
|
155 |
*
|
156 |
* @return bool Returns true if a transaction is in progress
|
157 |
*/
|
158 |
public function commit() { |
159 |
return $this->_transactionStarted; |
160 |
} |
161 |
|
162 |
/**
|
163 |
* Rollback a transaction
|
164 |
*
|
165 |
* @return bool Returns true if a transaction is in progress
|
166 |
*/
|
167 |
public function rollback() { |
168 |
return $this->_transactionStarted; |
169 |
} |
170 |
|
171 |
/**
|
172 |
* Converts column types to basic types
|
173 |
*
|
174 |
* @param string $real Real column type (i.e. "varchar(255)")
|
175 |
* @return string Abstract column type (i.e. "string")
|
176 |
*/
|
177 |
public function column($real) { |
178 |
return false; |
179 |
} |
180 |
|
181 |
/**
|
182 |
* Used to create new records. The "C" CRUD.
|
183 |
*
|
184 |
* To-be-overridden in subclasses.
|
185 |
*
|
186 |
* @param Model $Model The Model to be created.
|
187 |
* @param array $fields An Array of fields to be saved.
|
188 |
* @param array $values An Array of values to save.
|
189 |
* @return bool success
|
190 |
*/
|
191 |
public function create(Model $Model, $fields = null, $values = null) { |
192 |
return false; |
193 |
} |
194 |
|
195 |
/**
|
196 |
* Used to read records from the Datasource. The "R" in CRUD
|
197 |
*
|
198 |
* To-be-overridden in subclasses.
|
199 |
*
|
200 |
* @param Model $Model The model being read.
|
201 |
* @param array $queryData An array of query data used to find the data you want
|
202 |
* @param int $recursive Number of levels of association
|
203 |
* @return mixed
|
204 |
*/
|
205 |
public function read(Model $Model, $queryData = array(), $recursive = null) { |
206 |
return false; |
207 |
} |
208 |
|
209 |
/**
|
210 |
* Update a record(s) in the datasource.
|
211 |
*
|
212 |
* To-be-overridden in subclasses.
|
213 |
*
|
214 |
* @param Model $Model Instance of the model class being updated
|
215 |
* @param array $fields Array of fields to be updated
|
216 |
* @param array $values Array of values to be update $fields to.
|
217 |
* @param mixed $conditions The array of conditions to use.
|
218 |
* @return bool Success
|
219 |
*/
|
220 |
public function update(Model $Model, $fields = null, $values = null, $conditions = null) { |
221 |
return false; |
222 |
} |
223 |
|
224 |
/**
|
225 |
* Delete a record(s) in the datasource.
|
226 |
*
|
227 |
* To-be-overridden in subclasses.
|
228 |
*
|
229 |
* @param Model $Model The model class having record(s) deleted
|
230 |
* @param mixed $conditions The conditions to use for deleting.
|
231 |
* @return bool Success
|
232 |
*/
|
233 |
public function delete(Model $Model, $conditions = null) { |
234 |
return false; |
235 |
} |
236 |
|
237 |
/**
|
238 |
* Returns the ID generated from the previous INSERT operation.
|
239 |
*
|
240 |
* @param mixed $source The source name.
|
241 |
* @return mixed Last ID key generated in previous INSERT
|
242 |
*/
|
243 |
public function lastInsertId($source = null) { |
244 |
return false; |
245 |
} |
246 |
|
247 |
/**
|
248 |
* Returns the number of rows returned by last operation.
|
249 |
*
|
250 |
* @param mixed $source The source name.
|
251 |
* @return int Number of rows returned by last operation
|
252 |
*/
|
253 |
public function lastNumRows($source = null) { |
254 |
return false; |
255 |
} |
256 |
|
257 |
/**
|
258 |
* Returns the number of rows affected by last query.
|
259 |
*
|
260 |
* @param mixed $source The source name.
|
261 |
* @return int Number of rows affected by last query.
|
262 |
*/
|
263 |
public function lastAffected($source = null) { |
264 |
return false; |
265 |
} |
266 |
|
267 |
/**
|
268 |
* Check whether the conditions for the Datasource being available
|
269 |
* are satisfied. Often used from connect() to check for support
|
270 |
* before establishing a connection.
|
271 |
*
|
272 |
* @return bool Whether or not the Datasources conditions for use are met.
|
273 |
*/
|
274 |
public function enabled() { |
275 |
return true; |
276 |
} |
277 |
|
278 |
/**
|
279 |
* Sets the configuration for the DataSource.
|
280 |
* Merges the $config information with the _baseConfig and the existing $config property.
|
281 |
*
|
282 |
* @param array $config The configuration array
|
283 |
* @return void
|
284 |
*/
|
285 |
public function setConfig($config = array()) { |
286 |
$this->config = array_merge($this->_baseConfig, $this->config, $config); |
287 |
} |
288 |
|
289 |
/**
|
290 |
* Cache the DataSource description
|
291 |
*
|
292 |
* @param string $object The name of the object (model) to cache
|
293 |
* @param mixed $data The description of the model, usually a string or array
|
294 |
* @return mixed
|
295 |
*/
|
296 |
protected function _cacheDescription($object, $data = null) { |
297 |
if ($this->cacheSources === false) { |
298 |
return null; |
299 |
} |
300 |
|
301 |
if ($data !== null) { |
302 |
$this->_descriptions[$object] =& $data; |
303 |
} |
304 |
|
305 |
$key = ConnectionManager::getSourceName($this) . '_' . $object; |
306 |
$cache = Cache::read($key, '_cake_model_'); |
307 |
|
308 |
if (empty($cache)) { |
309 |
$cache = $data; |
310 |
Cache::write($key, $cache, '_cake_model_'); |
311 |
} |
312 |
|
313 |
return $cache; |
314 |
} |
315 |
|
316 |
/**
|
317 |
* Replaces `{$__cakeID__$}` and `{$__cakeForeignKey__$}` placeholders in query data.
|
318 |
*
|
319 |
* @param string $query Query string needing replacements done.
|
320 |
* @param array $data Array of data with values that will be inserted in placeholders.
|
321 |
* @param string $association Name of association model being replaced.
|
322 |
* @param Model $Model Model instance.
|
323 |
* @param array $stack The context stack.
|
324 |
* @return mixed String of query data with placeholders replaced, or false on failure.
|
325 |
*/
|
326 |
public function insertQueryData($query, $data, $association, Model $Model, $stack) { |
327 |
$keys = array('{$__cakeID__$}', '{$__cakeForeignKey__$}'); |
328 |
|
329 |
$modelAlias = $Model->alias; |
330 |
|
331 |
foreach ($keys as $key) { |
332 |
if (strpos($query, $key) === false) { |
333 |
continue;
|
334 |
} |
335 |
|
336 |
$insertKey = $InsertModel = null; |
337 |
switch ($key) { |
338 |
case '{$__cakeID__$}': |
339 |
$InsertModel = $Model; |
340 |
$insertKey = $Model->primaryKey; |
341 |
|
342 |
break;
|
343 |
case '{$__cakeForeignKey__$}': |
344 |
foreach ($Model->associations() as $type) { |
345 |
foreach ($Model->{$type} as $assoc => $assocData) { |
346 |
if ($assoc !== $association) { |
347 |
continue;
|
348 |
} |
349 |
|
350 |
if (isset($assocData['foreignKey'])) { |
351 |
$InsertModel = $Model->{$assoc}; |
352 |
$insertKey = $assocData['foreignKey']; |
353 |
} |
354 |
|
355 |
break 3; |
356 |
} |
357 |
} |
358 |
|
359 |
break;
|
360 |
} |
361 |
|
362 |
$val = $dataType = null; |
363 |
if (!empty($insertKey) && !empty($InsertModel)) { |
364 |
if (isset($data[$modelAlias][$insertKey])) { |
365 |
$val = $data[$modelAlias][$insertKey]; |
366 |
} elseif (isset($data[$association][$insertKey])) { |
367 |
$val = $data[$association][$insertKey]; |
368 |
} else {
|
369 |
$found = false; |
370 |
foreach (array_reverse($stack) as $assocData) { |
371 |
if (isset($data[$assocData]) && isset($data[$assocData][$insertKey])) { |
372 |
$val = $data[$assocData][$insertKey]; |
373 |
$found = true; |
374 |
break;
|
375 |
} |
376 |
} |
377 |
|
378 |
if (!$found) { |
379 |
$val = ''; |
380 |
} |
381 |
} |
382 |
|
383 |
$dataType = $InsertModel->getColumnType($InsertModel->primaryKey); |
384 |
} |
385 |
|
386 |
if (empty($val) && $val !== '0') { |
387 |
return false; |
388 |
} |
389 |
|
390 |
$query = str_replace($key, $this->value($val, $dataType), $query); |
391 |
} |
392 |
|
393 |
return $query; |
394 |
} |
395 |
|
396 |
/**
|
397 |
* To-be-overridden in subclasses.
|
398 |
*
|
399 |
* @param Model $Model Model instance
|
400 |
* @param string $key Key name to make
|
401 |
* @return string Key name for model.
|
402 |
*/
|
403 |
public function resolveKey(Model $Model, $key) { |
404 |
return $Model->alias . $key; |
405 |
} |
406 |
|
407 |
/**
|
408 |
* Returns the schema name. Override this in subclasses.
|
409 |
*
|
410 |
* @return string|null The schema name
|
411 |
*/
|
412 |
public function getSchemaName() { |
413 |
return null; |
414 |
} |
415 |
|
416 |
/**
|
417 |
* Closes a connection. Override in subclasses.
|
418 |
*
|
419 |
* @return bool
|
420 |
*/
|
421 |
public function close() { |
422 |
return $this->connected = false; |
423 |
} |
424 |
|
425 |
/**
|
426 |
* Closes the current datasource.
|
427 |
*/
|
428 |
public function __destruct() { |
429 |
if ($this->_transactionStarted) { |
430 |
$this->rollback();
|
431 |
} |
432 |
if ($this->connected) { |
433 |
$this->close();
|
434 |
} |
435 |
} |
436 |
|
437 |
} |