[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/AkActiveRecord/ -> AkDbAdapter.php (source)

   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  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6