| [ Index ] |
PHP Cross Reference of Akelos Framework |
[Summary view] [Print] [Text view]
1 <?php 2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 3 4 // +----------------------------------------------------------------------+ 5 // | Akelos Framework - http://www.akelos.org | 6 // +----------------------------------------------------------------------+ 7 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez | 8 // | Released under the GNU Lesser General Public License, see LICENSE.txt| 9 // +----------------------------------------------------------------------+ 10 11 /** 12 * @package ActiveRecord 13 * @subpackage Base 14 * @component DbAdapter 15 * @author Bermi Ferrer <bermi a.t akelos c.om> 2004 - 2007 16 * @author Kaste 2007 17 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org 18 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html> 19 */ 20 21 defined('AK_AVAILABLE_DATABASES') ? null : define('AK_AVAILABLE_DATABASES', 'mysql,pgsql,sqlite'); 22 23 require_once (AK_LIB_DIR.DS.'AkObject.php'); 24 25 class AkDbAdapter extends AkObject 26 { 27 28 var $connection; 29 var $settings; 30 var $dictionary; 31 var $debug=false; 32 var $logger; 33 34 /** 35 * @param array $database_settings 36 */ 37 function __construct($database_settings, $auto_connect = false) 38 { 39 $this->settings = $database_settings; 40 if ($auto_connect){ 41 $this->connect(); 42 } 43 if (AK_LOG_EVENTS){ 44 $this->logger =& Ak::getLogger(); 45 } 46 } 47 48 function __destruct() 49 { 50 } 51 52 function connect($die_on_error=true) 53 { 54 $dsn = $this->_constructDsn($this->settings); 55 require_once(AK_CONTRIB_DIR.DS.'adodb'.DS.'adodb.inc.php'); 56 $this->connection = AK_DEBUG ? NewADOConnection($dsn) : @NewADOConnection($dsn); 57 if (!$this->connection){ 58 error_reporting(E_ALL); 59 if(defined('AK_DATABASE_CONNECTION_FAILURE_CALLBACK') && function_exists(AK_DATABASE_CONNECTION_FAILURE_CALLBACK)){ 60 $fn = AK_DATABASE_CONNECTION_FAILURE_CALLBACK; 61 $fn(); 62 } 63 if(!AK_PHP5 && $this->type() == 'sqlite'){ 64 trigger_error(Ak::t("\nWarning, sqlite support is not available by default on PHP4.\n Check your PHP version by running \"env php -v\", and change the first line in your scripts/ so they point to a php5 binary\n\n"),E_USER_WARNING); 65 } 66 trigger_error(Ak::t("Connection to the database failed. %dsn", 67 array('%dsn'=> AK_DEBUG ? preg_replace('/\/\/(\w+):(.*)@/i','//$1:******@', urldecode($dsn))."\n" : '')), 68 ($die_on_error?E_USER_ERROR:E_USER_WARNING)); 69 } else { 70 $this->connection->debug = AK_DEBUG == 2; 71 $this->connection->SetFetchMode(ADODB_FETCH_ASSOC); 72 defined('AK_DATABASE_CONNECTION_AVAILABLE') ? null : define('AK_DATABASE_CONNECTION_AVAILABLE', true); 73 } 74 } 75 76 function connected() 77 { 78 return !empty($this->connection); 79 } 80 81 82 /** 83 * @static 84 * @param array $database_settings 85 * @return AkDbAdapter 86 */ 87 function &getInstance($database_specifications = AK_DEFAULT_DATABASE_PROFILE, $auto_connect = true) 88 { 89 static $connections; 90 91 $settings_hash = is_string($database_specifications) ? $database_specifications : AkDbAdapter::_hash($database_specifications); 92 93 if (empty($connections[$settings_hash])){ 94 if (empty($database_specifications)) { 95 $settings_hash = AK_ENVIRONMENT; 96 $database_specifications = Ak::getSettings('database',false,$settings_hash); 97 } else if (is_string($database_specifications)){ 98 $environment_settings = Ak::getSettings('database',false,$database_specifications); 99 if (!empty($environment_settings)){ 100 $database_specifications = $environment_settings; 101 } elseif(strstr($database_specifications, '://')) { 102 $database_specifications = AkDbAdapter::_getDbSettingsFromDsn($database_specifications); 103 $settings_hash = AK_ENVIRONMENT; 104 } else { 105 global $database_settings; 106 if (isset($database_settings) && !file_exists(AK_CONFIG_DIR.DS.'database.yml')) { 107 trigger_error(Ak::t("You are still using the old config/config.php database configuration. Please upgrade to use the config/database.yml configuration."), E_USER_NOTICE); 108 } 109 if (!file_exists(AK_CONFIG_DIR.DS.'database.yml')) { 110 trigger_error(Ak::t("Could not find the database configuration file in %dbconfig.",array('%dbconfig'=>AK_CONFIG_DIR.DS.'database.yml')),E_USER_ERROR); 111 } else { 112 trigger_error(Ak::t("Could not find the database profile '%profile_name' in config/database.yml.",array('%profile_name'=>$database_specifications)),E_USER_ERROR); 113 } 114 115 116 $return = false; 117 return $return; 118 } 119 }elseif (!empty($database_settings[$settings_hash])){ 120 $database_specifications = $database_settings[$settings_hash]; 121 } 122 $available_adapters = Ak::toArray(AK_AVAILABLE_DATABASES); 123 $class_name = 'AkDbAdapter'; 124 $designated_database = strtolower($database_specifications['type']); 125 if (in_array($designated_database, $available_adapters)) { 126 $class_name = 'Ak'.ucfirst($designated_database).'DbAdapter'; 127 require_once(AK_LIB_DIR.DS.'AkActiveRecord'.DS.'AkDbAdapters'.DS.$class_name.'.php'); 128 } 129 $connections[$settings_hash] =& new $class_name($database_specifications,$auto_connect); 130 } 131 return $connections[$settings_hash]; 132 } 133 134 /** 135 * @param array $settings 136 * @return string 137 */ 138 function _hash($settings) 139 { 140 if(!is_array($settings)){ 141 return AK_ENVIRONMENT; 142 } 143 if (isset($settings['password'])){ 144 unset($settings['password']); 145 } 146 return join(':',$settings); 147 } 148 149 function &getDictionary() 150 { 151 if (empty($this->dictionary)){ 152 if (!$this->connected()){ 153 $this->connect(); 154 } 155 require_once(AK_CONTRIB_DIR.DS.'adodb'.DS.'adodb.inc.php'); 156 $this->dictionary =& NewDataDictionary($this->connection); 157 } 158 return $this->dictionary; 159 } 160 161 /** 162 * @param array $database_settings 163 * @return string 164 */ 165 function _constructDsn($database_settings) 166 { 167 if(is_string($database_settings)){ 168 return $database_settings; 169 } 170 $dsn = $database_settings['type'].'://'; 171 $dsn .= $database_settings['user'].':'.$database_settings['password']; 172 $dsn .= !empty($database_settings['host']) ? '@'.$database_settings['host'] : '@localhost'; 173 $dsn .= !empty($database_settings['port']) ? ':'.$database_settings['port'] : ''; 174 $dsn .= '/'.$database_settings['database_name']; 175 $dsn .= !empty($database_settings['options']) ? $database_settings['options'] : ''; 176 return $dsn; 177 178 } 179 180 function _getDbSettingsFromDsn($dsn) 181 { 182 $settings = $result = parse_url($dsn); 183 $result['type'] = $settings['scheme']; 184 $result['password'] = $settings['pass']; 185 $result['database_name'] = trim($settings['path'],'/'); 186 return $result; 187 } 188 189 function type() 190 { 191 return $this->settings['type']; 192 } 193 194 function debug($on = 'switch') 195 { 196 if ($on == 'switch') { 197 $this->debug = !$this->debug; 198 }else{ 199 $this->debug = $on; 200 } 201 return $this->debug; 202 } 203 204 function _log($message) 205 { 206 if (!AK_LOG_EVENTS){ 207 return; 208 } 209 $this->logger->message($message); 210 } 211 212 function addLimitAndOffset(&$sql,$options) 213 { 214 if (isset($options['limit']) && $limit = $options['limit']){ 215 $sql .= " LIMIT $limit"; 216 if (isset($options['offset']) && $offset = $options['offset']){ 217 $sql .= " OFFSET $offset"; 218 } 219 } 220 return $sql; 221 } 222 223 /* DATABASE STATEMENTS - CRUD */ 224 225 function execute($sql, $message = 'SQL') 226 { 227 if (is_array($sql)) { 228 $sql_string = array_shift($sql); 229 $bindings = $sql; 230 } else $sql_string = $sql; 231 232 $this->_log($message.': '.$sql_string); 233 $result = isset($bindings) ? $this->connection->Execute($sql_string, $bindings) : $this->connection->Execute($sql_string); 234 235 if (!$result){ 236 $error_message = '['.$this->connection->ErrorNo().'] '.$this->connection->ErrorMsg(); 237 $this->_log('SQL Error: '.$error_message); 238 if ($this->debug || AK_DEBUG) trigger_error("Tried '$sql_string'. Got: $error_message", E_USER_NOTICE); 239 } 240 return $result; 241 } 242 243 function incrementsPrimaryKeyAutomatically() 244 { 245 return true; 246 } 247 248 function getLastInsertedId($table,$pk) 249 { 250 return $this->connection->Insert_ID($table,$pk); 251 } 252 253 function getAffectedRows() 254 { 255 return $this->connection->Affected_Rows(); 256 } 257 258 function insert($sql,$id=null,$pk=null,$table=null,$message = '') 259 { 260 $result = $this->execute($sql,$message); 261 if (!$result){ 262 return false; 263 } 264 return is_null($id) ? $this->getLastInsertedId($table,$pk) : $id; 265 } 266 267 function update($sql,$message = '') 268 { 269 $result = $this->execute($sql,$message); 270 return ($result) ? $this->getAffectedRows() : false; 271 } 272 273 function delete($sql,$message = '') 274 { 275 $result = $this->execute($sql,$message); 276 return ($result) ? $this->getAffectedRows() : false; 277 } 278 279 /** 280 * Returns a single value, the first column from the first row, from a record 281 */ 282 function selectValue($sql) 283 { 284 $result = $this->selectOne($sql); 285 return !is_null($result) ? array_shift($result) : null; 286 } 287 288 /** 289 * Returns an array of the values of the first column in a select: 290 * sqlSelectValues("SELECT id FROM companies LIMIT 3") => array(1,2,3) 291 */ 292 function selectValues($sql) 293 { 294 $values = array(); 295 if($results = $this->select($sql)){ 296 foreach ($results as $result){ 297 $values[] = array_shift($result); 298 } 299 } 300 return $values; 301 } 302 303 /** 304 * Returns a record array of the first row with the column names as keys and column values 305 * as values. 306 */ 307 function selectOne($sql) 308 { 309 $result = $this->select($sql); 310 return !is_null($result) ? array_shift($result) : null; 311 } 312 313 /** 314 * alias for select 315 */ 316 function selectAll($sql) 317 { 318 return $this->select($sql); 319 } 320 321 /** 322 * Returns an array of record hashes with the column names as keys and 323 * column values as values. 324 */ 325 function select($sql, $message = '') 326 { 327 $result = $this->execute($sql, $message); 328 if (!$result){ 329 return array(); 330 } 331 332 $records = array(); 333 while ($record = $result->FetchRow()) { 334 $records[] = $record; 335 } 336 $result->Close(); 337 return $records; 338 } 339 340 /* TRANSACTIONS */ 341 342 function startTransaction() 343 { 344 return $this->connection->StartTrans(); 345 } 346 347 function stopTransaction() 348 { 349 return $this->connection->CompleteTrans(); 350 } 351 352 function failTransaction() 353 { 354 return $this->connection->FailTrans(); 355 } 356 357 function hasTransactionFailed() 358 { 359 return $this->connection->HasFailedTrans(); 360 } 361 362 /* SCHEMA */ 363 364 function renameColumn($table_name,$column_name,$new_name) 365 { 366 trigger_error(Ak::t('renameColumn is not available for your DbAdapter. Using %db_type.',array('%db_type'=>$this->type()))); 367 } 368 369 /* META */ 370 371 /** 372 * caching the meta info 373 * 374 * @return unknown 375 */ 376 function availableTables() 377 { 378 return $this->connection->MetaTables(); 379 } 380 /** 381 * caching the meta info 382 * 383 * @param unknown_type $table_name 384 * @return unknown 385 */ 386 function getColumnDetails($table_name) 387 { 388 return $this->connection->MetaColumns($table_name); 389 } 390 391 /** 392 * caching the meta info 393 * 394 * @param unknown_type $table_name 395 * @return unknown 396 */ 397 function getIndexes($table_name) 398 { 399 return $this->connection->MetaIndexes($table_name); 400 } 401 402 /* QUOTING */ 403 404 function quote_string($value) 405 { 406 return $this->connection->qstr($value); 407 } 408 409 function quote_datetime($value) 410 { 411 return $this->connection->DBTimeStamp($value); 412 } 413 414 function quote_date($value) 415 { 416 return $this->connection->DBDate($value); 417 } 418 419 // will be moved to postgre 420 function escape_blob($value) 421 { 422 return $this->connection->BlobEncode($value); 423 } 424 425 // will be moved to postgre 426 function unescape_blob($value) 427 { 428 return $this->connection->BlobDecode($value); 429 } 430 431 } 432 433 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Oct 27 12:43:49 2008 | Cross-referenced by PHPXref 0.6 |