/** @var array Map of (name => 1) for locks obtained via lock() */
private $mNamedLocksHeld = [];
/** @var array Map of (table name => 1) for TEMPORARY tables */
- private $mSessionTempTables = [];
+ protected $mSessionTempTables = [];
/** @var IDatabase|null Lazy handle to the master DB this server replicates from */
private $lazyMasterHandle;
- /**
- * @since 1.21
- * @var resource File handle for upgrade
- */
- protected $fileHandle = null;
-
/**
* @since 1.22
* @var string[] Process cache of VIEWs names in the database
$this->trxProfiler = $params['trxProfiler'];
$this->connLogger = $params['connLogger'];
$this->queryLogger = $params['queryLogger'];
+ $this->errorLogger = $params['errorLogger'];
// Set initial dummy domain until open() sets the final DB/prefix
$this->currentDomain = DatabaseDomain::newUnspecified();
return $old;
}
- /**
- * Set the filehandle to copy write statements to.
- *
- * @param resource $fh File handle
- */
- public function setFileHandle( $fh ) {
- $this->fileHandle = $fh;
- }
-
public function getLBInfo( $name = null ) {
if ( is_null( $name ) ) {
return $this->mLBInfo;
protected function installErrorHandler() {
$this->mPHPError = false;
$this->htmlErrors = ini_set( 'html_errors', '0' );
- set_error_handler( [ $this, 'connectionerrorLogger' ] );
+ set_error_handler( [ $this, 'connectionErrorLogger' ] );
}
/**
}
/**
+ * This method should not be used outside of Database classes
+ *
* @param int $errno
* @param string $errstr
*/
- public function connectionerrorLogger( $errno, $errstr ) {
+ public function connectionErrorLogger( $errno, $errstr ) {
$this->mPHPError = $errstr;
}
*/
abstract protected function closeConnection();
- function reportConnectionError( $error = 'Unknown error' ) {
+ public function reportConnectionError( $error = 'Unknown error' ) {
$myError = $this->lastError();
if ( $myError ) {
$error = $myError;
*/
protected function registerTempTableOperation( $sql ) {
if ( preg_match(
- '/^(CREATE|DROP)\s+TEMPORARY\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?[`"\']?(\w+)[`"\']?/i',
+ '/^CREATE\s+TEMPORARY\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?[`"\']?(\w+)[`"\']?/i',
$sql,
$matches
) ) {
- list( , $verb, $table ) = $matches;
- if ( $verb === 'CREATE' ) {
- $this->mSessionTempTables[$table] = 1;
- } else {
- unset( $this->mSessionTempTables[$table] );
- }
+ $this->mSessionTempTables[$matches[1]] = 1;
+
+ return true;
+ } elseif ( preg_match(
+ '/^DROP\s+(?:TEMPORARY\s+)?TABLE\s+(?:IF\s+EXISTS\s+)?[`"\']?(\w+)[`"\']?/i',
+ $sql,
+ $matches
+ ) ) {
+ unset( $this->mSessionTempTables[$matches[1]] );
return true;
} elseif ( preg_match(
* @return array
* @see DatabaseBase::select()
*/
- public function makeSelectOptions( $options ) {
+ protected function makeSelectOptions( $options ) {
$preLimitTail = $postLimitTail = '';
$startOpts = '';
* @see DatabaseBase::select()
* @since 1.21
*/
- public function makeGroupByWithHaving( $options ) {
+ protected function makeGroupByWithHaving( $options ) {
$sql = '';
if ( isset( $options['GROUP BY'] ) ) {
$gb = is_array( $options['GROUP BY'] )
* @see DatabaseBase::select()
* @since 1.21
*/
- public function makeOrderBy( $options ) {
+ protected function makeOrderBy( $options ) {
if ( isset( $options['ORDER BY'] ) ) {
$ob = is_array( $options['ORDER BY'] )
? implode( ',', $options['ORDER BY'] )
}
public function tableExists( $table, $fname = __METHOD__ ) {
+ $tableRaw = $this->tableName( $table, 'raw' );
+ if ( isset( $this->mSessionTempTables[$tableRaw] ) ) {
+ return true; // already known to exist
+ }
+
$table = $this->tableName( $table );
$old = $this->ignoreErrors( true );
$res = $this->query( "SELECT 1 FROM $table LIMIT 1", $fname );
return implode( ' ', $opts );
}
- function update( $table, $values, $conds, $fname = __METHOD__, $options = [] ) {
+ public function update( $table, $values, $conds, $fname = __METHOD__, $options = [] ) {
$table = $this->tableName( $table );
$opts = $this->makeUpdateOptions( $options );
$sql = "UPDATE $opts $table SET " . $this->makeList( $values, self::LIST_SET );
}
}
- /**
- * Return aggregated value alias
- *
- * @param array $valuedata
- * @param string $valuename
- *
- * @return string
- */
public function aggregateValue( $valuedata, $valuename = 'value' ) {
return $valuename;
}
return '(' . $this->selectSQLText( $table, $fld, $conds, null, [], $join_conds ) . ')';
}
- /**
- * @param string $field Field or column to cast
- * @return string
- * @since 1.28
- */
public function buildStringCast( $field ) {
return $field;
}
* @param string|bool $alias Alias (optional)
* @return string SQL name for aliased table. Will not alias a table to its own name
*/
- public function tableNameWithAlias( $name, $alias = false ) {
+ protected function tableNameWithAlias( $name, $alias = false ) {
if ( !$alias || $alias == $name ) {
return $this->tableName( $name );
} else {
* @param array $tables [ [alias] => table ]
* @return string[] See tableNameWithAlias()
*/
- public function tableNamesWithAlias( $tables ) {
+ protected function tableNamesWithAlias( $tables ) {
$retval = [];
foreach ( $tables as $alias => $table ) {
if ( is_numeric( $alias ) ) {
* @param string|bool $alias Alias (optional)
* @return string SQL name for aliased field. Will not alias a field to its own name
*/
- public function fieldNameWithAlias( $name, $alias = false ) {
+ protected function fieldNameWithAlias( $name, $alias = false ) {
if ( !$alias || (string)$alias === (string)$name ) {
return $name;
} else {
* @param array $fields [ [alias] => field ]
* @return string[] See fieldNameWithAlias()
*/
- public function fieldNamesWithAlias( $fields ) {
+ protected function fieldNamesWithAlias( $fields ) {
$retval = [];
foreach ( $fields as $alias => $field ) {
if ( is_numeric( $alias ) ) {
return $this->insert( $destTable, $rows, $fname, $insertOptions );
}
- public function nativeInsertSelect( $destTable, $srcTable, $varMap, $conds,
+ protected function nativeInsertSelect( $destTable, $srcTable, $varMap, $conds,
$fname = __METHOD__,
$insertOptions = [], $selectOptions = []
) {
*/
public function limitResult( $sql, $limit, $offset = false ) {
if ( !is_numeric( $limit ) ) {
- throw new DBUnexpectedError( $this, "Invalid non-numeric limit passed to limitResult()\n" );
+ throw new DBUnexpectedError( $this,
+ "Invalid non-numeric limit passed to limitResult()\n" );
}
return "$sql LIMIT "
}
/**
- * Determines if the given query error was a connection drop
- * STUB
+ * Do no use the class outside of Database/DBError classes
*
* @param integer|string $errno
- * @return bool
+ * @return bool Whether the given query error was a connection drop
*/
public function wasConnectionError( $errno ) {
return false;
throw new RuntimeException( __METHOD__ . ' is not implemented in descendant class' );
}
- function listTables( $prefix = null, $fname = __METHOD__ ) {
+ public function listTables( $prefix = null, $fname = __METHOD__ ) {
throw new RuntimeException( __METHOD__ . ' is not implemented in descendant class' );
}
}
public function timestamp( $ts = 0 ) {
- $t = new ConvertableTimestamp( $ts );
+ $t = new ConvertibleTimestamp( $ts );
// Let errors bubble up to avoid putting garbage in the DB
return $t->getTimestamp( TS_MW );
}
* @return array|null ('lag': seconds or false on error, 'since': UNIX timestamp of BEGIN)
* @since 1.27
*/
- public function getTransactionLagStatus() {
+ protected function getTransactionLagStatus() {
return $this->mTrxLevel
? [ 'lag' => $this->mTrxReplicaLag, 'since' => $this->trxTimestamp() ]
: null;
* @return array ('lag': seconds or false on error, 'since': UNIX timestamp of estimate)
* @since 1.27
*/
- public function getApproximateLagStatus() {
+ protected function getApproximateLagStatus() {
return [
'lag' => $this->getLBInfo( 'replica' ) ? $this->getLag() : 0,
'since' => microtime( true )
return 0;
}
- function maxListLen() {
+ public function maxListLen() {
return 0;
}
return 'infinity';
}
- try {
- $t = new ConvertableTimestamp( $expiry );
-
- return $t->getTimestamp( $format );
- } catch ( TimestampException $e ) {
- return false;
- }
+ return ConvertibleTimestamp::convert( $format, $expiry );
}
public function setBigSelects( $value = true ) {
// Open a new connection resource without messing with the old one
$this->mOpened = false;
$this->mConn = false;
- $this->mTrxLevel = 0; // no trx anymore
+ $this->mTrxEndCallbacks = []; // don't copy
+ $this->handleSessionLoss(); // no trx or locks anymore
$this->open( $this->mServer, $this->mUser, $this->mPassword, $this->mDBname );
$this->lastPing = microtime( true );
}