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