Ticket #21663: 21663-PDO-merge.diff
File 21663-PDO-merge.diff, 10.1 KB (added by , 12 years ago) |
---|
-
src/wp-includes/wp-db.php
510 510 public $is_mysql = null; 511 511 512 512 /** 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 /** 513 523 * Connects to the database server and selects a database 514 524 * 515 525 * PHP5 style constructor for compatibility with PHP5. Does … … 636 646 $charset = $this->charset; 637 647 if ( ! isset( $collate ) ) 638 648 $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 ); 648 654 } 649 655 } 650 656 … … 827 833 * @return null Always null. 828 834 */ 829 835 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 } 832 846 833 if ( ! @mysql_select_db( $db, $dbh )) {847 if ( ! $result ) { 834 848 $this->ready = false; 835 849 wp_load_translations_early(); 836 850 $this->bail( sprintf( __( '<h1>Can’t select database</h1> … … 876 890 * @return string escaped 877 891 */ 878 892 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 ); 885 894 } 886 895 887 896 /** … … 1019 1028 global $EZSQL_ERROR; 1020 1029 1021 1030 if ( !$str ) 1022 $str = mysql_error( $this->dbh);1031 $str = $this->get_error_message(); 1023 1032 $EZSQL_ERROR[] = array( 'query' => $this->last_query, 'error_str' => $str ); 1024 1033 1025 1034 if ( $this->suppress_errors ) … … 1116 1125 * @return void 1117 1126 */ 1118 1127 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(); 1119 1133 $this->last_result = array(); 1120 $this->col_info = null;1121 1134 $this->last_query = null; 1122 1135 $this->rows_affected = $this->num_rows = 0; 1123 1136 $this->last_error = ''; 1137 } 1124 1138 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; 1127 1167 } 1128 1168 1129 1169 /** … … 1132 1172 * @since 3.0.0 1133 1173 */ 1134 1174 function db_connect() { 1135 1136 1175 $this->is_mysql = true; 1137 1176 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; 1145 1182 } 1146 1183 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 ) ) { 1148 1192 wp_load_translations_early(); 1149 1193 $this->bail( sprintf( __( " 1150 1194 <h1>Error establishing a database connection</h1> … … 1168 1212 } 1169 1213 1170 1214 /** 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 /** 1171 1264 * Perform a MySQL database query, using current database connection. 1172 1265 * 1173 1266 * More information can be found on the codex page. … … 1180 1273 function query( $query ) { 1181 1274 if ( ! $this->ready ) 1182 1275 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 1191 1278 $query = apply_filters( 'query', $query ); 1192 1279 1193 1280 $return_val = 0; … … 1202 1289 if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) 1203 1290 $this->timer_start(); 1204 1291 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 1206 1301 $this->num_queries++; 1207 1302 1208 1303 if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) 1209 1304 $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() ); 1210 1305 1211 1306 // 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() ) { 1217 1308 $this->print_error(); 1218 1309 return false; 1219 1310 } … … 1221 1312 if ( preg_match( '/^\s*(create|alter|truncate|drop)\s/i', $query ) ) { 1222 1313 $return_val = $this->result; 1223 1314 } 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(); 1225 1316 // Take note of the insert_id 1226 1317 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(); 1228 1319 } 1229 1320 // Return number of rows affected 1230 1321 $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 ); 1231 1325 } 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 ); 1242 1327 } 1243 1328 1329 $this->last_result = $this->pdo_get_results(); 1330 1244 1331 return $return_val; 1245 1332 } 1246 1333 … … 1564 1651 } 1565 1652 1566 1653 /** 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 /** 1567 1668 * Load the column metadata from the last query. 1568 1669 * 1569 1670 * @since 3.5.0 … … 1572 1673 */ 1573 1674 protected function load_col_info() { 1574 1675 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 ); 1579 1679 } 1580 1680 } 1581 1681 … … 1747 1847 * @return false|string false on failure, version number on success 1748 1848 */ 1749 1849 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 ) ); 1751 1851 } 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