Guest User

Untitled

a guest
Nov 17th, 2013
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.76 KB | None | 0 0
  1. <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3.  * CodeIgniter
  4.  *
  5.  * An open source application development framework for PHP 5.1.6 or newer
  6.  *
  7.  * @package     CodeIgniter
  8.  * @author      ExpressionEngine Dev Team
  9.  * @copyright   Copyright (c) 2008 - 2011, EllisLab, Inc.
  10.  * @license     http://codeigniter.com/user_guide/license.html
  11.  * @link        http://codeigniter.com
  12.  * @since       Version 1.0
  13.  * @filesource
  14.  */
  15.  
  16. // ------------------------------------------------------------------------
  17.  
  18. /**
  19.  * MySQLi Database Adapter Class - MySQLi only works with PHP 5
  20.  *
  21.  * Note: _DB is an extender class that the app controller
  22.  * creates dynamically based on whether the active record
  23.  * class is being used or not.
  24.  *
  25.  * @package     CodeIgniter
  26.  * @subpackage  Drivers
  27.  * @category    Database
  28.  * @author      ExpressionEngine Dev Team
  29.  * @link        http://codeigniter.com/user_guide/database/
  30.  */
  31. class CI_DB_mysqli_driver extends CI_DB {
  32.  
  33.     var $dbdriver = 'mysqli';
  34.  
  35.     // The character used for escaping
  36.     var $_escape_char = '`';
  37.  
  38.     // clause and character used for LIKE escape sequences - not used in MySQL
  39.     var $_like_escape_str = '';
  40.     var $_like_escape_chr = '';
  41.  
  42.     /**
  43.      * The syntax to count rows is slightly different across different
  44.      * database engines, so this string appears in each driver and is
  45.      * used for the count_all() and count_all_results() functions.
  46.      */
  47.     var $_count_string = "SELECT COUNT(*) AS ";
  48.     var $_random_keyword = ' RAND()'; // database specific random keyword
  49.  
  50.     /**
  51.      * Whether to use the MySQL "delete hack" which allows the number
  52.      * of affected rows to be shown. Uses a preg_replace when enabled,
  53.      * adding a bit more processing to all queries.
  54.      */
  55.     var $delete_hack = TRUE;
  56.  
  57.     // whether SET NAMES must be used to set the character set
  58.     var $use_set_names;
  59.    
  60.     // --------------------------------------------------------------------
  61.  
  62.     /**
  63.      * Non-persistent database connection
  64.      *
  65.      * @access  private called by the base class
  66.      * @return  resource
  67.      */
  68.     function db_connect()
  69.     {
  70.         if ($this->port != '')
  71.         {
  72.             return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port);
  73.         }
  74.         else
  75.         {
  76.             return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database);
  77.         }
  78.  
  79.     }
  80.  
  81.     // --------------------------------------------------------------------
  82.  
  83.     /**
  84.      * Persistent database connection
  85.      *
  86.      * @access  private called by the base class
  87.      * @return  resource
  88.      */
  89.     function db_pconnect()
  90.     {
  91.         return $this->db_connect();
  92.     }
  93.  
  94.     // --------------------------------------------------------------------
  95.  
  96.     /**
  97.      * Reconnect
  98.      *
  99.      * Keep / reestablish the db connection if no queries have been
  100.      * sent for a length of time exceeding the server's idle timeout
  101.      *
  102.      * @access  public
  103.      * @return  void
  104.      */
  105.     function reconnect()
  106.     {
  107.         if (mysqli_ping($this->conn_id) === FALSE)
  108.         {
  109.             $this->conn_id = FALSE;
  110.         }
  111.     }
  112.  
  113.     // --------------------------------------------------------------------
  114.  
  115.     /**
  116.      * Select the database
  117.      *
  118.      * @access  private called by the base class
  119.      * @return  resource
  120.      */
  121.     function db_select()
  122.     {
  123.         return @mysqli_select_db($this->conn_id, $this->database);
  124.     }
  125.  
  126.     // --------------------------------------------------------------------
  127.  
  128.     /**
  129.      * Set client character set
  130.      *
  131.      * @access  private
  132.      * @param   string
  133.      * @param   string
  134.      * @return  resource
  135.      */
  136.     function _db_set_charset($charset, $collation)
  137.     {
  138.         if ( ! isset($this->use_set_names))
  139.         {
  140.             // mysqli_set_charset() requires MySQL >= 5.0.7, use SET NAMES as fallback
  141.             $this->use_set_names = (version_compare(mysqli_get_server_info($this->conn_id), '5.0.7', '>=')) ? FALSE : TRUE;
  142.         }
  143.  
  144.         if ($this->use_set_names === TRUE)
  145.         {
  146.             return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");
  147.         }
  148.         else
  149.         {
  150.             return @mysqli_set_charset($this->conn_id, $charset);
  151.         }
  152.     }
  153.  
  154.     // --------------------------------------------------------------------
  155.  
  156.     /**
  157.      * Version number query string
  158.      *
  159.      * @access  public
  160.      * @return  string
  161.      */
  162.     function _version()
  163.     {
  164.         return "SELECT version() AS ver";
  165.     }
  166.  
  167.     // --------------------------------------------------------------------
  168.  
  169.     /**
  170.      * Execute the query
  171.      *
  172.      * @access  private called by the base class
  173.      * @param   string  an SQL query
  174.      * @return  resource
  175.      */
  176.     function _execute($sql)
  177.     {
  178.         $sql = $this->_prep_query($sql);
  179.         $result = @mysqli_query($this->conn_id, $sql);
  180.         return $result;
  181.     }
  182.  
  183.     // --------------------------------------------------------------------
  184.  
  185.     /**
  186.      * Prep the query
  187.      *
  188.      * If needed, each database adapter can prep the query string
  189.      *
  190.      * @access  private called by execute()
  191.      * @param   string  an SQL query
  192.      * @return  string
  193.      */
  194.     function _prep_query($sql)
  195.     {
  196.         // "DELETE FROM TABLE" returns 0 affected rows This hack modifies
  197.         // the query so that it returns the number of affected rows
  198.         if ($this->delete_hack === TRUE)
  199.         {
  200.             if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
  201.             {
  202.                 $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
  203.             }
  204.         }
  205.  
  206.         return $sql;
  207.     }
  208.  
  209.     // --------------------------------------------------------------------
  210.  
  211.     /**
  212.      * Begin Transaction
  213.      *
  214.      * @access  public
  215.      * @return  bool
  216.      */
  217.     function trans_begin($test_mode = FALSE)
  218.     {
  219.         if ( ! $this->trans_enabled)
  220.         {
  221.             return TRUE;
  222.         }
  223.  
  224.         // When transactions are nested we only begin/commit/rollback the outermost ones
  225.         if ($this->_trans_depth > 0)
  226.         {
  227.             return TRUE;
  228.         }
  229.  
  230.         // Reset the transaction failure flag.
  231.         // If the $test_mode flag is set to TRUE transactions will be rolled back
  232.         // even if the queries produce a successful result.
  233.         $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
  234.  
  235.         $this->simple_query('SET AUTOCOMMIT=0');
  236.         $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
  237.         return TRUE;
  238.     }
  239.  
  240.     // --------------------------------------------------------------------
  241.  
  242.     /**
  243.      * Commit Transaction
  244.      *
  245.      * @access  public
  246.      * @return  bool
  247.      */
  248.     function trans_commit()
  249.     {
  250.         if ( ! $this->trans_enabled)
  251.         {
  252.             return TRUE;
  253.         }
  254.  
  255.         // When transactions are nested we only begin/commit/rollback the outermost ones
  256.         if ($this->_trans_depth > 0)
  257.         {
  258.             return TRUE;
  259.         }
  260.  
  261.         $this->simple_query('COMMIT');
  262.         $this->simple_query('SET AUTOCOMMIT=1');
  263.         return TRUE;
  264.     }
  265.  
  266.     // --------------------------------------------------------------------
  267.  
  268.     /**
  269.      * Rollback Transaction
  270.      *
  271.      * @access  public
  272.      * @return  bool
  273.      */
  274.     function trans_rollback()
  275.     {
  276.         if ( ! $this->trans_enabled)
  277.         {
  278.             return TRUE;
  279.         }
  280.  
  281.         // When transactions are nested we only begin/commit/rollback the outermost ones
  282.         if ($this->_trans_depth > 0)
  283.         {
  284.             return TRUE;
  285.         }
  286.  
  287.         $this->simple_query('ROLLBACK');
  288.         $this->simple_query('SET AUTOCOMMIT=1');
  289.         return TRUE;
  290.     }
  291.  
  292.     // --------------------------------------------------------------------
  293.  
  294.     /**
  295.      * Escape String
  296.      *
  297.      * @access  public
  298.      * @param   string
  299.      * @param   bool    whether or not the string will be used in a LIKE condition
  300.      * @return  string
  301.      */
  302.     function escape_str($str, $like = FALSE)
  303.     {
  304.         if (is_array($str))
  305.         {
  306.             foreach ($str as $key => $val)
  307.             {
  308.                 $str[$key] = $this->escape_str($val, $like);
  309.             }
  310.  
  311.             return $str;
  312.         }
  313.  
  314.         if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id))
  315.         {
  316.             $str = mysqli_real_escape_string($this->conn_id, $str);
  317.         }
  318.         elseif (function_exists('mysql_escape_string'))
  319.         {
  320.             $str = mysql_escape_string($str);
  321.         }
  322.         else
  323.         {
  324.             $str = addslashes($str);
  325.         }
  326.  
  327.         // escape LIKE condition wildcards
  328.         if ($like === TRUE)
  329.         {
  330.             $str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
  331.         }
  332.  
  333.         return $str;
  334.     }
  335.  
  336.     // --------------------------------------------------------------------
  337.  
  338.     /**
  339.      * Affected Rows
  340.      *
  341.      * @access  public
  342.      * @return  integer
  343.      */
  344.     function affected_rows()
  345.     {
  346.         return @mysqli_affected_rows($this->conn_id);
  347.     }
  348.  
  349.     // --------------------------------------------------------------------
  350.  
  351.     /**
  352.      * Insert ID
  353.      *
  354.      * @access  public
  355.      * @return  integer
  356.      */
  357.     function insert_id()
  358.     {
  359.         return @mysqli_insert_id($this->conn_id);
  360.     }
  361.  
  362.     // --------------------------------------------------------------------
  363.  
  364.     /**
  365.      * "Count All" query
  366.      *
  367.      * Generates a platform-specific query string that counts all records in
  368.      * the specified database
  369.      *
  370.      * @access  public
  371.      * @param   string
  372.      * @return  string
  373.      */
  374.     function count_all($table = '')
  375.     {
  376.         if ($table == '')
  377.         {
  378.             return 0;
  379.         }
  380.  
  381.         $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
  382.  
  383.         if ($query->num_rows() == 0)
  384.         {
  385.             return 0;
  386.         }
  387.  
  388.         $row = $query->row();
  389.         $this->_reset_select();
  390.         return (int) $row->numrows;
  391.     }
  392.  
  393.     // --------------------------------------------------------------------
  394.  
  395.     /**
  396.      * List table query
  397.      *
  398.      * Generates a platform-specific query string so that the table names can be fetched
  399.      *
  400.      * @access  private
  401.      * @param   boolean
  402.      * @return  string
  403.      */
  404.     function _list_tables($prefix_limit = FALSE)
  405.     {
  406.         $sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;
  407.  
  408.         if ($prefix_limit !== FALSE AND $this->dbprefix != '')
  409.         {
  410.             $sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%'";
  411.         }
  412.  
  413.         return $sql;
  414.     }
  415.  
  416.     // --------------------------------------------------------------------
  417.  
  418.     /**
  419.      * Show column query
  420.      *
  421.      * Generates a platform-specific query string so that the column names can be fetched
  422.      *
  423.      * @access  public
  424.      * @param   string  the table name
  425.      * @return  string
  426.      */
  427.     function _list_columns($table = '')
  428.     {
  429.         return "SHOW COLUMNS FROM ".$this->_protect_identifiers($table, TRUE, NULL, FALSE);
  430.     }
  431.  
  432.     // --------------------------------------------------------------------
  433.  
  434.     /**
  435.      * Field data query
  436.      *
  437.      * Generates a platform-specific query so that the column data can be retrieved
  438.      *
  439.      * @access  public
  440.      * @param   string  the table name
  441.      * @return  object
  442.      */
  443.     function _field_data($table)
  444.     {
  445.         return "DESCRIBE ".$table;
  446.     }
  447.  
  448.     // --------------------------------------------------------------------
  449.  
  450.     /**
  451.      * The error message string
  452.      *
  453.      * @access  private
  454.      * @return  string
  455.      */
  456.     function _error_message()
  457.     {
  458.         return mysqli_error($this->conn_id);
  459.     }
  460.  
  461.     // --------------------------------------------------------------------
  462.  
  463.     /**
  464.      * The error message number
  465.      *
  466.      * @access  private
  467.      * @return  integer
  468.      */
  469.     function _error_number()
  470.     {
  471.         return mysqli_errno($this->conn_id);
  472.     }
  473.  
  474.     // --------------------------------------------------------------------
  475.  
  476.     /**
  477.      * Escape the SQL Identifiers
  478.      *
  479.      * This function escapes column and table names
  480.      *
  481.      * @access  private
  482.      * @param   string
  483.      * @return  string
  484.      */
  485.     function _escape_identifiers($item)
  486.     {
  487.         if ($this->_escape_char == '')
  488.         {
  489.             return $item;
  490.         }
  491.  
  492.         foreach ($this->_reserved_identifiers as $id)
  493.         {
  494.             if (strpos($item, '.'.$id) !== FALSE)
  495.             {
  496.                 $str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
  497.  
  498.                 // remove duplicates if the user already included the escape
  499.                 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
  500.             }
  501.         }
  502.  
  503.         if (strpos($item, '.') !== FALSE)
  504.         {
  505.             $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
  506.         }
  507.         else
  508.         {
  509.             $str = $this->_escape_char.$item.$this->_escape_char;
  510.         }
  511.  
  512.         // remove duplicates if the user already included the escape
  513.         return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
  514.     }
  515.  
  516.     // --------------------------------------------------------------------
  517.  
  518.     /**
  519.      * From Tables
  520.      *
  521.      * This function implicitly groups FROM tables so there is no confusion
  522.      * about operator precedence in harmony with SQL standards
  523.      *
  524.      * @access  public
  525.      * @param   type
  526.      * @return  type
  527.      */
  528.     function _from_tables($tables)
  529.     {
  530.         if ( ! is_array($tables))
  531.         {
  532.             $tables = array($tables);
  533.         }
  534.  
  535.         return '('.implode(', ', $tables).')';
  536.     }
  537.  
  538.     // --------------------------------------------------------------------
  539.  
  540.     /**
  541.      * Insert statement
  542.      *
  543.      * Generates a platform-specific insert string from the supplied data
  544.      *
  545.      * @access  public
  546.      * @param   string  the table name
  547.      * @param   array   the insert keys
  548.      * @param   array   the insert values
  549.      * @return  string
  550.      */
  551.     function _insert($table, $keys, $values)
  552.     {
  553.         return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
  554.     }
  555.  
  556.     // --------------------------------------------------------------------
  557.  
  558.     /**
  559.      * Insert_batch statement
  560.      *
  561.      * Generates a platform-specific insert string from the supplied data
  562.      *
  563.      * @access  public
  564.      * @param   string  the table name
  565.      * @param   array   the insert keys
  566.      * @param   array   the insert values
  567.      * @return  string
  568.      */
  569.     function _insert_batch($table, $keys, $values)
  570.     {
  571.         return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
  572.     }
  573.  
  574.     // --------------------------------------------------------------------
  575.  
  576.  
  577.     /**
  578.      * Replace statement
  579.      *
  580.      * Generates a platform-specific replace string from the supplied data
  581.      *
  582.      * @access  public
  583.      * @param   string  the table name
  584.      * @param   array   the insert keys
  585.      * @param   array   the insert values
  586.      * @return  string
  587.      */
  588.     function _replace($table, $keys, $values)
  589.     {
  590.         return "REPLACE INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
  591.     }
  592.    
  593.     // --------------------------------------------------------------------
  594.  
  595.     /**
  596.      * Update statement
  597.      *
  598.      * Generates a platform-specific update string from the supplied data
  599.      *
  600.      * @access  public
  601.      * @param   string  the table name
  602.      * @param   array   the update data
  603.      * @param   array   the where clause
  604.      * @param   array   the orderby clause
  605.      * @param   array   the limit clause
  606.      * @return  string
  607.      */
  608.     function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
  609.     {
  610.         foreach ($values as $key => $val)
  611.         {
  612.             $valstr[] = $key." = ".$val;
  613.         }
  614.  
  615.         $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
  616.  
  617.         $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
  618.  
  619.         $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
  620.  
  621.         $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
  622.  
  623.         $sql .= $orderby.$limit;
  624.  
  625.         return $sql;
  626.     }
  627.  
  628.     // --------------------------------------------------------------------
  629.  
  630.     /**
  631.      * Update_Batch statement
  632.      *
  633.      * Generates a platform-specific batch update string from the supplied data
  634.      *
  635.      * @access  public
  636.      * @param   string  the table name
  637.      * @param   array   the update data
  638.      * @param   array   the where clause
  639.      * @return  string
  640.      */
  641.     function _update_batch($table, $values, $index, $where = NULL)
  642.     {
  643.         $ids = array();
  644.         $where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
  645.  
  646.         foreach ($values as $key => $val)
  647.         {
  648.             $ids[] = $val[$index];
  649.  
  650.             foreach (array_keys($val) as $field)
  651.             {
  652.                 if ($field != $index)
  653.                 {
  654.                     $final[$field][] =  'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
  655.                 }
  656.             }
  657.         }
  658.  
  659.         $sql = "UPDATE ".$table." SET ";
  660.         $cases = '';
  661.  
  662.         foreach ($final as $k => $v)
  663.         {
  664.             $cases .= $k.' = CASE '."\n";
  665.             foreach ($v as $row)
  666.             {
  667.                 $cases .= $row."\n";
  668.             }
  669.  
  670.             $cases .= 'ELSE '.$k.' END, ';
  671.         }
  672.  
  673.         $sql .= substr($cases, 0, -2);
  674.  
  675.         $sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
  676.  
  677.         return $sql;
  678.     }
  679.  
  680.     // --------------------------------------------------------------------
  681.  
  682.     /**
  683.      * Truncate statement
  684.      *
  685.      * Generates a platform-specific truncate string from the supplied data
  686.      * If the database does not support the truncate() command
  687.      * This function maps to "DELETE FROM table"
  688.      *
  689.      * @access  public
  690.      * @param   string  the table name
  691.      * @return  string
  692.      */
  693.     function _truncate($table)
  694.     {
  695.         return "TRUNCATE ".$table;
  696.     }
  697.  
  698.     // --------------------------------------------------------------------
  699.  
  700.     /**
  701.      * Delete statement
  702.      *
  703.      * Generates a platform-specific delete string from the supplied data
  704.      *
  705.      * @access  public
  706.      * @param   string  the table name
  707.      * @param   array   the where clause
  708.      * @param   string  the limit clause
  709.      * @return  string
  710.      */
  711.     function _delete($table, $where = array(), $like = array(), $limit = FALSE)
  712.     {
  713.         $conditions = '';
  714.  
  715.         if (count($where) > 0 OR count($like) > 0)
  716.         {
  717.             $conditions = "\nWHERE ";
  718.             $conditions .= implode("\n", $this->ar_where);
  719.  
  720.             if (count($where) > 0 && count($like) > 0)
  721.             {
  722.                 $conditions .= " AND ";
  723.             }
  724.             $conditions .= implode("\n", $like);
  725.         }
  726.  
  727.         $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
  728.  
  729.         return "DELETE FROM ".$table.$conditions.$limit;
  730.     }
  731.  
  732.     // --------------------------------------------------------------------
  733.  
  734.     /**
  735.      * Limit string
  736.      *
  737.      * Generates a platform-specific LIMIT clause
  738.      *
  739.      * @access  public
  740.      * @param   string  the sql query string
  741.      * @param   integer the number of rows to limit the query to
  742.      * @param   integer the offset value
  743.      * @return  string
  744.      */
  745.     function _limit($sql, $limit, $offset)
  746.     {
  747.         $sql .= "LIMIT ".$limit;
  748.  
  749.         if ($offset > 0)
  750.         {
  751.             $sql .= " OFFSET ".$offset;
  752.         }
  753.  
  754.         return $sql;
  755.     }
  756.  
  757.     // --------------------------------------------------------------------
  758.  
  759.     /**
  760.      * Close DB Connection
  761.      *
  762.      * @access  public
  763.      * @param   resource
  764.      * @return  void
  765.      */
  766.     function _close($conn_id)
  767.     {
  768.         @mysqli_close($conn_id);
  769.     }
  770.  
  771.  
  772. }
  773.  
  774.  
  775. /* End of file mysqli_driver.php */
  776. /* Location: ./system/database/drivers/mysqli/mysqli_driver.php */
Add Comment
Please, Sign In to add comment