odbc_driver.php

Go to the documentation of this file.
00001 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
00002 /**
00003  * CodeIgniter
00004  *
00005  * An open source application development framework for PHP 4.3.2 or newer
00006  *
00007  * @package             CodeIgniter
00008  * @author              ExpressionEngine Dev Team
00009  * @copyright   Copyright (c) 2008, EllisLab, Inc.
00010  * @license             http://codeigniter.com/user_guide/license.html
00011  * @link                http://codeigniter.com
00012  * @since               Version 1.0
00013  * @filesource
00014  */
00015 
00016 // ------------------------------------------------------------------------
00017 
00018 /**
00019  * ODBC Database Adapter Class
00020  *
00021  * Note: _DB is an extender class that the app controller
00022  * creates dynamically based on whether the active record
00023  * class is being used or not.
00024  *
00025  * @package             CodeIgniter
00026  * @subpackage  Drivers
00027  * @category    Database
00028  * @author              ExpressionEngine Dev Team
00029  * @link                http://codeigniter.com/user_guide/database/
00030  */
00031 class CI_DB_odbc_driver extends CI_DB {
00032 
00033         var $dbdriver = 'odbc';
00034         
00035         // the character used to excape - not necessary for ODBC
00036         var $_escape_char = '';
00037 
00038         /**
00039          * The syntax to count rows is slightly different across different
00040          * database engines, so this string appears in each driver and is
00041          * used for the count_all() and count_all_results() functions.
00042          */
00043         var $_count_string = "SELECT COUNT(*) AS ";
00044         var $_random_keyword;
00045 
00046 
00047         function CI_DB_odbc_driver($params)
00048         {
00049                 parent::CI_DB($params);
00050                 
00051                 $this->_random_keyword = ' RND('.time().')'; // database specific random keyword
00052         }
00053 
00054         /**
00055          * Non-persistent database connection
00056          *
00057          * @access      private called by the base class
00058          * @return      resource
00059          */     
00060         function db_connect()
00061         {
00062                 return @odbc_connect($this->hostname, $this->username, $this->password);
00063         }
00064         
00065         // --------------------------------------------------------------------
00066 
00067         /**
00068          * Persistent database connection
00069          *
00070          * @access      private called by the base class
00071          * @return      resource
00072          */     
00073         function db_pconnect()
00074         {
00075                 return @odbc_pconnect($this->hostname, $this->username, $this->password);
00076         }
00077         
00078         // --------------------------------------------------------------------
00079 
00080         /**
00081          * Select the database
00082          *
00083          * @access      private called by the base class
00084          * @return      resource
00085          */     
00086         function db_select()
00087         {
00088                 // Not needed for ODBC
00089                 return TRUE;
00090         }
00091 
00092         // --------------------------------------------------------------------
00093 
00094         /**
00095          * Set client character set
00096          *
00097          * @access      public
00098          * @param       string
00099          * @param       string
00100          * @return      resource
00101          */
00102         function db_set_charset($charset, $collation)
00103         {
00104                 // @todo - add support if needed
00105                 return TRUE;
00106         }
00107 
00108         // --------------------------------------------------------------------
00109         
00110         /**
00111          * Version number query string
00112          *
00113          * @access      public
00114          * @return      string
00115          */
00116         function _version()
00117         {
00118                 return "SELECT version() AS ver";
00119         }
00120 
00121         // --------------------------------------------------------------------
00122 
00123         /**
00124          * Execute the query
00125          *
00126          * @access      private called by the base class
00127          * @param       string  an SQL query
00128          * @return      resource
00129          */     
00130         function _execute($sql)
00131         {
00132                 $sql = $this->_prep_query($sql);
00133                 return @odbc_exec($this->conn_id, $sql);
00134         }
00135         
00136         // --------------------------------------------------------------------
00137 
00138         /**
00139          * Prep the query
00140          *
00141          * If needed, each database adapter can prep the query string
00142          *
00143          * @access      private called by execute()
00144          * @param       string  an SQL query
00145          * @return      string
00146          */     
00147         function _prep_query($sql)
00148         {
00149                 return $sql;
00150         }
00151 
00152         // --------------------------------------------------------------------
00153 
00154         /**
00155          * Begin Transaction
00156          *
00157          * @access      public
00158          * @return      bool            
00159          */     
00160         function trans_begin($test_mode = FALSE)
00161         {
00162                 if ( ! $this->trans_enabled)
00163                 {
00164                         return TRUE;
00165                 }
00166                 
00167                 // When transactions are nested we only begin/commit/rollback the outermost ones
00168                 if ($this->_trans_depth > 0)
00169                 {
00170                         return TRUE;
00171                 }
00172 
00173                 // Reset the transaction failure flag.
00174                 // If the $test_mode flag is set to TRUE transactions will be rolled back
00175                 // even if the queries produce a successful result.
00176                 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
00177 
00178                 return odbc_autocommit($this->conn_id, FALSE);
00179         }
00180 
00181         // --------------------------------------------------------------------
00182 
00183         /**
00184          * Commit Transaction
00185          *
00186          * @access      public
00187          * @return      bool            
00188          */     
00189         function trans_commit()
00190         {
00191                 if ( ! $this->trans_enabled)
00192                 {
00193                         return TRUE;
00194                 }
00195 
00196                 // When transactions are nested we only begin/commit/rollback the outermost ones
00197                 if ($this->_trans_depth > 0)
00198                 {
00199                         return TRUE;
00200                 }
00201 
00202                 $ret = odbc_commit($this->conn_id);
00203                 odbc_autocommit($this->conn_id, TRUE);
00204                 return $ret;
00205         }
00206 
00207         // --------------------------------------------------------------------
00208 
00209         /**
00210          * Rollback Transaction
00211          *
00212          * @access      public
00213          * @return      bool            
00214          */     
00215         function trans_rollback()
00216         {
00217                 if ( ! $this->trans_enabled)
00218                 {
00219                         return TRUE;
00220                 }
00221 
00222                 // When transactions are nested we only begin/commit/rollback the outermost ones
00223                 if ($this->_trans_depth > 0)
00224                 {
00225                         return TRUE;
00226                 }
00227 
00228                 $ret = odbc_rollback($this->conn_id);
00229                 odbc_autocommit($this->conn_id, TRUE);
00230                 return $ret;
00231         }
00232 
00233         // --------------------------------------------------------------------
00234 
00235         /**
00236          * Escape String
00237          *
00238          * @access      public
00239          * @param       string
00240          * @return      string
00241          */
00242         function escape_str($str)       
00243         {
00244                 // Access the CI object
00245                 $CI =& get_instance();
00246 
00247                 // ODBC doesn't require escaping
00248                 return $CI->_remove_invisible_characters($str);
00249         }
00250         
00251         // --------------------------------------------------------------------
00252 
00253         /**
00254          * Affected Rows
00255          *
00256          * @access      public
00257          * @return      integer
00258          */
00259         function affected_rows()
00260         {
00261                 return @odbc_num_rows($this->conn_id);
00262         }
00263         
00264         // --------------------------------------------------------------------
00265 
00266         /**
00267          * Insert ID
00268          *
00269          * @access      public
00270          * @return      integer
00271          */
00272         function insert_id()
00273         {
00274                 return @odbc_insert_id($this->conn_id);
00275         }
00276 
00277         // --------------------------------------------------------------------
00278 
00279         /**
00280          * "Count All" query
00281          *
00282          * Generates a platform-specific query string that counts all records in
00283          * the specified database
00284          *
00285          * @access      public
00286          * @param       string
00287          * @return      string
00288          */
00289         function count_all($table = '')
00290         {
00291                 if ($table == '')
00292                         return '0';
00293         
00294                 $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
00295         
00296                 if ($query->num_rows() == 0)
00297                         return '0';
00298 
00299                 $row = $query->row();
00300                 return $row->numrows;
00301         }
00302 
00303         // --------------------------------------------------------------------
00304 
00305         /**
00306          * Show table query
00307          *
00308          * Generates a platform-specific query string so that the table names can be fetched
00309          *
00310          * @access      private
00311          * @param       boolean
00312          * @return      string
00313          */
00314         function _list_tables($prefix_limit = FALSE)
00315         {
00316                 $sql = "SHOW TABLES FROM `".$this->database."`";
00317 
00318                 if ($prefix_limit !== FALSE AND $this->dbprefix != '')
00319                 {
00320                         //$sql .= " LIKE '".$this->dbprefix."%'";
00321                         return FALSE; // not currently supported
00322                 }
00323                 
00324                 return $sql;
00325         }
00326         
00327         // --------------------------------------------------------------------
00328 
00329         /**
00330          * Show column query
00331          *
00332          * Generates a platform-specific query string so that the column names can be fetched
00333          *
00334          * @access      public
00335          * @param       string  the table name
00336          * @return      string
00337          */
00338         function _list_columns($table = '')
00339         {
00340                 return "SHOW COLUMNS FROM ".$table;
00341         }
00342 
00343         // --------------------------------------------------------------------
00344 
00345         /**
00346          * Field data query
00347          *
00348          * Generates a platform-specific query so that the column data can be retrieved
00349          *
00350          * @access      public
00351          * @param       string  the table name
00352          * @return      object
00353          */
00354         function _field_data($table)
00355         {
00356                 return "SELECT TOP 1 FROM ".$table;
00357         }
00358 
00359         // --------------------------------------------------------------------
00360 
00361         /**
00362          * The error message string
00363          *
00364          * @access      private
00365          * @return      string
00366          */
00367         function _error_message()
00368         {
00369                 return odbc_errormsg($this->conn_id);
00370         }
00371         
00372         // --------------------------------------------------------------------
00373 
00374         /**
00375          * The error message number
00376          *
00377          * @access      private
00378          * @return      integer
00379          */
00380         function _error_number()
00381         {
00382                 return odbc_error($this->conn_id);
00383         }
00384 
00385         // --------------------------------------------------------------------
00386 
00387         /**
00388          * Escape the SQL Identifiers
00389          *
00390          * This function escapes column and table names
00391          *
00392          * @access      private
00393          * @param       string
00394          * @return      string
00395          */
00396         function _escape_identifiers($item)
00397         {
00398                 if ($this->_escape_char == '')
00399                 {
00400                         return $item;
00401                 }
00402         
00403                 if (strpos($item, '.') !== FALSE)
00404                 {
00405                         $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    
00406                 }
00407                 else
00408                 {
00409                         $str = $this->_escape_char.$item.$this->_escape_char;
00410                 }
00411                 
00412                 // remove duplicates if the user already included the escape
00413                 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
00414         }
00415                         
00416         // --------------------------------------------------------------------
00417 
00418         /**
00419          * From Tables
00420          *
00421          * This function implicitly groups FROM tables so there is no confusion
00422          * about operator precedence in harmony with SQL standards
00423          *
00424          * @access      public
00425          * @param       type
00426          * @return      type
00427          */
00428         function _from_tables($tables)
00429         {
00430                 if ( ! is_array($tables))
00431                 {
00432                         $tables = array($tables);
00433                 }
00434                 
00435                 return '('.implode(', ', $tables).')';
00436         }
00437 
00438         // --------------------------------------------------------------------
00439         
00440         /**
00441          * Insert statement
00442          *
00443          * Generates a platform-specific insert string from the supplied data
00444          *
00445          * @access      public
00446          * @param       string  the table name
00447          * @param       array   the insert keys
00448          * @param       array   the insert values
00449          * @return      string
00450          */
00451         function _insert($table, $keys, $values)
00452         {       
00453                 return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
00454         }
00455         
00456         // --------------------------------------------------------------------
00457 
00458         /**
00459          * Update statement
00460          *
00461          * Generates a platform-specific update string from the supplied data
00462          *
00463          * @access      public
00464          * @param       string  the table name
00465          * @param       array   the update data
00466          * @param       array   the where clause
00467          * @param       array   the orderby clause
00468          * @param       array   the limit clause
00469          * @return      string
00470          */
00471         function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
00472         {
00473                 foreach($values as $key => $val)
00474                 {
00475                         $valstr[] = $key." = ".$val;
00476                 }
00477                 
00478                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
00479                 
00480                 $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
00481         
00482                 $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
00483 
00484                 $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
00485 
00486                 $sql .= $orderby.$limit;
00487                 
00488                 return $sql;
00489         }
00490 
00491         
00492         // --------------------------------------------------------------------
00493 
00494         /**
00495          * Truncate statement
00496          *
00497          * Generates a platform-specific truncate string from the supplied data
00498          * If the database does not support the truncate() command
00499          * This function maps to "DELETE FROM table"
00500          *
00501          * @access      public
00502          * @param       string  the table name
00503          * @return      string
00504          */     
00505         function _truncate($table)
00506         {
00507                 return $this->_delete($table);
00508         }
00509         
00510         // --------------------------------------------------------------------
00511 
00512         /**
00513          * Delete statement
00514          *
00515          * Generates a platform-specific delete string from the supplied data
00516          *
00517          * @access      public
00518          * @param       string  the table name
00519          * @param       array   the where clause
00520          * @param       string  the limit clause
00521          * @return      string
00522          */     
00523         function _delete($table, $where = array(), $like = array(), $limit = FALSE)
00524         {
00525                 $conditions = '';
00526 
00527                 if (count($where) > 0 OR count($like) > 0)
00528                 {
00529                         $conditions = "\nWHERE ";
00530                         $conditions .= implode("\n", $this->ar_where);
00531 
00532                         if (count($where) > 0 && count($like) > 0)
00533                         {
00534                                 $conditions .= " AND ";
00535                         }
00536                         $conditions .= implode("\n", $like);
00537                 }
00538 
00539                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
00540         
00541                 return "DELETE FROM ".$table.$conditions.$limit;
00542         }
00543 
00544         // --------------------------------------------------------------------
00545 
00546         /**
00547          * Limit string
00548          *
00549          * Generates a platform-specific LIMIT clause
00550          *
00551          * @access      public
00552          * @param       string  the sql query string
00553          * @param       integer the number of rows to limit the query to
00554          * @param       integer the offset value
00555          * @return      string
00556          */
00557         function _limit($sql, $limit, $offset)
00558         {
00559                 // Does ODBC doesn't use the LIMIT clause?
00560                 return $sql;
00561         }
00562 
00563         // --------------------------------------------------------------------
00564 
00565         /**
00566          * Close DB Connection
00567          *
00568          * @access      public
00569          * @param       resource
00570          * @return      void
00571          */
00572         function _close($conn_id)
00573         {
00574                 @odbc_close($conn_id);
00575         }
00576 
00577         
00578 }
00579 
00580 
00581 
00582 /* End of file odbc_driver.php */
00583 /* Location: ./system/database/drivers/odbc/odbc_driver.php */