mysqli_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  * MySQLi Database Adapter Class - MySQLi only works with PHP 5
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_mysqli_driver extends CI_DB {
00032 
00033         var $dbdriver = 'mysqli';
00034         
00035         // The character used for escaping
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 = ' RAND()'; // database specific random keyword
00045 
00046         /**
00047          * Whether to use the MySQL "delete hack" which allows the number
00048          * of affected rows to be shown. Uses a preg_replace when enabled,
00049          * adding a bit more processing to all queries.
00050          */     
00051         var $delete_hack = TRUE;
00052 
00053         // --------------------------------------------------------------------
00054 
00055         /**
00056          * Non-persistent database connection
00057          *
00058          * @access      private called by the base class
00059          * @return      resource
00060          */     
00061         function db_connect()
00062         {
00063                 return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port);
00064         }
00065 
00066         // --------------------------------------------------------------------
00067 
00068         /**
00069          * Persistent database connection
00070          *
00071          * @access      private called by the base class
00072          * @return      resource
00073          */     
00074         function db_pconnect()
00075         {
00076                 return $this->db_connect();
00077         }
00078         
00079         // --------------------------------------------------------------------
00080 
00081         /**
00082          * Select the database
00083          *
00084          * @access      private called by the base class
00085          * @return      resource
00086          */     
00087         function db_select()
00088         {
00089                 return @mysqli_select_db($this->conn_id, $this->database);
00090         }
00091 
00092         // --------------------------------------------------------------------
00093 
00094         /**
00095          * Set client character set
00096          *
00097          * @access      private
00098          * @param       string
00099          * @param       string
00100          * @return      resource
00101          */
00102         function _db_set_charset($charset, $collation)
00103         {
00104                 return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");
00105         }
00106 
00107         // --------------------------------------------------------------------
00108         
00109         /**
00110          * Version number query string
00111          *
00112          * @access      public
00113          * @return      string
00114          */
00115         function _version()
00116         {
00117                 return "SELECT version() AS ver";
00118         }
00119 
00120         // --------------------------------------------------------------------
00121 
00122         /**
00123          * Execute the query
00124          *
00125          * @access      private called by the base class
00126          * @param       string  an SQL query
00127          * @return      resource
00128          */     
00129         function _execute($sql)
00130         {
00131                 $sql = $this->_prep_query($sql);        
00132                 $result = @mysqli_query($this->conn_id, $sql);
00133                 return $result;
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                 // "DELETE FROM TABLE" returns 0 affected rows This hack modifies
00150                 // the query so that it returns the number of affected rows
00151                 if ($this->delete_hack === TRUE)
00152                 {
00153                         if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
00154                         {
00155                                 $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
00156                         }
00157                 }
00158                 
00159                 return $sql;
00160         }
00161 
00162         // --------------------------------------------------------------------
00163 
00164         /**
00165          * Begin Transaction
00166          *
00167          * @access      public
00168          * @return      bool            
00169          */     
00170         function trans_begin($test_mode = FALSE)
00171         {
00172                 if ( ! $this->trans_enabled)
00173                 {
00174                         return TRUE;
00175                 }
00176                 
00177                 // When transactions are nested we only begin/commit/rollback the outermost ones
00178                 if ($this->_trans_depth > 0)
00179                 {
00180                         return TRUE;
00181                 }
00182 
00183                 // Reset the transaction failure flag.
00184                 // If the $test_mode flag is set to TRUE transactions will be rolled back
00185                 // even if the queries produce a successful result.
00186                 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
00187 
00188                 $this->simple_query('SET AUTOCOMMIT=0');
00189                 $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
00190                 return TRUE;
00191         }
00192 
00193         // --------------------------------------------------------------------
00194 
00195         /**
00196          * Commit Transaction
00197          *
00198          * @access      public
00199          * @return      bool            
00200          */     
00201         function trans_commit()
00202         {
00203                 if ( ! $this->trans_enabled)
00204                 {
00205                         return TRUE;
00206                 }
00207 
00208                 // When transactions are nested we only begin/commit/rollback the outermost ones
00209                 if ($this->_trans_depth > 0)
00210                 {
00211                         return TRUE;
00212                 }
00213 
00214                 $this->simple_query('COMMIT');
00215                 $this->simple_query('SET AUTOCOMMIT=1');
00216                 return TRUE;
00217         }
00218 
00219         // --------------------------------------------------------------------
00220 
00221         /**
00222          * Rollback Transaction
00223          *
00224          * @access      public
00225          * @return      bool            
00226          */     
00227         function trans_rollback()
00228         {
00229                 if ( ! $this->trans_enabled)
00230                 {
00231                         return TRUE;
00232                 }
00233 
00234                 // When transactions are nested we only begin/commit/rollback the outermost ones
00235                 if ($this->_trans_depth > 0)
00236                 {
00237                         return TRUE;
00238                 }
00239 
00240                 $this->simple_query('ROLLBACK');
00241                 $this->simple_query('SET AUTOCOMMIT=1');
00242                 return TRUE;
00243         }
00244 
00245         // --------------------------------------------------------------------
00246 
00247         /**
00248          * Escape String
00249          *
00250          * @access      public
00251          * @param       string
00252          * @return      string
00253          */
00254         function escape_str($str)       
00255         {
00256                 if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id))
00257                 {
00258                         return mysqli_real_escape_string($this->conn_id, $str);
00259                 }
00260                 elseif (function_exists('mysql_escape_string'))
00261                 {
00262                         return mysql_escape_string($str);
00263                 }
00264                 else
00265                 {
00266                         return addslashes($str);
00267                 }
00268         }
00269                 
00270         // --------------------------------------------------------------------
00271 
00272         /**
00273          * Affected Rows
00274          *
00275          * @access      public
00276          * @return      integer
00277          */
00278         function affected_rows()
00279         {
00280                 return @mysqli_affected_rows($this->conn_id);
00281         }
00282         
00283         // --------------------------------------------------------------------
00284 
00285         /**
00286          * Insert ID
00287          *
00288          * @access      public
00289          * @return      integer
00290          */
00291         function insert_id()
00292         {
00293                 return @mysqli_insert_id($this->conn_id);
00294         }
00295 
00296         // --------------------------------------------------------------------
00297 
00298         /**
00299          * "Count All" query
00300          *
00301          * Generates a platform-specific query string that counts all records in
00302          * the specified database
00303          *
00304          * @access      public
00305          * @param       string
00306          * @return      string
00307          */
00308         function count_all($table = '')
00309         {
00310                 if ($table == '')
00311                         return '0';
00312                 
00313                 $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
00314                 
00315                 if ($query->num_rows() == 0)
00316                         return '0';
00317 
00318                 $row = $query->row();
00319                 return $row->numrows;
00320         }
00321 
00322         // --------------------------------------------------------------------
00323 
00324         /**
00325          * List table query
00326          *
00327          * Generates a platform-specific query string so that the table names can be fetched
00328          *
00329          * @access      private
00330          * @param       boolean
00331          * @return      string
00332          */
00333         function _list_tables($prefix_limit = FALSE)
00334         {
00335                 $sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;     
00336                 
00337                 if ($prefix_limit !== FALSE AND $this->dbprefix != '')
00338                 {
00339                         $sql .= " LIKE '".$this->dbprefix."%'";
00340                 }
00341                 
00342                 return $sql;
00343         }
00344 
00345         // --------------------------------------------------------------------
00346 
00347         /**
00348          * Show column query
00349          *
00350          * Generates a platform-specific query string so that the column names can be fetched
00351          *
00352          * @access      public
00353          * @param       string  the table name
00354          * @return      string
00355          */
00356         function _list_columns($table = '')
00357         {
00358                 return "SHOW COLUMNS FROM ".$table;
00359         }
00360 
00361         // --------------------------------------------------------------------
00362 
00363         /**
00364          * Field data query
00365          *
00366          * Generates a platform-specific query so that the column data can be retrieved
00367          *
00368          * @access      public
00369          * @param       string  the table name
00370          * @return      object
00371          */
00372         function _field_data($table)
00373         {
00374                 return "SELECT * FROM ".$table." LIMIT 1";
00375         }
00376 
00377         // --------------------------------------------------------------------
00378 
00379         /**
00380          * The error message string
00381          *
00382          * @access      private
00383          * @return      string
00384          */
00385         function _error_message()
00386         {
00387                 return mysqli_error($this->conn_id);
00388         }
00389         
00390         // --------------------------------------------------------------------
00391 
00392         /**
00393          * The error message number
00394          *
00395          * @access      private
00396          * @return      integer
00397          */
00398         function _error_number()
00399         {
00400                 return mysqli_errno($this->conn_id);
00401         }
00402 
00403         // --------------------------------------------------------------------
00404 
00405         /**
00406          * Escape the SQL Identifiers
00407          *
00408          * This function escapes column and table names
00409          *
00410          * @access      private
00411          * @param       string
00412          * @return      string
00413          */
00414         function _escape_identifiers($item)
00415         {
00416                 if ($this->_escape_char == '')
00417                 {
00418                         return $item;
00419                 }
00420         
00421                 if (strpos($item, '.') !== FALSE)
00422                 {
00423                         $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    
00424                 }
00425                 else
00426                 {
00427                         $str = $this->_escape_char.$item.$this->_escape_char;
00428                 }
00429                 
00430                 // remove duplicates if the user already included the escape
00431                 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
00432         }
00433                         
00434         // --------------------------------------------------------------------
00435 
00436         /**
00437          * From Tables
00438          *
00439          * This function implicitly groups FROM tables so there is no confusion
00440          * about operator precedence in harmony with SQL standards
00441          *
00442          * @access      public
00443          * @param       type
00444          * @return      type
00445          */
00446         function _from_tables($tables)
00447         {
00448                 if ( ! is_array($tables))
00449                 {
00450                         $tables = array($tables);
00451                 }
00452                 
00453                 return '('.implode(', ', $tables).')';
00454         }
00455 
00456         // --------------------------------------------------------------------
00457         
00458         /**
00459          * Insert statement
00460          *
00461          * Generates a platform-specific insert string from the supplied data
00462          *
00463          * @access      public
00464          * @param       string  the table name
00465          * @param       array   the insert keys
00466          * @param       array   the insert values
00467          * @return      string
00468          */
00469         function _insert($table, $keys, $values)
00470         {       
00471                 return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
00472         }
00473         
00474         // --------------------------------------------------------------------
00475 
00476         /**
00477          * Update statement
00478          *
00479          * Generates a platform-specific update string from the supplied data
00480          *
00481          * @access      public
00482          * @param       string  the table name
00483          * @param       array   the update data
00484          * @param       array   the where clause
00485          * @param       array   the orderby clause
00486          * @param       array   the limit clause
00487          * @return      string
00488          */
00489         function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
00490         {
00491                 foreach($values as $key => $val)
00492                 {
00493                         $valstr[] = $key." = ".$val;
00494                 }
00495                 
00496                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
00497                 
00498                 $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
00499         
00500                 $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
00501                 
00502                 $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
00503                 
00504                 $sql .= $orderby.$limit;
00505                 
00506                 return $sql;
00507         }
00508 
00509         
00510         // --------------------------------------------------------------------
00511 
00512         /**
00513          * Truncate statement
00514          *
00515          * Generates a platform-specific truncate string from the supplied data
00516          * If the database does not support the truncate() command
00517          * This function maps to "DELETE FROM table"
00518          *
00519          * @access      public
00520          * @param       string  the table name
00521          * @return      string
00522          */     
00523         function _truncate($table)
00524         {
00525                 return "TRUNCATE ".$table;
00526         }
00527         
00528         // --------------------------------------------------------------------
00529 
00530         /**
00531          * Delete statement
00532          *
00533          * Generates a platform-specific delete string from the supplied data
00534          *
00535          * @access      public
00536          * @param       string  the table name
00537          * @param       array   the where clause
00538          * @param       string  the limit clause
00539          * @return      string
00540          */     
00541         function _delete($table, $where = array(), $like = array(), $limit = FALSE)
00542         {
00543                 $conditions = '';
00544 
00545                 if (count($where) > 0 OR count($like) > 0)
00546                 {
00547                         $conditions = "\nWHERE ";
00548                         $conditions .= implode("\n", $this->ar_where);
00549 
00550                         if (count($where) > 0 && count($like) > 0)
00551                         {
00552                                 $conditions .= " AND ";
00553                         }
00554                         $conditions .= implode("\n", $like);
00555                 }
00556 
00557                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
00558         
00559                 return "DELETE FROM ".$table.$conditions.$limit;
00560         }
00561 
00562         // --------------------------------------------------------------------
00563 
00564         /**
00565          * Limit string
00566          *
00567          * Generates a platform-specific LIMIT clause
00568          *
00569          * @access      public
00570          * @param       string  the sql query string
00571          * @param       integer the number of rows to limit the query to
00572          * @param       integer the offset value
00573          * @return      string
00574          */
00575         function _limit($sql, $limit, $offset)
00576         {       
00577                 $sql .= "LIMIT ".$limit;
00578         
00579                 if ($offset > 0)
00580                 {
00581                         $sql .= " OFFSET ".$offset;
00582                 }
00583                 
00584                 return $sql;
00585         }
00586 
00587         // --------------------------------------------------------------------
00588 
00589         /**
00590          * Close DB Connection
00591          *
00592          * @access      public
00593          * @param       resource
00594          * @return      void
00595          */
00596         function _close($conn_id)
00597         {
00598                 @mysqli_close($conn_id);
00599         }
00600 
00601 
00602 }
00603 
00604 
00605 /* End of file mysqli_driver.php */
00606 /* Location: ./system/database/drivers/mysqli/mysqli_driver.php */