dbo_odbc.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: dbo_odbc.php 7921 2008-12-14 18:36:40Z TommyO $ */
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. (http://www.cakefoundation.org)
00013  *
00014  * Licensed under The MIT License
00015  * Redistributions of files must retain the above copyright notice.
00016  *
00017  * @filesource
00018  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00019  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00020  * @package       cake
00021  * @subpackage    cake.cake.libs.model.dbo
00022  * @since         CakePHP(tm) v 0.10.5.1790
00023  * @version       $Revision: 7921 $
00024  * @modifiedby    $LastChangedBy: TommyO $
00025  * @lastmodified  $Date: 2008-12-14 13:36:40 -0500 (Sun, 14 Dec 2008) $
00026  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00027  */
00028 
00029 /**
00030  * Short description for class.
00031  *
00032  * Long description for class
00033  *
00034  * @package       cake
00035  * @subpackage    cake.cake.libs.model.datasources.dbo
00036  */
00037 class DboOdbc extends DboSource {
00038 /**
00039  * Driver description
00040  *
00041  * @var string
00042  */
00043     var $description = "ODBC DBO Driver";
00044 /**
00045  * Table/column starting quote
00046  *
00047  * @var string
00048  */
00049     var $startQuote = "`";
00050 /**
00051  * Table/column end quote
00052  *
00053  * @var string
00054  */
00055     var $endQuote = "`";
00056 /**
00057  * Driver base configuration
00058  *
00059  * @var array
00060  */
00061     var $_baseConfig = array(
00062         'persistent' => true,
00063         'login' => 'root',
00064         'password' => '',
00065         'database' => 'cake',
00066         'connect'  => 'odbc_pconnect'
00067     );
00068 /**
00069  * Enter description here...
00070  *
00071  * @var unknown_type
00072  */
00073     var $columns = array();
00074 
00075     //  var $columns = array('primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
00076     //                      'string' => array('name' => 'varchar', 'limit' => '255'),
00077     //                      'text' => array('name' => 'text'),
00078     //                      'integer' => array('name' => 'int', 'limit' => '11'),
00079     //                      'float' => array('name' => 'float'),
00080     //                      'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
00081     //                      'timestamp' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
00082     //                      'time' => array('name' => 'time', 'format' => 'h:i:s', 'formatter' => 'date'),
00083     //                      'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
00084     //                      'binary' => array('name' => 'blob'),
00085     //                      'boolean' => array('name' => 'tinyint', 'limit' => '1'));
00086 /**
00087  * Connects to the database using options in the given configuration array.
00088  *
00089  * @return boolean True if the database could be connected, else false
00090  */
00091     function connect() {
00092         $config = $this->config;
00093         $connect = $config['connect'];
00094         if (!$config['persistent']) {
00095             $connect = 'odbc_connect';
00096         }
00097         if (!function_exists($connect)) {
00098             die('no odbc?');
00099         }
00100         $this->connected = false;
00101         $this->connection = $connect($config['database'], $config['login'], $config['password'],  SQL_CUR_USE_ODBC);
00102         if ($this->connection) {
00103             $this->connected = true;
00104         }
00105 
00106         return $this->connected;
00107     }
00108 /**
00109  * Disconnects from database.
00110  *
00111  * @return boolean True if the database could be disconnected, else false
00112  */
00113     function disconnect() {
00114         return @odbc_close($this->connection);
00115     }
00116 /**
00117  * Executes given SQL statement.
00118  *
00119  * @param string $sql SQL statement
00120  * @return resource Result resource identifier
00121  * @access protected
00122  */
00123     function _execute($sql) {
00124         switch ($sql) {
00125             case 'BEGIN':
00126                 return odbc_autocommit($this->connection, false);
00127             case 'COMMIT':
00128                 return odbc_commit($this->connection);
00129             case 'ROLLBACK':
00130                 return odbc_rollback($this->connection);
00131         }
00132         // TODO: should flags be set? possible requirement:  SQL_CURSOR_STATIC
00133         return odbc_exec($this->connection, $sql);
00134     }
00135 /**
00136  * Returns an array of sources (tables) in the database.
00137  *
00138  * @return array Array of tablenames in the database
00139  */
00140     function listSources() {
00141         $cache = parent::listSources();
00142         if ($cache != null) {
00143             return $cache;
00144         }
00145 
00146         $result = odbc_tables($this->connection);
00147 
00148         $tables = array();
00149         while (odbc_fetch_row($result)) {
00150             array_push($tables, odbc_result($result, 'TABLE_NAME'));
00151         }
00152 
00153         parent::listSources($tables);
00154         return $tables;
00155     }
00156 /**
00157  * Returns an array of the fields in given table name.
00158  *
00159  * @param Model $model Model object to describe
00160  * @return array Fields in table. Keys are name and type
00161  */
00162     function &describe(&$model) {
00163         $cache=parent::describe($model);
00164 
00165         if ($cache != null) {
00166                 return $cache;
00167         }
00168 
00169         $fields = array();
00170         $sql = 'SELECT * FROM ' . $this->fullTableName($model);
00171         $result = odbc_exec($this->connection, $sql);
00172 
00173         $count = odbc_num_fields($result);
00174 
00175         for ($i = 1; $i <= $count; $i++) {
00176                 $cols[$i - 1] = odbc_field_name($result, $i);
00177         }
00178 
00179         foreach ($cols as $column) {
00180             $type = odbc_field_type(odbc_exec($this->connection, 'SELECT ' . $column . ' FROM ' . $this->fullTableName($model)), 1);
00181             $fields[$column] = array('type' => $type);
00182         }
00183 
00184         $this->__cacheDescription($model->tablePrefix . $model->table, $fields);
00185         return $fields;
00186     }
00187 /**
00188  * Returns a quoted and escaped string of $data for use in an SQL statement.
00189  *
00190  * @param string $data String to be prepared for use in an SQL statement
00191  * @param string $column The column into which this data will be inserted
00192  * @return string Quoted and escaped
00193  * @todo Add logic that formats/escapes data based on column type
00194  */
00195     function value($data, $column = null) {
00196         $parent=parent::value($data, $column);
00197 
00198         if ($parent != null) {
00199                 return $parent;
00200         }
00201 
00202         if ($data === null) {
00203                 return 'NULL';
00204         }
00205 
00206         if (!is_numeric($data)) {
00207                 return "'" . $data . "'";
00208         }
00209 
00210         return $data;
00211     }
00212 /**
00213  * Returns a formatted error message from previous database operation.
00214  *
00215  * @return string Error message with error number
00216  */
00217     function lastError() {
00218         if ($error = odbc_errormsg($this->connection)) {
00219             return odbc_error($this->connection) . ': ' . $error;
00220         }
00221         return null;
00222     }
00223 /**
00224  * Returns number of affected rows in previous database operation. If no previous operation exists,
00225  * this returns false.
00226  *
00227  * @return integer Number of affected rows
00228  */
00229     function lastAffected() {
00230         if ($this->hasResult()) {
00231             return odbc_num_rows($this->_result);
00232         }
00233         return null;
00234     }
00235 /**
00236  * Returns number of rows in previous resultset. If no previous resultset exists,
00237  * this returns false.
00238  *
00239  * @return int Number of rows in resultset
00240  */
00241     function lastNumRows() {
00242         if ($this->hasResult()) {
00243             return odbc_num_rows($this->_result);
00244         }
00245         return null;
00246     }
00247 /**
00248  * Returns the ID generated from the previous INSERT operation.
00249  *
00250  * @param unknown_type $source
00251  * @return int
00252  */
00253     function lastInsertId($source = null) {
00254         $result = $this->fetchRow('SELECT @@IDENTITY');
00255         return $result[0];
00256     }
00257 /**
00258  * Enter description here...
00259  *
00260  * @param string $real Real database-layer column type (i.e. "varchar(255)")
00261  */
00262     function column($real) {
00263         if (is_array($real)) {
00264             $col=$real['name'];
00265             if (isset($real['limit'])) {
00266                 $col .= '(' . $real['limit'] . ')';
00267             }
00268             return $col;
00269         }
00270         return $real;
00271     }
00272 /**
00273 * Enter description here...
00274 *
00275 * @param unknown_type $results
00276 */
00277     function resultSet(&$results) {
00278         $this->results =& $results;
00279         $num_fields = odbc_num_fields($results);
00280         $this->map = array();
00281         $index = 0;
00282         $j = 0;
00283         while ($j < $num_fields) {
00284             $column = odbc_field_name($results, $j+1);
00285 
00286             if (strpos($column, '_dot_') !== false) {
00287                 list($table, $column) = explode('_dot_', $column);
00288                 $this->map[$index++] = array($table, $column);
00289             } else {
00290                 $this->map[$index++] = array(0, $column);
00291             }
00292             $j++;
00293         }
00294     }
00295 /**
00296 * Generates the fields list of an SQL query.
00297 *
00298 * @param Model $model
00299 * @param string $alias Alias tablename
00300 * @param mixed $fields
00301 * @return array
00302 */
00303     function fields(&$model, $alias = null, $fields = null, $quote = true) {
00304         if (empty($alias)) {
00305             $alias = $model->name;
00306         }
00307         if (!is_array($fields)) {
00308             if ($fields != null) {
00309                 $fields = array_map('trim', explode(',', $fields));
00310             } else {
00311                 foreach($model->tableToModel as $tableName => $modelName) {
00312                     foreach($this->__descriptions[$model->tablePrefix .$tableName] as $field => $type) {
00313                         $fields[] = $modelName .'.' .$field;
00314                     }
00315                 }
00316             }
00317         }
00318 
00319         $count = count($fields);
00320 
00321         if ($count >= 1 && $fields[0] != '*' && strpos($fields[0], 'COUNT(*)') === false) {
00322             for ($i = 0; $i < $count; $i++) {
00323                 if (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
00324                     $prepend = '';
00325                     if (strpos($fields[$i], 'DISTINCT') !== false) {
00326                         $prepend = 'DISTINCT ';
00327                         $fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i]));
00328                     }
00329 
00330                     if (strrpos($fields[$i], '.') === false) {
00331                         $fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '_dot_' . $fields[$i]);
00332                     } else {
00333                         $build = explode('.', $fields[$i]);
00334                         $fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '_dot_' . $build[1]);
00335                     }
00336                 }
00337             }
00338         }
00339         return $fields;
00340     }
00341 /**
00342  * Fetches the next row from the current result set
00343  *
00344  * @return unknown
00345  */
00346     function fetchResult() {
00347         if ($row = odbc_fetch_row($this->results)) {
00348             $resultRow = array();
00349             $numFields = odbc_num_fields($this->results);
00350             $i = 0;
00351             for($i = 0; $i < $numFields; $i++) {
00352                 list($table, $column) = $this->map[$i];
00353                 $resultRow[$table][$column] = odbc_result($this->results, $i + 1);
00354             }
00355             return $resultRow;
00356         }
00357         return false;
00358     }
00359 }
00360 ?>

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