datasource.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: datasource.php 8270 2009-08-02 18:52:55Z jperras $ */
00003 /**
00004  * DataSource base class
00005  *
00006  * Long description for file
00007  *
00008  * PHP versions 4 and 5
00009  *
00010  * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
00011  * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00018  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package       cake
00020  * @subpackage    cake.cake.libs.model.datasources
00021  * @since         CakePHP(tm) v 0.10.5.1790
00022  * @version       $Revision: 8270 $
00023  * @modifiedby    $LastChangedBy: jperras $
00024  * @lastmodified  $Date: 2009-08-02 14:52:55 -0400 (Sun, 02 Aug 2009) $
00025  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 /**
00028  * DataSource base class
00029  *
00030  * Long description for file
00031  *
00032  * @package       cake
00033  * @subpackage    cake.cake.libs.model.datasources
00034  */
00035 class DataSource extends Object {
00036 /**
00037  * Are we connected to the DataSource?
00038  *
00039  * @var boolean
00040  * @access public
00041  */
00042     var $connected = false;
00043 /**
00044  * Print full query debug info?
00045  *
00046  * @var boolean
00047  * @access public
00048  */
00049     var $fullDebug = false;
00050 /**
00051  * Error description of last query
00052  *
00053  * @var unknown_type
00054  * @access public
00055  */
00056     var $error = null;
00057 /**
00058  * String to hold how many rows were affected by the last SQL operation.
00059  *
00060  * @var string
00061  * @access public
00062  */
00063     var $affected = null;
00064 /**
00065  * Number of rows in current resultset
00066  *
00067  * @var int
00068  * @access public
00069  */
00070     var $numRows = null;
00071 /**
00072  * Time the last query took
00073  *
00074  * @var int
00075  * @access public
00076  */
00077     var $took = null;
00078 /**
00079  * The starting character that this DataSource uses for quoted identifiers.
00080  *
00081  * @var string
00082  */
00083     var $startQuote = null;
00084 /**
00085  * The ending character that this DataSource uses for quoted identifiers.
00086  *
00087  * @var string
00088  */
00089     var $endQuote = null;
00090 /**
00091  * Enter description here...
00092  *
00093  * @var array
00094  * @access protected
00095  */
00096     var $_result = null;
00097 /**
00098  * Queries count.
00099  *
00100  * @var int
00101  * @access protected
00102  */
00103     var $_queriesCnt = 0;
00104 /**
00105  * Total duration of all queries.
00106  *
00107  * @var unknown_type
00108  * @access protected
00109  */
00110     var $_queriesTime = null;
00111 /**
00112  * Log of queries executed by this DataSource
00113  *
00114  * @var unknown_type
00115  * @access protected
00116  */
00117     var $_queriesLog = array();
00118 /**
00119  * Maximum number of items in query log, to prevent query log taking over
00120  * too much memory on large amounts of queries -- I we've had problems at
00121  * >6000 queries on one system.
00122  *
00123  * @var int Maximum number of queries in the queries log.
00124  * @access protected
00125  */
00126     var $_queriesLogMax = 200;
00127 /**
00128  * Caches serialzed results of executed queries
00129  *
00130  * @var array Maximum number of queries in the queries log.
00131  * @access protected
00132  */
00133     var $_queryCache = array();
00134 /**
00135  * The default configuration of a specific DataSource
00136  *
00137  * @var array
00138  * @access protected
00139  */
00140     var $_baseConfig = array();
00141 /**
00142  * Holds references to descriptions loaded by the DataSource
00143  *
00144  * @var array
00145  * @access private
00146  */
00147     var $__descriptions = array();
00148 /**
00149  * Holds a list of sources (tables) contained in the DataSource
00150  *
00151  * @var array
00152  * @access protected
00153  */
00154     var $_sources = null;
00155 /**
00156  * A reference to the physical connection of this DataSource
00157  *
00158  * @var array
00159  * @access public
00160  */
00161     var $connection = null;
00162 /**
00163  * The DataSource configuration
00164  *
00165  * @var array
00166  * @access public
00167  */
00168     var $config = array();
00169 /**
00170  * The DataSource configuration key name
00171  *
00172  * @var string
00173  * @access public
00174  */
00175     var $configKeyName = null;
00176 /**
00177  * Whether or not this DataSource is in the middle of a transaction
00178  *
00179  * @var boolean
00180  * @access protected
00181  */
00182     var $_transactionStarted = false;
00183 /**
00184  * Whether or not source data like available tables and schema descriptions
00185  * should be cached
00186  *
00187  * @var boolean
00188  */
00189     var $cacheSources = true;
00190 /**
00191  * Constructor.
00192  */
00193     function __construct($config = array()) {
00194         parent::__construct();
00195         $this->setConfig($config);
00196     }
00197 /**
00198  * Caches/returns cached results for child instances
00199  *
00200  * @return array
00201  */
00202     function listSources($data = null) {
00203         if ($this->cacheSources === false) {
00204             return null;
00205         }
00206 
00207         if ($this->_sources !== null) {
00208             return $this->_sources;
00209         }
00210 
00211         $key = ConnectionManager::getSourceName($this) . '_' . $this->config['database'] . '_list';
00212         $key = preg_replace('/[^A-Za-z0-9_\-.+]/', '_', $key);
00213         $sources = Cache::read($key, '_cake_model_');
00214 
00215         if (empty($sources)) {
00216             $sources = $data;
00217             Cache::write($key, $data, '_cake_model_');
00218         }
00219 
00220         $this->_sources = $sources;
00221         return $sources;
00222     }
00223 /**
00224  * Convenience method for DboSource::listSources().  Returns source names in lowercase.
00225  *
00226  * @return array
00227  */
00228     function sources($reset = false) {
00229         if ($reset === true) {
00230             $this->_sources = null;
00231         }
00232         return array_map('strtolower', $this->listSources());
00233     }
00234 /**
00235  * Returns a Model description (metadata) or null if none found.
00236  *
00237  * @param Model $model
00238  * @return mixed
00239  */
00240     function describe($model) {
00241         if ($this->cacheSources === false) {
00242             return null;
00243         }
00244         $table = $this->fullTableName($model, false);
00245         if (isset($this->__descriptions[$table])) {
00246             return $this->__descriptions[$table];
00247         }
00248         $cache = $this->__cacheDescription($table);
00249 
00250         if ($cache !== null) {
00251             $this->__descriptions[$table] =& $cache;
00252             return $cache;
00253         }
00254         return null;
00255     }
00256 /**
00257  * Begin a transaction
00258  *
00259  * @return boolean Returns true if a transaction is not in progress
00260  */
00261     function begin(&$model) {
00262         return !$this->_transactionStarted;
00263     }
00264 /**
00265  * Commit a transaction
00266  *
00267  * @return boolean Returns true if a transaction is in progress
00268  */
00269     function commit(&$model) {
00270         return $this->_transactionStarted;
00271     }
00272 /**
00273  * Rollback a transaction
00274  *
00275  * @return boolean Returns true if a transaction is in progress
00276  */
00277     function rollback(&$model) {
00278         return $this->_transactionStarted;
00279     }
00280 /**
00281  * Converts column types to basic types
00282  *
00283  * @param string $real Real  column type (i.e. "varchar(255)")
00284  * @return string Abstract column type (i.e. "string")
00285  */
00286     function column($real) {
00287         return false;
00288     }
00289 /**
00290  * To-be-overridden in subclasses.
00291  *
00292  * @param unknown_type $model
00293  * @param unknown_type $fields
00294  * @param unknown_type $values
00295  * @return unknown
00296  */
00297     function create(&$model, $fields = null, $values = null) {
00298         return false;
00299     }
00300 /**
00301  * To-be-overridden in subclasses.
00302  *
00303  * @param unknown_type $model
00304  * @param unknown_type $queryData
00305  * @return unknown
00306  */
00307     function read(&$model, $queryData = array()) {
00308         return false;
00309     }
00310 /**
00311  * To-be-overridden in subclasses.
00312  *
00313  * @param unknown_type $model
00314  * @param unknown_type $fields
00315  * @param unknown_type $values
00316  * @return unknown
00317  */
00318     function update(&$model, $fields = null, $values = null) {
00319         return false;
00320     }
00321 /**
00322  * To-be-overridden in subclasses.
00323  *
00324  * @param unknown_type $model
00325  * @param unknown_type $id
00326  */
00327     function delete(&$model, $id = null) {
00328         if ($id == null) {
00329             $id = $model->id;
00330         }
00331     }
00332 /**
00333  * Returns the ID generated from the previous INSERT operation.
00334  *
00335  * @param unknown_type $source
00336  * @return in
00337  */
00338     function lastInsertId($source = null) {
00339         return false;
00340     }
00341 /**
00342  * Returns the ID generated from the previous INSERT operation.
00343  *
00344  * @param unknown_type $source
00345  * @return in
00346  */
00347     function lastNumRows($source = null) {
00348         return false;
00349     }
00350 /**
00351  * Returns the ID generated from the previous INSERT operation.
00352  *
00353  * @param unknown_type $source
00354  * @return in
00355  */
00356     function lastAffected($source = null) {
00357         return false;
00358     }
00359 /**
00360  * Returns true if the DataSource supports the given interface (method)
00361  *
00362  * @param string $interface The name of the interface (method)
00363  * @return boolean True on success
00364  */
00365     function isInterfaceSupported($interface) {
00366         $methods = get_class_methods(get_class($this));
00367         $methods = strtolower(implode('|', $methods));
00368         $methods = explode('|', $methods);
00369         $return = in_array(strtolower($interface), $methods);
00370         return $return;
00371     }
00372 /**
00373  * Sets the configuration for the DataSource
00374  *
00375  * @param array $config The configuration array
00376  * @return void
00377  */
00378     function setConfig($config = array()) {
00379         $this->config = array_merge($this->_baseConfig, $this->config, $config);
00380     }
00381 /**
00382  * Cache the DataSource description
00383  *
00384  * @param string $object The name of the object (model) to cache
00385  * @param mixed $data The description of the model, usually a string or array
00386  */
00387     function __cacheDescription($object, $data = null) {
00388         if ($this->cacheSources === false) {
00389             return null;
00390         }
00391 
00392         if ($data !== null) {
00393             $this->__descriptions[$object] =& $data;
00394         }
00395 
00396         $key = ConnectionManager::getSourceName($this) . '_' . $object;
00397         $cache = Cache::read($key, '_cake_model_');
00398 
00399         if (empty($cache)) {
00400             $cache = $data;
00401             Cache::write($key, $cache, '_cake_model_');
00402         }
00403 
00404         return $cache;
00405     }
00406 /**
00407  * Enter description here...
00408  *
00409  * @param unknown_type $query
00410  * @param unknown_type $data
00411  * @param unknown_type $association
00412  * @param unknown_type $assocData
00413  * @param Model $model
00414  * @param Model $linkModel
00415  * @param array $stack
00416  * @return unknown
00417  */
00418     function insertQueryData($query, $data, $association, $assocData, &$model, &$linkModel, $stack) {
00419         $keys = array('{$__cakeID__$}', '{$__cakeForeignKey__$}');
00420 
00421         foreach ($keys as $key) {
00422             $val = null;
00423 
00424             if (strpos($query, $key) !== false) {
00425                 switch ($key) {
00426                     case '{$__cakeID__$}':
00427                         if (isset($data[$model->alias]) || isset($data[$association])) {
00428                             if (isset($data[$model->alias][$model->primaryKey])) {
00429                                 $val = $data[$model->alias][$model->primaryKey];
00430                             } elseif (isset($data[$association][$model->primaryKey])) {
00431                                 $val = $data[$association][$model->primaryKey];
00432                             }
00433                         } else {
00434                             $found = false;
00435                             foreach (array_reverse($stack) as $assoc) {
00436                                 if (isset($data[$assoc]) && isset($data[$assoc][$model->primaryKey])) {
00437                                     $val = $data[$assoc][$model->primaryKey];
00438                                     $found = true;
00439                                     break;
00440                                 }
00441                             }
00442                             if (!$found) {
00443                                 $val = '';
00444                             }
00445                         }
00446                     break;
00447                     case '{$__cakeForeignKey__$}':
00448                         foreach ($model->__associations as $id => $name) {
00449                             foreach ($model->$name as $assocName => $assoc) {
00450                                 if ($assocName === $association) {
00451                                     if (isset($assoc['foreignKey'])) {
00452                                         $foreignKey = $assoc['foreignKey'];
00453 
00454                                         if (isset($data[$model->alias][$foreignKey])) {
00455                                             $val = $data[$model->alias][$foreignKey];
00456                                         } elseif (isset($data[$association][$foreignKey])) {
00457                                             $val = $data[$association][$foreignKey];
00458                                         } else {
00459                                             $found = false;
00460                                             foreach (array_reverse($stack) as $assoc) {
00461                                                 if (isset($data[$assoc]) && isset($data[$assoc][$foreignKey])) {
00462                                                     $val = $data[$assoc][$foreignKey];
00463                                                     $found = true;
00464                                                     break;
00465                                                 }
00466                                             }
00467                                             if (!$found) {
00468                                                 $val = '';
00469                                             }
00470                                         }
00471                                     }
00472                                     break 3;
00473                                 }
00474                             }
00475                         }
00476                     break;
00477                 }
00478                 if (empty($val) && $val !== '0') {
00479                     return false;
00480                 }
00481                 $query = str_replace($key, $this->value($val, $model->getColumnType($model->primaryKey)), $query);
00482             }
00483         }
00484         return $query;
00485     }
00486 /**
00487  * To-be-overridden in subclasses.
00488  *
00489  * @param unknown_type $model
00490  * @param unknown_type $key
00491  * @return unknown
00492  */
00493     function resolveKey($model, $key) {
00494         return $model->alias . $key;
00495     }
00496 /**
00497  * Closes the current datasource.
00498  *
00499  */
00500     function __destruct() {
00501         if ($this->_transactionStarted) {
00502             $null = null;
00503             $this->rollback($null);
00504         }
00505         if ($this->connected) {
00506             $this->close();
00507         }
00508     }
00509 }
00510 ?>

Generated on Sun Nov 22 00:30:53 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7