* @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;
* @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,
* @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__ );
}
* @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 );
}
/**
* @return int
*/
function affectedRows() {
- return mysql_affected_rows( $this->mConn );
+ $conn = $this->getBindingHandle();
+
+ return mysql_affected_rows( $conn );
}
/**
* @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 ) {
}
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 );
}
}
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;
( $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
* @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;
*/
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" );
* @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__ );
}
* @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;
}
/**
* @return int
*/
function affectedRows() {
- return $this->mConn->affected_rows;
+ $conn = $this->getBindingHandle();
+
+ return $conn->affected_rows;
}
/**
* @return bool
*/
function selectDB( $db ) {
+ $conn = $this->getBindingHandle();
+
$this->mDBname = $db;
- return $this->mConn->select_db( $db );
+ return $conn->select_db( $db );
}
/**
* @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();
}
/**
public function openConnection( $i, $wiki = false ) {
if ( $wiki !== false ) {
$conn = $this->openForeignConnection( $i, $wiki );
-
- return $conn;
- }
- if ( isset( $this->mConns['local'][$i][0] ) ) {
+ } elseif ( isset( $this->mConns['local'][$i][0] ) ) {
$conn = $this->mConns['local'][$i][0];
} else {
$server = $this->mServers[$i];
}
}
+ if ( $conn && !$conn->isOpen() ) {
+ // Connection was made but later unrecoverably lost for some reason.
+ // Do not return a handle that will just throw exceptions on use,
+ // but let the calling code (e.g. getReaderIndex) try another server.
+ // See DatabaseMyslBase::ping() for how this can happen.
+ $this->mErrorConnection = $conn;
+ $conn = false;
+ }
+
return $conn;
}