Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16591 anikendra 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
}