diff options
Diffstat (limited to 'includes/db/DatabaseMysql.php')
-rw-r--r-- | includes/db/DatabaseMysql.php | 159 |
1 files changed, 94 insertions, 65 deletions
diff --git a/includes/db/DatabaseMysql.php b/includes/db/DatabaseMysql.php index c179b724..7f389da9 100644 --- a/includes/db/DatabaseMysql.php +++ b/includes/db/DatabaseMysql.php @@ -2,6 +2,21 @@ /** * This is the MySQL database abstraction layer. * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * * @file * @ingroup Database */ @@ -44,7 +59,7 @@ class DatabaseMysql extends DatabaseBase { * @throws DBConnectionError */ function open( $server, $user, $password, $dbName ) { - global $wgAllDBsAreLocalhost; + global $wgAllDBsAreLocalhost, $wgDBmysql5, $wgSQLMode; wfProfileIn( __METHOD__ ); # Load mysql.so if we don't have it @@ -68,7 +83,15 @@ class DatabaseMysql extends DatabaseBase { $this->mPassword = $password; $this->mDBname = $dbName; - wfProfileIn("dbconnect-$server"); + $connFlags = 0; + if ( $this->mFlags & DBO_SSL ) { + $connFlags |= MYSQL_CLIENT_SSL; + } + if ( $this->mFlags & DBO_COMPRESS ) { + $connFlags |= MYSQL_CLIENT_COMPRESS; + } + + wfProfileIn( "dbconnect-$server" ); # The kernel's default SYN retransmission period is far too slow for us, # so we use a short timeout plus a manual retry. Retrying means that a small @@ -85,85 +108,71 @@ class DatabaseMysql extends DatabaseBase { usleep( 1000 ); } if ( $this->mFlags & DBO_PERSISTENT ) { - $this->mConn = mysql_pconnect( $realServer, $user, $password ); + $this->mConn = mysql_pconnect( $realServer, $user, $password, $connFlags ); } else { # Create a new connection... - $this->mConn = mysql_connect( $realServer, $user, $password, true ); + $this->mConn = mysql_connect( $realServer, $user, $password, true, $connFlags ); } #if ( $this->mConn === false ) { #$iplus = $i + 1; #wfLogDBError("Connect loop error $iplus of $max ($server): " . mysql_errno() . " - " . mysql_error()."\n"); #} } - $phpError = $this->restoreErrorHandler(); + $error = $this->restoreErrorHandler(); + + wfProfileOut( "dbconnect-$server" ); + # Always log connection errors if ( !$this->mConn ) { - $error = $this->lastError(); if ( !$error ) { - $error = $phpError; + $error = $this->lastError(); } wfLogDBError( "Error connecting to {$this->mServer}: $error\n" ); - wfDebug( "DB connection error\n" ); - wfDebug( "Server: $server, User: $user, Password: " . - substr( $password, 0, 3 ) . "..., error: " . mysql_error() . "\n" ); - } + wfDebug( "DB connection error\n" . + "Server: $server, User: $user, Password: " . + substr( $password, 0, 3 ) . "..., error: " . $error . "\n" ); - wfProfileOut("dbconnect-$server"); + wfProfileOut( __METHOD__ ); + $this->reportConnectionError( $error ); + } - if ( $dbName != '' && $this->mConn !== false ) { + if ( $dbName != '' ) { wfSuppressWarnings(); $success = mysql_select_db( $dbName, $this->mConn ); wfRestoreWarnings(); if ( !$success ) { - $error = "Error selecting database $dbName on server {$this->mServer} " . - "from client host " . wfHostname() . "\n"; - wfLogDBError(" Error selecting database $dbName on server {$this->mServer} \n"); - wfDebug( $error ); - } - } else { - # Delay USE query - $success = (bool)$this->mConn; - } + wfLogDBError( "Error selecting database $dbName on server {$this->mServer}\n" ); + wfDebug( "Error selecting database $dbName on server {$this->mServer} " . + "from client host " . wfHostname() . "\n" ); - if ( $success ) { - // Tell the server we're communicating with it in UTF-8. - // This may engage various charset conversions. - global $wgDBmysql5; - if( $wgDBmysql5 ) { - $this->query( 'SET NAMES utf8', __METHOD__ ); - } else { - $this->query( 'SET NAMES binary', __METHOD__ ); - } - // Set SQL mode, default is turning them all off, can be overridden or skipped with null - global $wgSQLMode; - if ( is_string( $wgSQLMode ) ) { - $mode = $this->addQuotes( $wgSQLMode ); - $this->query( "SET sql_mode = $mode", __METHOD__ ); + wfProfileOut( __METHOD__ ); + $this->reportConnectionError( "Error selecting database $dbName" ); } + } - // Turn off strict mode if it is on + // Tell the server we're communicating with it in UTF-8. + // This may engage various charset conversions. + if( $wgDBmysql5 ) { + $this->query( 'SET NAMES utf8', __METHOD__ ); } else { - $this->reportConnectionError( $phpError ); + $this->query( 'SET NAMES binary', __METHOD__ ); + } + // Set SQL mode, default is turning them all off, can be overridden or skipped with null + if ( is_string( $wgSQLMode ) ) { + $mode = $this->addQuotes( $wgSQLMode ); + $this->query( "SET sql_mode = $mode", __METHOD__ ); } - $this->mOpened = $success; + $this->mOpened = true; wfProfileOut( __METHOD__ ); - return $success; + return true; } /** * @return bool */ - function close() { - $this->mOpened = false; - if ( $this->mConn ) { - if ( $this->trxLevel() ) { - $this->commit(); - } - return mysql_close( $this->mConn ); - } else { - return true; - } + protected function closeConnection() { + return mysql_close( $this->mConn ); } /** @@ -194,7 +203,13 @@ class DatabaseMysql extends DatabaseBase { wfSuppressWarnings(); $row = mysql_fetch_object( $res ); wfRestoreWarnings(); - if( $this->lastErrno() ) { + + $errno = $this->lastErrno(); + // Unfortunately, mysql_fetch_object does not reset the last errno. + // Only check for CR_SERVER_LOST and CR_UNKNOWN_ERROR, as + // these are the only errors mysql_fetch_object can cause. + // See http://dev.mysql.com/doc/refman/5.0/es/mysql-fetch-row.html. + if( $errno == 2000 || $errno == 2013 ) { throw new DBUnexpectedError( $this, 'Error in fetchObject(): ' . htmlspecialchars( $this->lastError() ) ); } return $row; @@ -212,7 +227,13 @@ class DatabaseMysql extends DatabaseBase { wfSuppressWarnings(); $row = mysql_fetch_array( $res ); wfRestoreWarnings(); - if ( $this->lastErrno() ) { + + $errno = $this->lastErrno(); + // Unfortunately, mysql_fetch_array does not reset the last errno. + // Only check for CR_SERVER_LOST and CR_UNKNOWN_ERROR, as + // these are the only errors mysql_fetch_object can cause. + // See http://dev.mysql.com/doc/refman/5.0/es/mysql-fetch-row.html. + if( $errno == 2000 || $errno == 2013 ) { throw new DBUnexpectedError( $this, 'Error in fetchRow(): ' . htmlspecialchars( $this->lastError() ) ); } return $row; @@ -385,7 +406,7 @@ class DatabaseMysql extends DatabaseBase { * @param $table string * @param $index string * @param $fname string - * @return false|array + * @return bool|array|null False or null on failure */ function indexInfo( $table, $index, $fname = 'DatabaseMysql::indexInfo' ) { # SHOW INDEX works in MySQL 3.23.58, but SHOW INDEXES does not. @@ -558,7 +579,7 @@ class DatabaseMysql extends DatabaseBase { # Commit any open transactions if ( $this->mTrxLevel ) { - $this->commit(); + $this->commit( __METHOD__ ); } if ( !is_null( $this->mFakeSlaveLag ) ) { @@ -585,7 +606,7 @@ class DatabaseMysql extends DatabaseBase { /** * Get the position of the master from SHOW SLAVE STATUS * - * @return MySQLMasterPos|false + * @return MySQLMasterPos|bool */ function getSlavePos() { if ( !is_null( $this->mFakeSlaveLag ) ) { @@ -606,7 +627,7 @@ class DatabaseMysql extends DatabaseBase { /** * Get the position of the master from SHOW MASTER STATUS * - * @return MySQLMasterPos|false + * @return MySQLMasterPos|bool */ function getMasterPos() { if ( $this->mFakeMaster ) { @@ -653,13 +674,6 @@ class DatabaseMysql extends DatabaseBase { } /** - * @return bool - */ - function standardSelectDistinct() { - return false; - } - - /** * @param $options array */ public function setSessionOptions( array $options ) { @@ -680,6 +694,21 @@ class DatabaseMysql extends DatabaseBase { } /** + * Check to see if a named lock is available. This is non-blocking. + * + * @param $lockName String: name of lock to poll + * @param $method String: name of method calling us + * @return Boolean + * @since 1.20 + */ + public function lockIsFree( $lockName, $method ) { + $lockName = $this->addQuotes( $lockName ); + $result = $this->query( "SELECT IS_FREE_LOCK($lockName) AS lockstatus", $method ); + $row = $this->fetchObject( $result ); + return ( $row->lockstatus == 1 ); + } + + /** * @param $lockName string * @param $method string * @param $timeout int @@ -708,7 +737,7 @@ class DatabaseMysql extends DatabaseBase { $lockName = $this->addQuotes( $lockName ); $result = $this->query( "SELECT RELEASE_LOCK($lockName) as lockstatus", $method ); $row = $this->fetchObject( $result ); - return $row->lockstatus; + return ( $row->lockstatus == 1 ); } /** @@ -860,7 +889,7 @@ class DatabaseMysql extends DatabaseBase { /** * List all tables on the database * - * @param $prefix Only show tables with this prefix, e.g. mw_ + * @param $prefix string Only show tables with this prefix, e.g. mw_ * @param $fname String: calling function name * @return array */ |