use Psr\Log\LoggerInterface;
/**
- * Database abstraction object
+ * Relational database abstraction object
+ *
* @ingroup Database
+ * @since 1.28
*/
-abstract class Database implements IDatabase, LoggerAwareInterface {
+abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAwareInterface {
/** Number of times to re-try an operation in case of deadlock */
const DEADLOCK_TRIES = 4;
/** Minimum time to wait before retry, in microseconds */
* Either a short hexidecimal string if a transaction is active or ""
*
* @var string
- * @see DatabaseBase::mTrxLevel
+ * @see Database::mTrxLevel
*/
protected $mTrxShortId = '';
/**
* point (possibly more up-to-date since the first SELECT defines the snapshot).
*
* @var float|null
- * @see DatabaseBase::mTrxLevel
+ * @see Database::mTrxLevel
*/
private $mTrxTimestamp = null;
/** @var float Lag estimate at the time of BEGIN */
* Used to provide additional context for error reporting.
*
* @var string
- * @see DatabaseBase::mTrxLevel
+ * @see Database::mTrxLevel
*/
private $mTrxFname = null;
/**
* Record if possible write queries were done in the last transaction started
*
* @var bool
- * @see DatabaseBase::mTrxLevel
+ * @see Database::mTrxLevel
*/
private $mTrxDoneWrites = false;
/**
* Record if the current transaction was started implicitly due to DBO_TRX being set.
*
* @var bool
- * @see DatabaseBase::mTrxLevel
+ * @see Database::mTrxLevel
*/
private $mTrxAutomatic = false;
/**
*/
private $mTrxAtomicLevels = [];
/**
- * Record if the current transaction was started implicitly by DatabaseBase::startAtomic
+ * Record if the current transaction was started implicitly by Database::startAtomic
*
* @var bool
*/
/** @var IDatabase|null Lazy handle to the master DB this server replicates from */
private $lazyMasterHandle;
- /**
- * @since 1.22
- * @var string[] Process cache of VIEWs names in the database
- */
- protected $allViews = null;
-
/** @var float UNIX timestamp */
protected $lastPing = 0.0;
$this->agent = str_replace( '/', '-', $params['agent'] );
$this->mFlags = $params['flags'];
- if ( $this->mFlags & DBO_DEFAULT ) {
+ if ( $this->mFlags & self::DBO_DEFAULT ) {
if ( $this->cliMode ) {
- $this->mFlags &= ~DBO_TRX;
+ $this->mFlags &= ~self::DBO_TRX;
} else {
- $this->mFlags |= DBO_TRX;
+ $this->mFlags |= self::DBO_TRX;
}
}
}
public function bufferResults( $buffer = null ) {
- $res = !$this->getFlag( DBO_NOBUFFER );
+ $res = !$this->getFlag( self::DBO_NOBUFFER );
if ( $buffer !== null ) {
- $buffer ? $this->clearFlag( DBO_NOBUFFER ) : $this->setFlag( DBO_NOBUFFER );
+ $buffer
+ ? $this->clearFlag( self::DBO_NOBUFFER )
+ : $this->setFlag( self::DBO_NOBUFFER );
}
return $res;
* @return bool The previous value of the flag.
*/
protected function ignoreErrors( $ignoreErrors = null ) {
- $res = $this->getFlag( DBO_IGNORE );
+ $res = $this->getFlag( self::DBO_IGNORE );
if ( $ignoreErrors !== null ) {
- $ignoreErrors ? $this->setFlag( DBO_IGNORE ) : $this->clearFlag( DBO_IGNORE );
+ $ignoreErrors
+ ? $this->setFlag( self::DBO_IGNORE )
+ : $this->clearFlag( self::DBO_IGNORE );
}
return $res;
* @see setLazyMasterHandle()
* @since 1.27
*/
- public function getLazyMasterHandle() {
+ protected function getLazyMasterHandle() {
return $this->lazyMasterHandle;
}
$commentedSql = preg_replace( '/\s|$/', " /* $fname {$this->agent} */ ", $sql, 1 );
# Start implicit transactions that wrap the request if DBO_TRX is enabled
- if ( !$this->mTrxLevel && $this->getFlag( DBO_TRX )
+ if ( !$this->mTrxLevel && $this->getFlag( self::DBO_TRX )
&& $this->isTransactableQuery( $sql )
) {
$this->begin( __METHOD__ . " ($fname)", self::TRANSACTION_INTERNAL );
$this->mServer, $this->mDBname, $this->mTrxShortId );
}
- if ( $this->getFlag( DBO_DEBUG ) ) {
+ if ( $this->getFlag( self::DBO_DEBUG ) ) {
$this->queryLogger->debug( "{$this->mDBname} {$commentedSql}" );
}
* @param array $options Associative array of options to be turned into
* an SQL query, valid keys are listed in the function.
* @return array
- * @see DatabaseBase::select()
+ * @see Database::select()
*/
protected function makeSelectOptions( $options ) {
$preLimitTail = $postLimitTail = '';
*
* @param array $options Associative array of options
* @return string
- * @see DatabaseBase::select()
+ * @see Database::select()
* @since 1.21
*/
protected function makeGroupByWithHaving( $options ) {
*
* @param array $options Associative array of options
* @return string
- * @see DatabaseBase::select()
+ * @see Database::select()
* @since 1.21
*/
protected function makeOrderBy( $options ) {
}
/**
- * Helper for DatabaseBase::insert().
+ * Helper for Database::insert().
*
* @param array $options
* @return string
}
/**
- * Make UPDATE options array for DatabaseBase::makeUpdateOptions
+ * Make UPDATE options array for Database::makeUpdateOptions
*
* @param array $options
* @return array
}
/**
- * Make UPDATE options for the DatabaseBase::update function
+ * Make UPDATE options for the Database::update function
*
- * @param array $options The options passed to DatabaseBase::update
+ * @param array $options The options passed to Database::update
* @return string
*/
protected function makeUpdateOptions( $options ) {
return $this->mServer;
}
- /**
- * Format a table name ready for use in constructing an SQL query
- *
- * This does two important things: it quotes the table names to clean them up,
- * and it adds a table prefix if only given a table name with no quotes.
- *
- * All functions of this object which require a table name call this function
- * themselves. Pass the canonical name to such functions. This is only needed
- * when calling query() directly.
- *
- * @note This function does not sanitize user input. It is not safe to use
- * this function to escape user input.
- * @param string $name Database table name
- * @param string $format One of:
- * quoted - Automatically pass the table name through addIdentifierQuotes()
- * so that it can be used in a query.
- * raw - Do not add identifier quotes to the table name
- * @return string Full database name
- */
public function tableName( $name, $format = 'quoted' ) {
# Skip the entire process when we have a string quoted on both ends.
# Note that we check the end so that we will still quote any use of
return $tableName;
}
- /**
- * Fetch a number of table names into an array
- * This is handy when you need to construct SQL for joins
- *
- * Example:
- * extract( $dbr->tableNames( 'user', 'watchlist' ) );
- * $sql = "SELECT wl_namespace,wl_title FROM $watchlist,$user
- * WHERE wl_user=user_id AND wl_user=$nameWithQuotes";
- *
- * @return array
- */
public function tableNames() {
$inArray = func_get_args();
$retVal = [];
return $retVal;
}
- /**
- * Fetch a number of table names into an zero-indexed numerical array
- * This is handy when you need to construct SQL for joins
- *
- * Example:
- * list( $user, $watchlist ) = $dbr->tableNamesN( 'user', 'watchlist' );
- * $sql = "SELECT wl_namespace,wl_title FROM $watchlist,$user
- * WHERE wl_user=user_id AND wl_user=$nameWithQuotes";
- *
- * @return array
- */
public function tableNamesN() {
$inArray = func_get_args();
$retVal = [];
$this->query( $sql, $fname );
}
- /**
- * Returns the size of a text field, or -1 for "unlimited"
- *
- * @param string $table
- * @param string $field
- * @return int
- */
public function textFieldSize( $table, $field ) {
$table = $this->tableName( $table );
$sql = "SHOW COLUMNS FROM $table LIKE \"$field\";";
return false;
}
- /**
- * Perform a deadlock-prone transaction.
- *
- * This function invokes a callback function to perform a set of write
- * queries. If a deadlock occurs during the processing, the transaction
- * will be rolled back and the callback function will be called again.
- *
- * Avoid using this method outside of Job or Maintenance classes.
- *
- * Usage:
- * $dbw->deadlockLoop( callback, ... );
- *
- * Extra arguments are passed through to the specified callback function.
- * This method requires that no transactions are already active to avoid
- * causing premature commits or exceptions.
- *
- * Returns whatever the callback function returned on its successful,
- * iteration, or false on error, for example if the retry limit was
- * reached.
- *
- * @return mixed
- * @throws DBUnexpectedError
- * @throws Exception
- */
public function deadlockLoop() {
$args = func_get_args();
$function = array_shift( $args );
return 0;
}
- public function getSlavePos() {
+ public function getReplicaPos() {
# Stub
return false;
}
return;
}
- $autoTrx = $this->getFlag( DBO_TRX ); // automatic begin() enabled?
+ $autoTrx = $this->getFlag( self::DBO_TRX ); // automatic begin() enabled?
/** @var Exception $e */
$e = null; // first exception
do { // callbacks may add callbacks :)
foreach ( $callbacks as $callback ) {
try {
list( $phpCallback ) = $callback;
- $this->clearFlag( DBO_TRX ); // make each query its own transaction
+ $this->clearFlag( self::DBO_TRX ); // make each query its own transaction
call_user_func_array( $phpCallback, [ $trigger ] );
if ( $autoTrx ) {
- $this->setFlag( DBO_TRX ); // restore automatic begin()
+ $this->setFlag( self::DBO_TRX ); // restore automatic begin()
} else {
- $this->clearFlag( DBO_TRX ); // restore auto-commit
+ $this->clearFlag( self::DBO_TRX ); // restore auto-commit
}
} catch ( Exception $ex ) {
call_user_func( $this->errorLogger, $ex );
$this->begin( $fname, self::TRANSACTION_INTERNAL );
// If DBO_TRX is set, a series of startAtomic/endAtomic pairs will result
// in all changes being in one transaction to keep requests transactional.
- if ( !$this->getFlag( DBO_TRX ) ) {
+ if ( !$this->getFlag( self::DBO_TRX ) ) {
$this->mTrxAutomaticAtomic = true;
}
}
$this->queryLogger->error( $msg );
return; // join the main transaction set
}
- } elseif ( $this->getFlag( DBO_TRX ) && $mode !== self::TRANSACTION_INTERNAL ) {
+ } elseif ( $this->getFlag( self::DBO_TRX ) && $mode !== self::TRANSACTION_INTERNAL ) {
// @TODO: make this an exception at some point
$msg = "$fname: Implicit transaction expected (DBO_TRX set).";
$this->queryLogger->error( $msg );
/**
* Issues the BEGIN command to the database server.
*
- * @see DatabaseBase::begin()
+ * @see Database::begin()
* @param string $fname
*/
protected function doBegin( $fname ) {
/**
* Issues the COMMIT command to the database server.
*
- * @see DatabaseBase::commit()
+ * @see Database::commit()
* @param string $fname
*/
protected function doCommit( $fname ) {
$this->queryLogger->error(
"$fname: No transaction to rollback, something got out of sync." );
return; // nothing to do
- } elseif ( $this->getFlag( DBO_TRX ) ) {
+ } elseif ( $this->getFlag( self::DBO_TRX ) ) {
throw new DBUnexpectedError(
$this,
"$fname: Expected mass rollback of all peer databases (DBO_TRX set)."
/**
* Issues the ROLLBACK command to the database server.
*
- * @see DatabaseBase::rollback()
+ * @see Database::rollback()
* @param string $fname
*/
protected function doRollback( $fname ) {
throw new RuntimeException( __METHOD__ . ' is not implemented in descendant class' );
}
- /**
- * Reset the views process cache set by listViews()
- * @since 1.22
- */
- final public function clearViewsCache() {
- $this->allViews = null;
- }
-
- /**
- * Lists all the VIEWs in the database
- *
- * For caching purposes the list of all views should be stored in
- * $this->allViews. The process cache can be cleared with clearViewsCache()
- *
- * @param string $prefix Only show VIEWs with this prefix, eg. unit_test_
- * @param string $fname Name of calling function
- * @throws RuntimeException
- * @return array
- * @since 1.22
- */
public function listViews( $prefix = null, $fname = __METHOD__ ) {
throw new RuntimeException( __METHOD__ . ' is not implemented in descendant class' );
}
- /**
- * Differentiates between a TABLE and a VIEW
- *
- * @param string $name Name of the database-structure to test.
- * @throws RuntimeException
- * @return bool
- * @since 1.22
- */
- public function isView( $name ) {
- throw new RuntimeException( __METHOD__ . ' is not implemented in descendant class' );
- }
-
public function timestamp( $ts = 0 ) {
$t = new ConvertibleTimestamp( $ts );
// Let errors bubble up to avoid putting garbage in the DB
* necessary. Boolean values are passed through as is, to indicate success
* of write queries or failure.
*
- * Once upon a time, DatabaseBase::query() returned a bare MySQL result
+ * Once upon a time, Database::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.
}
// This will reconnect if possible or return false if not
- $this->clearFlag( DBO_TRX, self::REMEMBER_PRIOR );
+ $this->clearFlag( self::DBO_TRX, self::REMEMBER_PRIOR );
$ok = ( $this->query( self::PING_QUERY, __METHOD__, true ) !== false );
$this->restoreFlags( self::RESTORE_PRIOR );
public function setSessionOptions( array $options ) {
}
- /**
- * Read and execute SQL commands from a file.
- *
- * Returns true on success, error string or exception on failure (depending
- * on object's error ignore settings).
- *
- * @param string $filename File name to open
- * @param bool|callable $lineCallback Optional function called before reading each line
- * @param bool|callable $resultCallback Optional function called for each MySQL result
- * @param bool|string $fname Calling function name or false if name should be
- * generated dynamically using $filename
- * @param bool|callable $inputCallback Optional function called for each
- * complete line sent
- * @return bool|string
- * @throws Exception
- */
public function sourceFile(
$filename,
- $lineCallback = false,
- $resultCallback = false,
+ callable $lineCallback = null,
+ callable $resultCallback = null,
$fname = false,
- $inputCallback = false
+ callable $inputCallback = null
) {
MediaWiki\suppressWarnings();
$fp = fopen( $filename, 'r' );
$this->mSchemaVars = $vars;
}
- /**
- * Read and execute commands from an open file handle.
- *
- * Returns true on success, error string or exception on failure (depending
- * on object's error ignore settings).
- *
- * @param resource $fp File handle
- * @param bool|callable $lineCallback Optional function called before reading each query
- * @param bool|callable $resultCallback Optional function called for each MySQL result
- * @param string $fname Calling function name
- * @param bool|callable $inputCallback Optional function called for each complete query sent
- * @return bool|string
- */
public function sourceStream(
$fp,
- $lineCallback = false,
- $resultCallback = false,
+ callable $lineCallback = null,
+ callable $resultCallback = null,
$fname = __METHOD__,
- $inputCallback = false
+ callable $inputCallback = null
) {
$cmd = '';
}
}
}
+
+class_alias( 'Database', 'DatabaseBase' );