From: jenkins-bot Date: Sun, 28 Jun 2015 00:26:07 +0000 (+0000) Subject: Merge "database: Small DB class cleanups" X-Git-Tag: 1.31.0-rc.0~10940 X-Git-Url: http://git.cyclocoop.org/%28?a=commitdiff_plain;h=0bcd8347e597de8d689af1d3c74bb52cafaaf74d;hp=-c;p=lhc%2Fweb%2Fwiklou.git Merge "database: Small DB class cleanups" --- 0bcd8347e597de8d689af1d3c74bb52cafaaf74d diff --combined includes/db/Database.php index 2b8cfe255f,032e926d15..e74fe80690 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@@ -1019,6 -1019,17 +1019,17 @@@ abstract class DatabaseBase implements return $closed; } + /** + * Make sure isOpen() returns true as a sanity check + * + * @throws DBUnexpectedError + */ + protected function assertOpen() { + if ( !$this->isOpen() ) { + throw new DBUnexpectedError( $this, "DB connection was already closed." ); + } + } + /** * Closes underlying database connection * @since 1.20 @@@ -1175,9 -1186,7 +1186,7 @@@ $queryId = MWDebug::query( $sql, $fname, $isMaster ); # Avoid fatals if close() was called - if ( !$this->isOpen() ) { - throw new DBUnexpectedError( $this, "DB connection was already closed." ); - } + $this->assertOpen(); # Do the query and handle errors $startTime = microtime( true ); @@@ -3648,9 -3657,7 +3657,7 @@@ } # Avoid fatals if close() was called - if ( !$this->isOpen() ) { - throw new DBUnexpectedError( $this, "DB connection was already closed." ); - } + $this->assertOpen(); $this->doBegin( $fname ); $this->mTrxTimestamp = microtime( true ); @@@ -3715,9 -3722,7 +3722,7 @@@ } # Avoid fatals if close() was called - if ( !$this->isOpen() ) { - throw new DBUnexpectedError( $this, "DB connection was already closed." ); - } + $this->assertOpen(); $this->runOnTransactionPreCommitCallbacks(); $writeTime = $this->pendingWriteQueryDuration(); @@@ -3774,9 -3779,7 +3779,7 @@@ } # Avoid fatals if close() was called - if ( !$this->isOpen() ) { - throw new DBUnexpectedError( $this, "DB connection was already closed." ); - } + $this->assertOpen(); $this->doRollback( $fname ); $this->mTrxIdleCallbacks = array(); // cancel @@@ -3829,7 -3832,6 +3832,7 @@@ * @param string $prefix Only show tables with this prefix, e.g. mw_ * @param string $fname Calling function name * @throws MWException + * @return array */ function listTables( $prefix = null, $fname = __METHOD__ ) { throw new MWException( 'DatabaseBase::listTables is not implemented in descendant class' ); @@@ -3852,7 -3854,6 +3855,7 @@@ * @param string $prefix Only show VIEWs with this prefix, eg. unit_test_ * @param string $fname Name of calling function * @throws MWException + * @return array * @since 1.22 */ public function listViews( $prefix = null, $fname = __METHOD__ ) { @@@ -3864,7 -3865,6 +3867,7 @@@ * * @param string $name Name of the database-structure to test. * @throws MWException + * @return bool * @since 1.22 */ public function isView( $name ) { diff --combined includes/db/DatabaseMysql.php index b69efac5b1,915375351f..5b15147777 --- a/includes/db/DatabaseMysql.php +++ b/includes/db/DatabaseMysql.php @@@ -33,12 -33,10 +33,12 @@@ class DatabaseMysql extends DatabaseMys * @return resource False on error */ protected function doQuery( $sql ) { + $conn = $this->getBindingHandle(); + if ( $this->bufferResults() ) { - $ret = mysql_query( $sql, $this->mConn ); + $ret = mysql_query( $sql, $conn ); } else { - $ret = mysql_unbuffered_query( $sql, $this->mConn ); + $ret = mysql_unbuffered_query( $sql, $conn ); } return $ret; @@@ -50,7 -48,8 +50,7 @@@ * @throws DBConnectionError */ protected function mysqlConnect( $realServer ) { - # Fail now - # Otherwise we get a suppressed fatal error, which is very hard to track down + # Avoid a suppressed fatal error, which is very hard to track down if ( !extension_loaded( 'mysql' ) ) { throw new DBConnectionError( $this, @@@ -74,6 -73,9 +74,9 @@@ $conn = false; + # 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 + # but finite rate of SYN packet loss won't cause user-visible errors. for ( $i = 0; $i < $numAttempts && !$conn; $i++ ) { if ( $i > 1 ) { usleep( 1000 ); @@@ -94,10 -96,8 +97,10 @@@ * @return bool */ protected function mysqlSetCharset( $charset ) { + $conn = $this->getBindingHandle(); + if ( function_exists( 'mysql_set_charset' ) ) { - return mysql_set_charset( $charset, $this->mConn ); + return mysql_set_charset( $charset, $conn ); } else { return $this->query( 'SET NAMES ' . $charset, __METHOD__ ); } @@@ -107,18 -107,14 +110,18 @@@ * @return bool */ protected function closeConnection() { - return mysql_close( $this->mConn ); + $conn = $this->getBindingHandle(); + + return mysql_close( $conn ); } /** * @return int */ function insertId() { - return mysql_insert_id( $this->mConn ); + $conn = $this->getBindingHandle(); + + return mysql_insert_id( $conn ); } /** @@@ -136,9 -132,7 +139,9 @@@ * @return int */ function affectedRows() { - return mysql_affected_rows( $this->mConn ); + $conn = $this->getBindingHandle(); + + return mysql_affected_rows( $conn ); } /** @@@ -146,11 -140,9 +149,11 @@@ * @return bool */ function selectDB( $db ) { + $conn = $this->getBindingHandle(); + $this->mDBname = $db; - return mysql_select_db( $db, $this->mConn ); + return mysql_select_db( $db, $conn ); } protected function mysqlFreeResult( $res ) { @@@ -194,14 -186,10 +197,14 @@@ } protected function mysqlRealEscapeString( $s ) { - return mysql_real_escape_string( $s, $this->mConn ); + $conn = $this->getBindingHandle(); + + return mysql_real_escape_string( $s, $conn ); } protected function mysqlPing() { - return mysql_ping( $this->mConn ); + $conn = $this->getBindingHandle(); + + return mysql_ping( $conn ); } } diff --combined includes/db/DatabaseMysqlBase.php index 4085fa9c4d,9285d70d3b..e32690947f --- a/includes/db/DatabaseMysqlBase.php +++ b/includes/db/DatabaseMysqlBase.php @@@ -59,22 -59,16 +59,16 @@@ abstract class DatabaseMysqlBase extend function open( $server, $user, $password, $dbName ) { global $wgAllDBsAreLocalhost, $wgSQLMode; - # Debugging hack -- fake cluster - if ( $wgAllDBsAreLocalhost ) { - $realServer = 'localhost'; - } else { - $realServer = $server; - } + # Close/unset connection handle $this->close(); + + # Debugging hack -- fake cluster + $realServer = $wgAllDBsAreLocalhost ? 'localhost' : $server; $this->mServer = $server; $this->mUser = $user; $this->mPassword = $password; $this->mDBname = $dbName; - # 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 - # but finite rate of SYN packet loss won't cause user-visible errors. - $this->mConn = false; $this->installErrorHandler(); try { $this->mConn = $this->mysqlConnect( $realServer ); @@@ -586,12 -580,9 +580,12 @@@ function ping() { $ping = $this->mysqlPing(); if ( $ping ) { + // Connection was good or lost but reconnected... + // @note: mysqlnd (php 5.6+) does not support this (PHP bug 52561) return true; } + // Try a full disconnect/reconnect cycle if ping() failed $this->closeConnection(); $this->mOpened = false; $this->mConn = false; @@@ -1061,28 -1052,6 +1055,28 @@@ ( $this->lastErrno() == 1290 && strpos( $this->lastError(), '--read-only' ) !== false ); } + /** + * Get the underlying binding handle, mConn + * + * Makes sure that mConn is set (disconnects and ping() failure can unset it). + * This catches broken callers than catch and ignore disconnection exceptions. + * Unlike checking isOpen(), this is safe to call inside of open(). + * + * @return resource|object + * @throws DBUnexpectedError + * @since 1.26 + */ + protected function getBindingHandle() { + if ( !$this->mConn ) { + throw new DBUnexpectedError( + $this, + 'DB connection was already closed or the connection dropped.' + ); + } + + return $this->mConn; + } + /** * @param string $oldName * @param string $newName diff --combined includes/db/DatabaseMysqli.php index 8b51d81580,d4106bec1b..8ca2362773 --- a/includes/db/DatabaseMysqli.php +++ b/includes/db/DatabaseMysqli.php @@@ -29,17 -29,18 +29,20 @@@ * @see Database */ class DatabaseMysqli extends DatabaseMysqlBase { + /** @var mysqli */ + protected $mConn; + /** * @param string $sql * @return resource */ protected function doQuery( $sql ) { + $conn = $this->getBindingHandle(); + if ( $this->bufferResults() ) { - $ret = $this->mConn->query( $sql ); + $ret = $conn->query( $sql ); } else { - $ret = $this->mConn->query( $sql, MYSQLI_USE_RESULT ); + $ret = $conn->query( $sql, MYSQLI_USE_RESULT ); } return $ret; @@@ -52,8 -53,8 +55,8 @@@ */ protected function mysqlConnect( $realServer ) { global $wgDBmysql5; - # Fail now - # Otherwise we get a suppressed fatal error, which is very hard to track down + + # Avoid suppressed fatal error, which is very hard to track down if ( !function_exists( 'mysqli_init' ) ) { throw new DBConnectionError( $this, "MySQLi functions missing," . " have you compiled PHP with the --with-mysqli option?\n" ); @@@ -118,10 -119,8 +121,10 @@@ * @return bool */ protected function mysqlSetCharset( $charset ) { - if ( method_exists( $this->mConn, 'set_charset' ) ) { - return $this->mConn->set_charset( $charset ); + $conn = $this->getBindingHandle(); + + if ( method_exists( $conn, 'set_charset' ) ) { + return $conn->set_charset( $charset ); } else { return $this->query( 'SET NAMES ' . $charset, __METHOD__ ); } @@@ -131,18 -130,14 +134,18 @@@ * @return bool */ protected function closeConnection() { - return $this->mConn->close(); + $conn = $this->getBindingHandle(); + + return $conn->close(); } /** * @return int */ function insertId() { - return (int)$this->mConn->insert_id; + $conn = $this->getBindingHandle(); + + return (int)$conn->insert_id; } /** @@@ -160,9 -155,7 +163,9 @@@ * @return int */ function affectedRows() { - return $this->mConn->affected_rows; + $conn = $this->getBindingHandle(); + + return $conn->affected_rows; } /** @@@ -170,11 -163,9 +173,11 @@@ * @return bool */ function selectDB( $db ) { + $conn = $this->getBindingHandle(); + $this->mDBname = $db; - return $this->mConn->select_db( $db ); + return $conn->select_db( $db ); } /** @@@ -301,15 -292,11 +304,15 @@@ * @return string */ protected function mysqlRealEscapeString( $s ) { - return $this->mConn->real_escape_string( $s ); + $conn = $this->getBindingHandle(); + + return $conn->real_escape_string( $s ); } protected function mysqlPing() { - return $this->mConn->ping(); + $conn = $this->getBindingHandle(); + + return $conn->ping(); } /**