dbo_odbc.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: dbo__odbc_8php-source.html 580 2008-07-01 14:45:49Z gwoo $ */
00003 
00004 /**
00005  * ODBC for DBO
00006  *
00007  * Long description for file
00008  *
00009  * PHP versions 4 and 5
00010  *
00011  * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
00012  * Copyright 2005-2008, Cake Software Foundation, Inc.
00013  *                              1785 E. Sahara Avenue, Suite 490-204
00014  *                              Las Vegas, Nevada 89104
00015  *
00016  * Licensed under The MIT License
00017  * Redistributions of files must retain the above copyright notice.
00018  *
00019  * @filesource
00020  * @copyright       Copyright 2005-2008, Cake Software Foundation, Inc.
00021  * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00022  * @package         cake
00023  * @subpackage      cake.cake.libs.model.dbo
00024  * @since           CakePHP(tm) v 0.10.5.1790
00025  * @version         $Revision: 580 $
00026  * @modifiedby      $LastChangedBy: gwoo $
00027  * @lastmodified    $Date: 2008-07-01 09:45:49 -0500 (Tue, 01 Jul 2008) $
00028  * @license         http://www.opensource.org/licenses/mit-license.php The MIT License
00029  */
00030 
00031 /**
00032  * Short description for class.
00033  *
00034  * Long description for class
00035  *
00036  * @package     cake
00037  * @subpackage  cake.cake.libs.model.datasources.dbo
00038  */
00039 class DboOdbc extends DboSource{
00040 
00041 /**
00042  * Driver description
00043  *
00044  * @var string
00045  */
00046     var $description = "ODBC DBO Driver";
00047 
00048 /**
00049  * Table/column starting quote
00050  *
00051  * @var string
00052  */
00053     var $startQuote = "`";
00054 
00055 /**
00056  * Table/column end quote
00057  *
00058  * @var string
00059  */
00060     var $endQuote = "`";
00061 
00062 /**
00063  * Driver base configuration
00064  *
00065  * @var array
00066  */
00067     var $_baseConfig = array('persistent' => true,
00068                 'login' => 'root',
00069                 'password' => '',
00070                 'database' => 'cake',
00071                 'connect'  => 'odbc_pconnect'
00072     );
00073 
00074 /**
00075  * Enter description here...
00076  *
00077  * @var unknown_type
00078  */
00079 
00080     var $columns = array();
00081 
00082     //  var $columns = array('primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
00083     //                      'string' => array('name' => 'varchar', 'limit' => '255'),
00084     //                      'text' => array('name' => 'text'),
00085     //                      'integer' => array('name' => 'int', 'limit' => '11'),
00086     //                      'float' => array('name' => 'float'),
00087     //                      'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
00088     //                      'timestamp' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
00089     //                      'time' => array('name' => 'time', 'format' => 'h:i:s', 'formatter' => 'date'),
00090     //                      'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
00091     //                      'binary' => array('name' => 'blob'),
00092     //                      'boolean' => array('name' => 'tinyint', 'limit' => '1'));
00093 
00094 /**
00095  * Connects to the database using options in the given configuration array.
00096  *
00097  * @return boolean True if the database could be connected, else false
00098  */
00099     function connect() {
00100         $config = $this->config;
00101         $connect = $config['connect'];
00102 
00103         $this->connected = false;
00104         $this->connection = $connect($config['database'], $config['login'], $config['password']);
00105 
00106         if ($this->connection) {
00107                 $this->connected = true;
00108         }
00109 
00110         return $this->connected;
00111     }
00112 
00113 /**
00114  * Disconnects from database.
00115  *
00116  * @return boolean True if the database could be disconnected, else false
00117  */
00118     function disconnect() {
00119         return @odbc_close($this->connection);
00120     }
00121 /**
00122  * Executes given SQL statement.
00123  *
00124  * @param string $sql SQL statement
00125  * @return resource Result resource identifier
00126  * @access protected
00127  */
00128     function _execute($sql) {
00129         return odbc_exec($this->connection, $sql);
00130     }
00131 /**
00132  * Returns an array of sources (tables) in the database.
00133  *
00134  * @return array Array of tablenames in the database
00135  */
00136     function listSources() {
00137 
00138         $cache = parent::listSources();
00139         if ($cache != null) {
00140             return $cache;
00141         }
00142 
00143         /*$result = odbc_tables($this->connection);
00144         if (function_exists('odbc_fetch_row')) {
00145             echo 'GOOD';
00146         } else {
00147             echo 'BAD';
00148         }*/
00149 
00150         $result = odbc_tables($this->connection);
00151 
00152         $tables = array();
00153         while (odbc_fetch_row($result)) {
00154             array_push($tables, odbc_result($result, "TABLE_NAME"));
00155         }
00156 
00157         parent::listSources($tables);
00158         return $tables;
00159     }
00160 /**
00161  * Returns an array of the fields in given table name.
00162  *
00163  * @param Model $model Model object to describe
00164  * @return array Fields in table. Keys are name and type
00165  */
00166     function &describe(&$model) {
00167         $cache=parent::describe($model);
00168 
00169         if ($cache != null) {
00170                 return $cache;
00171         }
00172 
00173         $fields = array();
00174         $sql = 'SELECT * FROM ' . $this->fullTableName($model);
00175         $result = odbc_exec($this->connection, $sql);
00176 
00177         $count = odbc_num_fields($result);
00178 
00179         for ($i = 1; $i <= $count; $i++) {
00180                 $cols[$i - 1] = odbc_field_name($result, $i);
00181         }
00182 
00183         foreach ($cols as $column) {
00184             $type = odbc_field_type(odbc_exec($this->connection, "SELECT " . $column . " FROM " . $this->fullTableName($model)), 1);
00185             $fields[$column] = array('type' => $type);
00186         }
00187 
00188         $this->__cacheDescription($model->tablePrefix . $model->table, $fields);
00189         return $fields;
00190     }
00191 
00192     function name($data) {
00193         if ($data == '*') {
00194                 return '*';
00195         }
00196 
00197         $pos = strpos($data, '`');
00198 
00199         if ($pos === false) {
00200                 $data = '' . str_replace('.', '.', $data) . '';
00201         //$data = '`'. str_replace('.', '`.`', $data) .'`';
00202         }
00203 
00204         return $data;
00205     }
00206 
00207 /**
00208  * Returns a quoted and escaped string of $data for use in an SQL statement.
00209  *
00210  * @param string $data String to be prepared for use in an SQL statement
00211  * @param string $column The column into which this data will be inserted
00212  * @return string Quoted and escaped
00213  * @todo Add logic that formats/escapes data based on column type
00214  */
00215     function value($data, $column = null) {
00216         $parent=parent::value($data, $column);
00217 
00218         if ($parent != null) {
00219                 return $parent;
00220         }
00221 
00222         if ($data === null) {
00223                 return 'NULL';
00224         }
00225 
00226         // $data = mysql_real_escape_string($data, $this->connection);
00227 
00228         if (!is_numeric($data)) {
00229                 $return = "'" . $data . "'";
00230         } else {
00231                 $return = $data;
00232         }
00233 
00234         return $return;
00235     }
00236 
00237 /**
00238  * Not sure about this one, MySQL needs it but does ODBC?  Safer just to leave it
00239  * Translates between PHP boolean values and MySQL (faked) boolean values
00240  *
00241  * @param mixed $data Value to be translated
00242  * @return mixed Converted boolean value
00243  */
00244     function boolean($data) {
00245         if ($data === true || $data === false) {
00246                 if ($data === true) {
00247                     return 1;
00248                 }
00249 
00250                 return 0;
00251         } else {
00252                 if (intval($data !== 0)) {
00253                     return true;
00254                 }
00255 
00256                 return false;
00257         }
00258     }
00259 
00260 /**
00261  * Begin a transaction
00262  *
00263  * @param unknown_type $model
00264  * @return boolean True on success, false on fail
00265  * (i.e. if the database/model does not support transactions).
00266  */
00267     function begin(&$model) {
00268         if (parent::begin($model)) {
00269                 if (odbc_autocommit($this->connection, false)) {
00270                     $this->_transactionStarted = true;
00271                     return true;
00272                 }
00273         }
00274 
00275         return false;
00276     }
00277 
00278 /**
00279  * Commit a transaction
00280  *
00281  * @param unknown_type $model
00282  * @return boolean True on success, false on fail
00283  * (i.e. if the database/model does not support transactions,
00284  * or a transaction has not started).
00285  */
00286     function commit(&$model) {
00287         if (parent::commit($model)) {
00288                 if (odbc_commit($this->connection)) {
00289                     $this->_transactionStarted = false;
00290                     return true;
00291                 }
00292         }
00293 
00294         return false;
00295     }
00296 
00297 /**
00298  * Rollback a transaction
00299  *
00300  * @param unknown_type $model
00301  * @return boolean True on success, false on fail
00302  * (i.e. if the database/model does not support transactions,
00303  * or a transaction has not started).
00304  */
00305     function rollback(&$model) {
00306         if (parent::rollback($model)) {
00307                 $this->_transactionStarted=false;
00308                 return odbc_rollback($this->connection);
00309         }
00310 
00311         return false;
00312     }
00313 
00314 /**
00315  * Returns a formatted error message from previous database operation.
00316  *
00317  * @return string Error message with error number
00318  */
00319     function lastError() {
00320         if (odbc_error($this->connection)) {
00321                 return odbc_error($this->connection) . ': ' . odbc_errormsg($this->connection);
00322         }
00323 
00324         return null;
00325     }
00326 
00327 /**
00328  * Returns number of affected rows in previous database operation. If no previous operation exists,
00329  * this returns false.
00330  *
00331  * @return integer Number of affected rows
00332  */
00333     function lastAffected() {
00334         if ($this->_result) {
00335                 return null;
00336         }
00337 
00338         return null;
00339     }
00340 
00341 /**
00342  * Returns number of rows in previous resultset. If no previous resultset exists,
00343  * this returns false.
00344  *
00345  * @return integer Number of rows in resultset
00346  */
00347     function lastNumRows() {
00348         if ($this->_result) {
00349                 return@odbc_num_rows($this->_result);
00350         }
00351 
00352         return null;
00353     }
00354 
00355 /**
00356  * Returns the ID generated from the previous INSERT operation.
00357  *
00358  * @param unknown_type $source
00359  * @return int
00360  */
00361     function lastInsertId($source = null) {
00362         $result=$this->fetchRow('SELECT @@IDENTITY');
00363         return $result[0];
00364     }
00365 
00366 /**
00367  * Enter description here...
00368  *
00369  * @param string $real Real database-layer column type (i.e. "varchar(255)")
00370  */
00371     function column($real) {
00372         if (is_array($real)) {
00373                 $col=$real['name'];
00374 
00375                 if (isset($real['limit'])) {
00376                     $col .= '(' . $real['limit'] . ')';
00377                 }
00378 
00379                 return $col;
00380         }
00381 
00382         return $real;
00383     }
00384 
00385 /**
00386  * Enter description here...
00387  *
00388  * @param unknown_type $results
00389  */
00390     function resultSet(&$results) {
00391         $this->results=&$results;
00392         $this->map=array();
00393         $num_fields   =odbc_num_fields($results);
00394         $index        =0;
00395         $j            =0;
00396 
00397         while ($j < $num_fields) {
00398                 $column = odbc_fetch_array($results, $j);
00399 
00400                 if (!empty($column->table)) {
00401                     $this->map[$index++] = array($column->table,
00402                                 $column->name);
00403                 } else {
00404                     echo array(0,
00405                                 $column->name);
00406 
00407                     $this->map[$index++]=array(0,
00408                                 $column->name);
00409                 }
00410 
00411                 $j++;
00412         }
00413     }
00414 
00415 /**
00416  * Fetches the next row from the current result set
00417  *
00418  * @return unknown
00419  */
00420     function fetchResult() {
00421         if ($row = odbc_fetch_row($this->results)) {
00422                 $resultRow=array();
00423                 $i=0;
00424 
00425                 foreach ($row as $index => $field) {
00426                     list($table, $column)      = $this->map[$index];
00427                     $resultRow[$table][$column]=$row[$index];
00428                     $i++;
00429                 }
00430 
00431                 return $resultRow;
00432         } else {
00433                 return false;
00434         }
00435     }
00436 }
00437 ?>