Subversion-Projekte lars-tiefland.cakephp

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/* SVN FILE: $Id: datasource.php 7945 2008-12-19 02:16:01Z gwoo $ */
3
/**
4
 * DataSource base class
5
 *
6
 * Long description for file
7
 *
8
 * PHP versions 4 and 5
9
 *
10
 * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
11
 * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
12
 *
13
 * Licensed under The MIT License
14
 * Redistributions of files must retain the above copyright notice.
15
 *
16
 * @filesource
17
 * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
18
 * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
19
 * @package       cake
20
 * @subpackage    cake.cake.libs.model.datasources
21
 * @since         CakePHP(tm) v 0.10.5.1790
22
 * @version       $Revision: 7945 $
23
 * @modifiedby    $LastChangedBy: gwoo $
24
 * @lastmodified  $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
25
 * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
26
 */
27
/**
28
 * DataSource base class
29
 *
30
 * Long description for file
31
 *
32
 * @package       cake
33
 * @subpackage    cake.cake.libs.model.datasources
34
 */
35
class DataSource extends Object {
36
/**
37
 * Are we connected to the DataSource?
38
 *
39
 * @var boolean
40
 * @access public
41
 */
42
	var $connected = false;
43
/**
44
 * Print full query debug info?
45
 *
46
 * @var boolean
47
 * @access public
48
 */
49
	var $fullDebug = false;
50
/**
51
 * Error description of last query
52
 *
53
 * @var unknown_type
54
 * @access public
55
 */
56
	var $error = null;
57
/**
58
 * String to hold how many rows were affected by the last SQL operation.
59
 *
60
 * @var string
61
 * @access public
62
 */
63
	var $affected = null;
64
/**
65
 * Number of rows in current resultset
66
 *
67
 * @var int
68
 * @access public
69
 */
70
	var $numRows = null;
71
/**
72
 * Time the last query took
73
 *
74
 * @var int
75
 * @access public
76
 */
77
	var $took = null;
78
/**
79
 * The starting character that this DataSource uses for quoted identifiers.
80
 *
81
 * @var string
82
 */
83
	var $startQuote = null;
84
/**
85
 * The ending character that this DataSource uses for quoted identifiers.
86
 *
87
 * @var string
88
 */
89
	var $endQuote = null;
90
/**
91
 * Enter description here...
92
 *
93
 * @var array
94
 * @access private
95
 */
96
	var $_result = null;
97
/**
98
 * Queries count.
99
 *
100
 * @var int
101
 * @access private
102
 */
103
	var $_queriesCnt = 0;
104
/**
105
 * Total duration of all queries.
106
 *
107
 * @var unknown_type
108
 * @access private
109
 */
110
	var $_queriesTime = null;
111
/**
112
 * Log of queries executed by this DataSource
113
 *
114
 * @var unknown_type
115
 * @access private
116
 */
117
	var $_queriesLog = array();
118
/**
119
 * Maximum number of items in query log, to prevent query log taking over
120
 * too much memory on large amounts of queries -- I we've had problems at
121
 * >6000 queries on one system.
122
 *
123
 * @var int Maximum number of queries in the queries log.
124
 * @access private
125
 */
126
	var $_queriesLogMax = 200;
127
/**
128
 * Caches serialzed results of executed queries
129
 *
130
 * @var array Maximum number of queries in the queries log.
131
 * @access private
132
 */
133
	var $_queryCache = array();
134
/**
135
 * The default configuration of a specific DataSource
136
 *
137
 * @var array
138
 * @access public
139
 */
140
	var $_baseConfig = array();
141
/**
142
 * Holds references to descriptions loaded by the DataSource
143
 *
144
 * @var array
145
 * @access private
146
 */
147
	var $__descriptions = array();
148
/**
149
 * Holds a list of sources (tables) contained in the DataSource
150
 *
151
 * @var array
152
 * @access protected
153
 */
154
	var $_sources = null;
155
/**
156
 * A reference to the physical connection of this DataSource
157
 *
158
 * @var array
159
 * @access public
160
 */
161
	var $connection = null;
162
/**
163
 * The DataSource configuration
164
 *
165
 * @var array
166
 * @access public
167
 */
168
	var $config = array();
169
/**
170
 * The DataSource configuration key name
171
 *
172
 * @var string
173
 * @access public
174
 */
175
	var $configKeyName = null;
176
/**
177
 * Whether or not this DataSource is in the middle of a transaction
178
 *
179
 * @var boolean
180
 * @access protected
181
 */
182
	var $_transactionStarted = false;
183
/**
184
 * Whether or not source data like available tables and schema descriptions
185
 * should be cached
186
 *
187
 * @var boolean
188
 */
189
	var $cacheSources = true;
190
/**
191
 * Constructor.
192
 */
193
	function __construct($config = array()) {
194
		parent::__construct();
195
		$this->setConfig($config);
196
	}
197
/**
198
 * Caches/returns cached results for child instances
199
 *
200
 * @return array
201
 */
202
	function listSources($data = null) {
203
		if ($this->cacheSources === false) {
204
			return null;
205
		}
206
 
207
		if ($this->_sources !== null) {
208
			return $this->_sources;
209
		}
210
 
211
		$key = ConnectionManager::getSourceName($this) . '_' . $this->config['database'] . '_list';
212
		$key = preg_replace('/[^A-Za-z0-9_\-.+]/', '_', $key);
213
		$sources = Cache::read($key, '_cake_model_');
214
 
215
		if (empty($sources)) {
216
			$sources = $data;
217
			Cache::write($key, $data, '_cake_model_');
218
		}
219
 
220
		$this->_sources = $sources;
221
		return $sources;
222
	}
223
/**
224
 * Convenience method for DboSource::listSources().  Returns source names in lowercase.
225
 *
226
 * @return array
227
 */
228
	function sources($reset = false) {
229
		if ($reset === true) {
230
			$this->_sources = null;
231
		}
232
		return array_map('strtolower', $this->listSources());
233
	}
234
/**
235
 * Returns a Model description (metadata) or null if none found.
236
 *
237
 * @param Model $model
238
 * @return mixed
239
 */
240
	function describe($model) {
241
		if ($this->cacheSources === false) {
242
			return null;
243
		}
244
		if (isset($this->__descriptions[$model->tablePrefix . $model->table])) {
245
			return $this->__descriptions[$model->tablePrefix . $model->table];
246
		}
247
		$cache = $this->__cacheDescription($model->tablePrefix . $model->table);
248
 
249
		if ($cache !== null) {
250
			$this->__descriptions[$model->tablePrefix . $model->table] =& $cache;
251
			return $cache;
252
		}
253
		return null;
254
	}
255
/**
256
 * Begin a transaction
257
 *
258
 * @return boolean Returns true if a transaction is not in progress
259
 */
260
	function begin(&$model) {
261
		return !$this->_transactionStarted;
262
	}
263
/**
264
 * Commit a transaction
265
 *
266
 * @return boolean Returns true if a transaction is in progress
267
 */
268
	function commit(&$model) {
269
		return $this->_transactionStarted;
270
	}
271
/**
272
 * Rollback a transaction
273
 *
274
 * @return boolean Returns true if a transaction is in progress
275
 */
276
	function rollback(&$model) {
277
		return $this->_transactionStarted;
278
	}
279
/**
280
 * Converts column types to basic types
281
 *
282
 * @param string $real Real  column type (i.e. "varchar(255)")
283
 * @return string Abstract column type (i.e. "string")
284
 */
285
	function column($real) {
286
		return false;
287
	}
288
/**
289
 * To-be-overridden in subclasses.
290
 *
291
 * @param unknown_type $model
292
 * @param unknown_type $fields
293
 * @param unknown_type $values
294
 * @return unknown
295
 */
296
	function create(&$model, $fields = null, $values = null) {
297
		return false;
298
	}
299
/**
300
 * To-be-overridden in subclasses.
301
 *
302
 * @param unknown_type $model
303
 * @param unknown_type $queryData
304
 * @return unknown
305
 */
306
	function read(&$model, $queryData = array()) {
307
		return false;
308
	}
309
/**
310
 * To-be-overridden in subclasses.
311
 *
312
 * @param unknown_type $model
313
 * @param unknown_type $fields
314
 * @param unknown_type $values
315
 * @return unknown
316
 */
317
	function update(&$model, $fields = null, $values = null) {
318
		return false;
319
	}
320
/**
321
 * To-be-overridden in subclasses.
322
 *
323
 * @param unknown_type $model
324
 * @param unknown_type $id
325
 */
326
	function delete(&$model, $id = null) {
327
		if ($id == null) {
328
			$id = $model->id;
329
		}
330
	}
331
/**
332
 * Returns the ID generated from the previous INSERT operation.
333
 *
334
 * @param unknown_type $source
335
 * @return in
336
 */
337
	function lastInsertId($source = null) {
338
		return false;
339
	}
340
/**
341
 * Returns the ID generated from the previous INSERT operation.
342
 *
343
 * @param unknown_type $source
344
 * @return in
345
 */
346
	function lastNumRows($source = null) {
347
		return false;
348
	}
349
/**
350
 * Returns the ID generated from the previous INSERT operation.
351
 *
352
 * @param unknown_type $source
353
 * @return in
354
 */
355
	function lastAffected($source = null) {
356
		return false;
357
	}
358
/**
359
 * Returns true if the DataSource supports the given interface (method)
360
 *
361
 * @param string $interface The name of the interface (method)
362
 * @return boolean True on success
363
 */
364
	function isInterfaceSupported($interface) {
365
		$methods = get_class_methods(get_class($this));
366
		$methods = strtolower(implode('|', $methods));
367
		$methods = explode('|', $methods);
368
		$return = in_array(strtolower($interface), $methods);
369
		return $return;
370
	}
371
/**
372
 * Sets the configuration for the DataSource
373
 *
374
 * @param array $config The configuration array
375
 * @return void
376
 */
377
	function setConfig($config = array()) {
378
		$this->config = array_merge($this->_baseConfig, $this->config, $config);
379
	}
380
/**
381
 * Cache the DataSource description
382
 *
383
 * @param string $object The name of the object (model) to cache
384
 * @param mixed $data The description of the model, usually a string or array
385
 */
386
	function __cacheDescription($object, $data = null) {
387
		if ($this->cacheSources === false) {
388
			return null;
389
		}
390
 
391
		if ($data !== null) {
392
			$this->__descriptions[$object] =& $data;
393
		}
394
 
395
		$key = ConnectionManager::getSourceName($this) . '_' . $object;
396
		$cache = Cache::read($key, '_cake_model_');
397
 
398
		if (empty($cache)) {
399
			$cache = $data;
400
			Cache::write($key, $cache, '_cake_model_');
401
		}
402
 
403
		return $cache;
404
	}
405
/**
406
 * Enter description here...
407
 *
408
 * @param unknown_type $query
409
 * @param unknown_type $data
410
 * @param unknown_type $association
411
 * @param unknown_type $assocData
412
 * @param Model $model
413
 * @param Model $linkModel
414
 * @param array $stack
415
 * @return unknown
416
 */
417
	function insertQueryData($query, $data, $association, $assocData, &$model, &$linkModel, $stack) {
418
		$keys = array('{$__cakeID__$}', '{$__cakeForeignKey__$}');
419
 
420
		foreach ($keys as $key) {
421
			$val = null;
422
 
423
			if (strpos($query, $key) !== false) {
424
				switch ($key) {
425
					case '{$__cakeID__$}':
426
						if (isset($data[$model->alias]) || isset($data[$association])) {
427
							if (isset($data[$model->alias][$model->primaryKey])) {
428
								$val = $data[$model->alias][$model->primaryKey];
429
							} elseif (isset($data[$association][$model->primaryKey])) {
430
								$val = $data[$association][$model->primaryKey];
431
							}
432
						} else {
433
							$found = false;
434
							foreach (array_reverse($stack) as $assoc) {
435
								if (isset($data[$assoc]) && isset($data[$assoc][$model->primaryKey])) {
436
									$val = $data[$assoc][$model->primaryKey];
437
									$found = true;
438
									break;
439
								}
440
							}
441
							if (!$found) {
442
								$val = '';
443
							}
444
						}
445
					break;
446
					case '{$__cakeForeignKey__$}':
447
						foreach ($model->__associations as $id => $name) {
448
							foreach ($model->$name as $assocName => $assoc) {
449
								if ($assocName === $association) {
450
									if (isset($assoc['foreignKey'])) {
451
										$foreignKey = $assoc['foreignKey'];
452
 
453
										if (isset($data[$model->alias][$foreignKey])) {
454
											$val = $data[$model->alias][$foreignKey];
455
										} elseif (isset($data[$association][$foreignKey])) {
456
											$val = $data[$association][$foreignKey];
457
										} else {
458
											$found = false;
459
											foreach (array_reverse($stack) as $assoc) {
460
												if (isset($data[$assoc]) && isset($data[$assoc][$foreignKey])) {
461
													$val = $data[$assoc][$foreignKey];
462
													$found = true;
463
													break;
464
												}
465
											}
466
											if (!$found) {
467
												$val = '';
468
											}
469
										}
470
									}
471
									break 3;
472
								}
473
							}
474
						}
475
					break;
476
				}
477
				if (empty($val) && $val !== '0') {
478
					return false;
479
				}
480
				$query = str_replace($key, $this->value($val, $model->getColumnType($model->primaryKey)), $query);
481
			}
482
		}
483
		return $query;
484
	}
485
/**
486
 * To-be-overridden in subclasses.
487
 *
488
 * @param unknown_type $model
489
 * @param unknown_type $key
490
 * @return unknown
491
 */
492
	function resolveKey($model, $key) {
493
		return $model->alias . $key;
494
	}
495
/**
496
 * Closes the current datasource.
497
 *
498
 */
499
	function __destruct() {
500
		if ($this->_transactionStarted) {
501
			$null = null;
502
			$this->rollback($null);
503
		}
504
		if ($this->connected) {
505
			$this->close();
506
		}
507
	}
508
}
509
?>