/**
* Array of levels of atomicity within transactions
*
- * @var SplStack
+ * @var array
*/
- private $mTrxAtomicLevels;
+ private $mTrxAtomicLevels = array();
/**
* Record if the current transaction was started implicitly by DatabaseBase::startAtomic
}
}
- /**
- * Set lag time in seconds for a fake slave
- *
- * @param mixed $lag Valid values for this parameter are determined by the
- * subclass, but should be a PHP scalar or array that would be sensible
- * as part of $wgLBFactoryConf.
- */
- public function setFakeSlaveLag( $lag ) {
- }
-
- /**
- * Make this connection a fake master
- *
- * @param bool $enabled
- */
- public function setFakeMaster( $enabled = true ) {
- }
-
/**
* @return TransactionProfiler
*/
function __construct( array $params ) {
global $wgDBprefix, $wgDBmwschema, $wgCommandLineMode, $wgDebugDBTransactions;
- $this->mTrxAtomicLevels = new SplStack;
-
$server = $params['host'];
$user = $params['user'];
$password = $params['password'];
$isWriteQuery = $this->isWriteQuery( $sql );
if ( $isWriteQuery ) {
- if ( !$this->mDoneWrites ) {
- wfDebug( __METHOD__ . ': Writes done: ' .
- DatabaseBase::generalizeSQL( $sql ) . "\n" );
+ $reason = $this->getLBInfo( 'readOnlyReason' );
+ if ( is_string( $reason ) ) {
+ throw new DBReadOnlyError( $this, "Database is read-only: $reason" );
}
# Set a flag indicating that writes have been done
$this->mDoneWrites = microtime( true );
$res = $this->resultObject( $ret );
// Destroy profile sections in the opposite order to their creation
- $queryProfSection = false;
- $totalProfSection = false;
+ ScopedCallback::consume( $queryProfSection );
+ ScopedCallback::consume( $totalProfSection );
if ( $isWriteQuery && $this->mTrxLevel ) {
$this->mTrxWriteDuration += $queryRuntime;
* @param string|array $options The query options. See DatabaseBase::select() for details.
*
* @return bool|mixed The value from the field, or false on failure.
+ * @throws DBUnexpectedError
*/
public function selectField(
$table, $var, $cond = '', $fname = __METHOD__, $options = array()
$preLimitTail .= $this->makeOrderBy( $options );
// if (isset($options['LIMIT'])) {
- // $tailOpts .= $this->limitResult('', $options['LIMIT'],
- // isset($options['OFFSET']) ? $options['OFFSET']
- // : false);
+ // $tailOpts .= $this->limitResult('', $options['LIMIT'],
+ // isset($options['OFFSET']) ? $options['OFFSET']
+ // : false);
// }
if ( isset( $noKeyOptions['FOR UPDATE'] ) ) {
if ( !$alias || (string)$alias === (string)$name ) {
return $name;
} else {
- return $name . ' AS ' . $alias; //PostgreSQL needs AS
+ return $name . ' AS ' . $alias; // PostgreSQL needs AS
}
}
$args = func_get_args();
$function = array_shift( $args );
$tries = self::DEADLOCK_TRIES;
- if ( is_array( $function ) ) {
- $fname = $function[0];
- } else {
- $fname = $function;
- }
$this->begin( __METHOD__ );
}
}
- $this->mTrxAtomicLevels->push( $fname );
+ $this->mTrxAtomicLevels[] = $fname;
}
/**
if ( !$this->mTrxLevel ) {
throw new DBUnexpectedError( $this, 'No atomic transaction is open.' );
}
- if ( $this->mTrxAtomicLevels->isEmpty() ||
- $this->mTrxAtomicLevels->pop() !== $fname
+ if ( !$this->mTrxAtomicLevels ||
+ array_pop( $this->mTrxAtomicLevels ) !== $fname
) {
throw new DBUnexpectedError( $this, 'Invalid atomic section ended.' );
}
- if ( $this->mTrxAtomicLevels->isEmpty() && $this->mTrxAutomaticAtomic ) {
+ if ( !$this->mTrxAtomicLevels && $this->mTrxAutomaticAtomic ) {
$this->commit( $fname, 'flush' );
}
}
global $wgDebugDBTransactions;
if ( $this->mTrxLevel ) { // implicit commit
- if ( !$this->mTrxAtomicLevels->isEmpty() ) {
+ if ( $this->mTrxAtomicLevels ) {
// If the current transaction was an automatic atomic one, then we definitely have
// a problem. Same if there is any unclosed atomic level.
throw new DBUnexpectedError( $this,
$this->mTrxDoneWrites = false;
$this->mTrxAutomatic = false;
$this->mTrxAutomaticAtomic = false;
- $this->mTrxAtomicLevels = new SplStack;
+ $this->mTrxAtomicLevels = array();
$this->mTrxIdleCallbacks = array();
$this->mTrxPreCommitCallbacks = array();
$this->mTrxShortId = wfRandomString( 12 );
* @throws DBUnexpectedError
*/
final public function commit( $fname = __METHOD__, $flush = '' ) {
- if ( !$this->mTrxAtomicLevels->isEmpty() ) {
+ if ( $this->mTrxLevel && $this->mTrxAtomicLevels ) {
// There are still atomic sections open. This cannot be ignored
throw new DBUnexpectedError(
$this,
$this->doRollback( $fname );
$this->mTrxIdleCallbacks = array(); // cancel
$this->mTrxPreCommitCallbacks = array(); // cancel
- $this->mTrxAtomicLevels = new SplStack;
+ $this->mTrxAtomicLevels = array();
if ( $this->mTrxDoneWrites ) {
$this->getTransactionProfiler()->transactionWritingOut(
$this->mServer, $this->mDBname, $this->mTrxShortId );
* Once upon a time, DatabaseBase::query() returned a bare MySQL result
* resource, and it was necessary to call this function to convert it to
* a wrapper. Nowadays, raw database objects are never exposed to external
- * callers, so this is unnecessary in external code. For compatibility with
- * old code, ResultWrapper objects are passed through unaltered.
+ * callers, so this is unnecessary in external code.
*
- * @param bool|ResultWrapper|resource $result
+ * @param bool|ResultWrapper|resource|object $result
* @return bool|ResultWrapper
*/
- public function resultObject( $result ) {
- if ( empty( $result ) ) {
+ protected function resultObject( $result ) {
+ if ( !$result ) {
return false;
} elseif ( $result instanceof ResultWrapper ) {
return $result;