Make WordPress Core

Ticket #21663: 21663-PDO-merge.diff

File 21663-PDO-merge.diff, 10.1 KB (added by wonderboymusic, 12 years ago)
  • src/wp-includes/wp-db.php

     
    510510        public $is_mysql = null;
    511511
    512512        /**
     513         * Array of fetched rows.
     514         * PDO doesn't have a "count rows" feature, so we have to fetch the rows
     515         * up front, and cache them here
     516         *
     517         * @since 3.8.0
     518         * @var array
     519         */
     520        private $fetched_rows = array();
     521
     522        /**
    513523         * Connects to the database server and selects a database
    514524         *
    515525         * PHP5 style constructor for compatibility with PHP5. Does
     
    636646                        $charset = $this->charset;
    637647                if ( ! isset( $collate ) )
    638648                        $collate = $this->collate;
    639                 if ( $this->has_cap( 'collation' ) && ! empty( $charset ) ) {
    640                         if ( function_exists( 'mysql_set_charset' ) && $this->has_cap( 'set_charset' ) ) {
    641                                 mysql_set_charset( $charset, $dbh );
    642                         } else {
    643                                 $query = $this->prepare( 'SET NAMES %s', $charset );
    644                                 if ( ! empty( $collate ) )
    645                                         $query .= $this->prepare( ' COLLATE %s', $collate );
    646                                 mysql_query( $query, $dbh );
    647                         }
     649                if ( $this->has_cap( 'collation', $dbh ) && !empty( $charset ) ) {
     650                        $query = $this->prepare( 'SET NAMES %s', $charset );
     651                        if ( ! empty( $collate ) )
     652                                $query .= $this->prepare( ' COLLATE %s', $collate );
     653                        $this->dbh->query( $query );
    648654                }
    649655        }
    650656
     
    827833         * @return null Always null.
    828834         */
    829835        function select( $db, $dbh = null ) {
    830                 if ( is_null($dbh) )
    831                         $dbh = $this->dbh;
     836                if ( $dbh instanceof PDO ) {
     837                        $result = true;
     838                        try {
     839                                $dbh->exec( sprintf( 'USE `%s`', $db ) );
     840                        } catch ( Exception $e ) {
     841                                $result = false;
     842                        }
     843                } else {
     844                        $result = $dbh->select( $db );
     845                }
    832846
    833                 if ( !@mysql_select_db( $db, $dbh ) ) {
     847                if ( ! $result ) {
    834848                        $this->ready = false;
    835849                        wp_load_translations_early();
    836850                        $this->bail( sprintf( __( '<h1>Can&#8217;t select database</h1>
     
    876890         * @return string escaped
    877891         */
    878892        function _real_escape( $string ) {
    879                 if ( $this->dbh )
    880                         return mysql_real_escape_string( $string, $this->dbh );
    881 
    882                 $class = get_class( $this );
    883                 _doing_it_wrong( $class, "$class must set a database connection for use with escaping.", E_USER_NOTICE );
    884                 return addslashes( $string );
     893                return substr( $this->dbh->quote( $string ), 1, -1 );
    885894        }
    886895
    887896        /**
     
    10191028                global $EZSQL_ERROR;
    10201029
    10211030                if ( !$str )
    1022                         $str = mysql_error( $this->dbh );
     1031                        $str = $this->get_error_message();
    10231032                $EZSQL_ERROR[] = array( 'query' => $this->last_query, 'error_str' => $str );
    10241033
    10251034                if ( $this->suppress_errors )
     
    11161125         * @return void
    11171126         */
    11181127        function flush() {
     1128                if ( $this->result instanceof PDOStatement )
     1129                        $this->result->closeCursor();
     1130                $this->result = null;
     1131                $this->col_info = null;
     1132                $this->fetched_rows = array();
    11191133                $this->last_result = array();
    1120                 $this->col_info    = null;
    11211134                $this->last_query  = null;
    11221135                $this->rows_affected = $this->num_rows = 0;
    11231136                $this->last_error  = '';
     1137        }
    11241138
    1125                 if ( is_resource( $this->result ) )
    1126                         mysql_free_result( $this->result );
     1139        /**
     1140         * Connect to database
     1141         * @return bool
     1142         */
     1143        public function connect( $host, $user, $pass, $port = 3306, $options = array() ) {
     1144                $dsn = sprintf( 'mysql:host=%1$s;port=%2$d', $host, $port );
     1145
     1146                try {
     1147                        $pdo_options = array();
     1148
     1149                        if ( ! empty( $options['key'] ) && ! empty( $options['cert'] ) && ! empty( $options['ca'] ) ) {
     1150                                $pdo_options[ PDO::MYSQL_ATTR_SSL_KEY ]    = $options['key'];
     1151                                $pdo_options[ PDO::MYSQL_ATTR_SSL_CERT ]   = $options['cert'];
     1152                                $pdo_options[ PDO::MYSQL_ATTR_SSL_CA ]     = $options['ca'];
     1153                                $pdo_options[ PDO::MYSQL_ATTR_SSL_CAPATH ] = $options['ca_path'];
     1154                                $pdo_options[ PDO::MYSQL_ATTR_SSL_CIPHER ] = $options['cipher'];
     1155
     1156                                // Cleanup empty values
     1157                                $pdo_options = array_filter( $pdo_options );
     1158                        }
     1159
     1160                        $this->dbh = new PDO( $dsn, $user, $pass, $pdo_options );
     1161                        $this->dbh->setAttribute ( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
     1162                } catch ( Exception $e ) {
     1163                        return false;
     1164                }
     1165
     1166                return true;
    11271167        }
    11281168
    11291169        /**
     
    11321172         * @since 3.0.0
    11331173         */
    11341174        function db_connect() {
    1135 
    11361175                $this->is_mysql = true;
    11371176
    1138                 $new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
    1139                 $client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;
    1140 
    1141                 if ( WP_DEBUG ) {
    1142                         $this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
    1143                 } else {
    1144                         $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
     1177                if ( false !== strpos( $this->dbhost, ':' ) ) {
     1178                        list( $host, $port ) = explode( ':', $this->dbhost );
     1179                } else {
     1180                        $host = $this->dbhost;
     1181                        $port = 3306;
    11451182                }
    11461183
    1147                 if ( !$this->dbh ) {
     1184                $options = array();
     1185                $options['key'] = defined( 'DB_SSL_KEY' ) ? DB_SSL_KEY : null;
     1186                $options['cert'] = defined( 'DB_SSL_CERT' ) ? DB_SSL_CERT : null;
     1187                $options['ca'] = defined( 'DB_SSL_CA' ) ? DB_SSL_CA : null;
     1188                $options['ca_path'] = defined( 'DB_SSL_CA_PATH' ) ? DB_SSL_CA_PATH : null;
     1189                $options['cipher'] = defined( 'DB_SSL_CIPHER' ) ? DB_SSL_CIPHER : null;
     1190
     1191                if ( ! $this->connect( $host, $this->dbuser, $this->dbpassword, $port, $options ) ) {
    11481192                        wp_load_translations_early();
    11491193                        $this->bail( sprintf( __( "
    11501194<h1>Error establishing a database connection</h1>
     
    11681212        }
    11691213
    11701214        /**
     1215         * Get last insert id
     1216         *
     1217         * @since 3.8.0
     1218         *
     1219         * @return int
     1220         */
     1221        public function insert_id() {
     1222                return $this->dbh->lastInsertId();
     1223        }
     1224
     1225        /**
     1226         * Get the latest error message from the DB driver
     1227         *
     1228         * @since 3.8.0
     1229         *
     1230         * @return string
     1231         */
     1232        public function get_error_message() {
     1233                $error = $this->dbh->errorInfo();
     1234                if ( isset( $error[2] ) ) {
     1235                        return $error[2];
     1236                }
     1237                return '';
     1238        }
     1239
     1240        /**
     1241         * Get results
     1242         *
     1243         * @since 3.8.0
     1244         *
     1245         * @return array
     1246         */
     1247        public function pdo_get_results() {
     1248                if ( ! empty( $this->fetched_rows ) ) {
     1249                        return $this->fetched_rows;
     1250                }
     1251                $this->fetched_rows = array();
     1252
     1253                if ( ! empty( $this->result ) && $this->result->rowCount() > 0 ) {
     1254                        try {
     1255                                while ( $row = $this->result->fetchObject() )
     1256                                        $this->fetched_rows[] = $row;
     1257                        } catch ( Exception $e ) {}
     1258                }
     1259
     1260                return $this->fetched_rows;
     1261        }
     1262
     1263        /**
    11711264         * Perform a MySQL database query, using current database connection.
    11721265         *
    11731266         * More information can be found on the codex page.
     
    11801273        function query( $query ) {
    11811274                if ( ! $this->ready )
    11821275                        return false;
    1183                 /**
    1184                  * Filter the database query.
    1185                  *
    1186                  * Some queries are made before the plugins have been loaded, and thus cannot be filtered with this method.
    1187                  *
    1188                  * @since 2.1.0
    1189                  * @param string $query Database query.
    1190                  */
     1276
     1277                // some queries are made before the plugins have been loaded, and thus cannot be filtered with this method
    11911278                $query = apply_filters( 'query', $query );
    11921279
    11931280                $return_val = 0;
     
    12021289                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
    12031290                        $this->timer_start();
    12041291
    1205                 $this->result = @mysql_query( $query, $this->dbh );
     1292                try {
     1293                        $this->result = $this->dbh->query( $query );
     1294                } catch ( Exception $e ) {
     1295                        if ( WP_DEBUG ) {
     1296                                error_log( 'Error executing query: ' . $e->getCode() . ' - ' . $e->getMessage() . ' in query ' . $query );
     1297                        }
     1298                        return $return_val;
     1299                }
     1300
    12061301                $this->num_queries++;
    12071302
    12081303                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
    12091304                        $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
    12101305
    12111306                // If there is an error then take note of it..
    1212                 if ( $this->last_error = mysql_error( $this->dbh ) ) {
    1213                         // Clear insert_id on a subsequent failed insert.
    1214                         if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) )
    1215                                 $this->insert_id = 0;
    1216 
     1307                if ( $this->last_error = $this->get_error_message() ) {
    12171308                        $this->print_error();
    12181309                        return false;
    12191310                }
     
    12211312                if ( preg_match( '/^\s*(create|alter|truncate|drop)\s/i', $query ) ) {
    12221313                        $return_val = $this->result;
    12231314                } elseif ( preg_match( '/^\s*(insert|delete|update|replace)\s/i', $query ) ) {
    1224                         $this->rows_affected = mysql_affected_rows( $this->dbh );
     1315                        $this->rows_affected = $this->affected_rows();
    12251316                        // Take note of the insert_id
    12261317                        if ( preg_match( '/^\s*(insert|replace)\s/i', $query ) ) {
    1227                                 $this->insert_id = mysql_insert_id($this->dbh);
     1318                                $this->insert_id = $this->insert_id();
    12281319                        }
    12291320                        // Return number of rows affected
    12301321                        $return_val = $this->rows_affected;
     1322                } elseif ( preg_match( '/^\s*select\s/i', $query ) ) {
     1323                        $this->get_results();
     1324                        $return_val = count( $this->fetched_rows );
    12311325                } else {
    1232                         $num_rows = 0;
    1233                         while ( $row = @mysql_fetch_object( $this->result ) ) {
    1234                                 $this->last_result[$num_rows] = $row;
    1235                                 $num_rows++;
    1236                         }
    1237 
    1238                         // Log number of rows the query returned
    1239                         // and return number of rows selected
    1240                         $this->num_rows = $num_rows;
    1241                         $return_val     = $num_rows;
     1326                        $return_val = $this->num_rows = count( $this->result );
    12421327                }
    12431328
     1329                $this->last_result = $this->pdo_get_results();
     1330
    12441331                return $return_val;
    12451332        }
    12461333
     
    15641651        }
    15651652
    15661653        /**
     1654         * Get number of rows affected
     1655         *
     1656         * @since 3.8.0
     1657         *
     1658         * @return int
     1659         */
     1660        public function affected_rows() {
     1661                if ( $this->result instanceof PDOStatement )
     1662                        return $this->result->rowCount();
     1663
     1664                return 0;
     1665        }
     1666
     1667        /**
    15671668         * Load the column metadata from the last query.
    15681669         *
    15691670         * @since 3.5.0
     
    15721673         */
    15731674        protected function load_col_info() {
    15741675                if ( $this->col_info )
    1575                         return;
    1576 
    1577                 for ( $i = 0; $i < @mysql_num_fields( $this->result ); $i++ ) {
    1578                         $this->col_info[ $i ] = @mysql_fetch_field( $this->result, $i );
     1676                        return $this->col_info;
     1677                for ( $i = 0; $i < $this->result->columnCount() ; $i++ ) {
     1678                        $this->col_info[ $i ] = $this->result->fetchColumn( $i );
    15791679                }
    15801680        }
    15811681
     
    17471847         * @return false|string false on failure, version number on success
    17481848         */
    17491849        function db_version() {
    1750                 return preg_replace( '/[^0-9.].*/', '', mysql_get_server_info( $this->dbh ) );
     1850                return preg_replace( '/[^0-9.].*/', '', $this->dbh->getAttribute( PDO::ATTR_SERVER_VERSION ) );
    17511851        }
    1752 }
     1852
     1853        /**
     1854         * Don't save any state.  The db wrapper should call connect() again.
     1855         *
     1856         * @since 3.8.0
     1857         *
     1858         * @return array
     1859         */
     1860        public function __sleep() {
     1861                return array();
     1862        }
     1863}
     1864 No newline at end of file