/**
* Open a connection to the database. Usually aborts on failure
*
- * @param string $server database server host
- * @param string $user database user name
- * @param string $password database user password
- * @param string $dbName database name
+ * @param string $server Database server host
+ * @param string $user Database user name
+ * @param string $password Database user password
+ * @param string $dbName Database name
* @return bool
* @throws DBConnectionError
*/
}
/**
- * @return string command delimiter used by this database engine
+ * @return string Command delimiter used by this database engine
*/
public function getDelimiter() {
return $this->delimiter;
* - false to disable debugging
* - omitted or null to do nothing
*
- * @return bool|null previous value of the flag
+ * @return bool|null Previous value of the flag
*/
public function debug( $debug = null ) {
return wfSetBit( $this->mFlags, DBO_DEBUG, $debug );
* parameters, the member with the given name is set to the given value.
*
* @param string $name
- * @param $value
+ * @param array $value
*/
public function setLBInfo( $name, $value = null ) {
if ( is_null( $value ) ) {
* database. Example uses in core:
* @see LoadBalancer::reallyOpenConnection()
* @see ForeignDBRepo::getMasterDB()
- * @see WebInstaller_DBConnect::execute()
+ * @see WebInstallerDBConnect::execute()
*
* @since 1.18
*
}
/**
- * @param $errno
+ * @param int $errno
* @param string $errstr
*/
public function connectionErrorHandler( $errno, $errstr ) {
if ( count( $this->mTrxIdleCallbacks ) ) { // sanity
throw new MWException( "Transaction idle callbacks still pending." );
}
- $this->mOpened = false;
if ( $this->mConn ) {
if ( $this->trxLevel() ) {
if ( !$this->mTrxAutomatic ) {
$this->commit( __METHOD__, 'flush' );
}
- $ret = $this->closeConnection();
+ $closed = $this->closeConnection();
$this->mConn = false;
-
- return $ret;
} else {
- return true;
+ $closed = true;
}
+ $this->mOpened = false;
+
+ return $closed;
}
/**
# Keep track of whether the transaction has write queries pending
if ( $this->mTrxLevel && !$this->mTrxDoneWrites && $this->isWriteQuery( $sql ) ) {
$this->mTrxDoneWrites = true;
- Profiler::instance()->transactionWritingIn( $this->mServer, $this->mDBname );
+ $id = spl_object_hash( $this );
+ Profiler::instance()->transactionWritingIn( $this->mServer, $this->mDBname, $id );
}
$queryProf = '';
$queryId = MWDebug::query( $sql, $fname, $isMaster );
+ # Avoid fatals if close() was called
+ if ( !$this->isOpen() ) {
+ throw new DBUnexpectedError( $this, "DB connection was already closed." );
+ }
+
# Do the query and handle errors
$ret = $this->doQuery( $commentedSql );
# Transaction is gone, like it or not
$hadTrx = $this->mTrxLevel; // possible lost transaction
$this->mTrxLevel = 0;
+ $this->mTrxIdleCallbacks = array(); // bug 65263
+ $this->mTrxPreCommitCallbacks = array(); // bug 65263
wfDebug( "Connection lost, reconnecting...\n" );
if ( $this->ping() ) {
+ global $wgRequestTime;
wfDebug( "Reconnected\n" );
$sqlx = substr( $commentedSql, 0, 500 );
$sqlx = strtr( $sqlx, "\t\n", ' ' );
- global $wgRequestTime;
$elapsed = round( microtime( true ) - $wgRequestTime, 3 );
if ( $elapsed < 300 ) {
# Not a database error to lose a transaction after a minute or two
wfLogDBError( "Connection lost and reconnected after {$elapsed}s, query: $sqlx" );
}
- if ( !$hadTrx ) {
- # Should be safe to silently retry
+ if ( $hadTrx ) {
+ # Leave $ret as false and let an error be reported.
+ # Callers may catch the exception and continue to use the DB.
+ } else {
+ # Should be safe to silently retry (no trx and thus no callbacks)
$ret = $this->doQuery( $commentedSql );
}
} else {
/**
* Execute a prepared query with the various arguments
- * @param string $prepared the prepared sql
+ * @param string $prepared The prepared sql
* @param mixed $args Either an array here, or put scalars as varargs
*
* @return ResultWrapper
* For faking prepared SQL statements on DBs that don't support it directly.
*
* @param string $preparedQuery A 'preparable' SQL statement
- * @param array $args of Arguments to fill it with
+ * @param array $args Array of Arguments to fill it with
* @return string Executable SQL
*/
public function fillPrepared( $preparedQuery, $args ) {
* array(baseKeyVal => array(subKeyVal => [ignored], ...), ...)
* @param string $baseKey Field name to match the base-level keys to (eg 'pl_namespace')
* @param string $subKey Field name to match the sub-level keys to (eg 'pl_title')
- * @return Mixed: string SQL fragment, or false if no items in array.
+ * @return string|bool string SQL fragment, or false if no items in array.
*/
public function makeWhereFrom2d( $data, $baseKey, $subKey ) {
$conds = array();
/**
* Return aggregated value alias
*
- * @param $valuedata
+ * @param array $valuedata
* @param string $valuename
*
* @return string
*
* @todo Explain what exactly will fail if this is not overridden.
*
- * @param $db
+ * @param string $db
*
* @return bool Success or failure
*/
/**
* Get the current DB name
+ * @return string
*/
public function getDBname() {
return $this->mDBname;
/**
* Get the server hostname or IP address
+ * @return string
*/
public function getServer() {
return $this->mServer;
/**
* Returns true if current database backend supports ORDER BY or LIMIT for separate subqueries
* within the UNION construct.
- * @return Boolean
+ * @return bool
*/
public function unionSupportsOrderAndLimit() {
return true; // True for almost every DB supported
$this->runOnTransactionPreCommitCallbacks();
$this->doCommit( $fname );
if ( $this->mTrxDoneWrites ) {
- Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname );
+ $id = spl_object_hash( $this );
+ Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname, $id );
}
$this->runOnTransactionIdleCallbacks();
}
+ # Avoid fatals if close() was called
+ if ( !$this->isOpen() ) {
+ throw new DBUnexpectedError( $this, "DB connection was already closed." );
+ }
+
$this->doBegin( $fname );
$this->mTrxFname = $fname;
$this->mTrxDoneWrites = false;
}
}
+ # Avoid fatals if close() was called
+ if ( !$this->isOpen() ) {
+ throw new DBUnexpectedError( $this, "DB connection was already closed." );
+ }
+
$this->runOnTransactionPreCommitCallbacks();
$this->doCommit( $fname );
if ( $this->mTrxDoneWrites ) {
- Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname );
+ $id = spl_object_hash( $this );
+ Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname, $id );
}
$this->runOnTransactionIdleCallbacks();
}
}
}
+ # Avoid fatals if close() was called
+ if ( !$this->isOpen() ) {
+ throw new DBUnexpectedError( $this, "DB connection was already closed." );
+ }
+
$this->doRollback( $fname );
$this->mTrxIdleCallbacks = array(); // cancel
$this->mTrxPreCommitCallbacks = array(); // cancel
$this->mTrxAtomicLevels = new SplStack;
if ( $this->mTrxDoneWrites ) {
- Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname );
+ $id = spl_object_hash( $this );
+ Profiler::instance()->transactionWritingOut( $this->mServer, $this->mDBname, $id );
}
}