X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Flibs%2Frdbms%2Fdatabase%2FDatabase.php;h=2eb5c5483daec835e48adcc45288228d8f323adc;hb=bdf062a8e9f351d3b94f99f2cbe9f7176f0b8801;hp=e04566eb497c9f2b747088902ca92645f5ee6768;hpb=3dde125644219cf58bfb765733462031f5c3287a;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/libs/rdbms/database/Database.php b/includes/libs/rdbms/database/Database.php index e04566eb49..2eb5c5483d 100644 --- a/includes/libs/rdbms/database/Database.php +++ b/includes/libs/rdbms/database/Database.php @@ -394,7 +394,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware $p['variables'] = isset( $p['variables'] ) ? $p['variables'] : []; $p['tablePrefix'] = isset( $p['tablePrefix'] ) ? $p['tablePrefix'] : ''; $p['schema'] = isset( $p['schema'] ) ? $p['schema'] : ''; - $p['cliMode'] = isset( $p['cliMode'] ) ? $p['cliMode'] : ( PHP_SAPI === 'cli' ); + $p['cliMode'] = isset( $p['cliMode'] ) + ? $p['cliMode'] + : ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' ); $p['agent'] = isset( $p['agent'] ) ? $p['agent'] : ''; if ( !isset( $p['connLogger'] ) ) { $p['connLogger'] = new \Psr\Log\NullLogger(); @@ -461,9 +463,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware protected function ignoreErrors( $ignoreErrors = null ) { $res = $this->getFlag( self::DBO_IGNORE ); if ( $ignoreErrors !== null ) { - $ignoreErrors - ? $this->setFlag( self::DBO_IGNORE ) - : $this->clearFlag( self::DBO_IGNORE ); + // setFlag()/clearFlag() do not allow DBO_IGNORE changes for sanity + if ( $ignoreErrors ) { + $this->mFlags |= self::DBO_IGNORE; + } else { + $this->mFlags &= ~self::DBO_IGNORE; + } } return $res; @@ -621,6 +626,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware } public function setFlag( $flag, $remember = self::REMEMBER_NOTHING ) { + if ( ( $flag & self::DBO_IGNORE ) ) { + throw new \UnexpectedValueException( "Modifying DBO_IGNORE is not allowed." ); + } + if ( $remember === self::REMEMBER_PRIOR ) { array_push( $this->priorFlags, $this->mFlags ); } @@ -628,6 +637,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware } public function clearFlag( $flag, $remember = self::REMEMBER_NOTHING ) { + if ( ( $flag & self::DBO_IGNORE ) ) { + throw new \UnexpectedValueException( "Modifying DBO_IGNORE is not allowed." ); + } + if ( $remember === self::REMEMBER_PRIOR ) { array_push( $this->priorFlags, $this->mFlags ); } @@ -897,6 +910,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware } if ( $isWrite ) { + if ( $this->getLBInfo( 'replica' ) === true ) { + throw new DBError( + $this, + 'Write operations are not allowed on replica database connections.' + ); + } # In theory, non-persistent writes are allowed in read-only mode, but due to things # like https://bugs.mysql.com/bug.php?id=33669 that might not work anyway... $reason = $this->getReadOnlyReason(); @@ -2019,9 +2038,19 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware if ( is_array( $table ) ) { // A parenthesized group - $joinedTable = '(' - . $this->tableNamesWithIndexClauseOrJOIN( $table, $use_index, $ignore_index, $join_conds ) - . ')'; + if ( count( $table ) > 1 ) { + $joinedTable = '(' + . $this->tableNamesWithIndexClauseOrJOIN( $table, $use_index, $ignore_index, $join_conds ) + . ')'; + } else { + // Degenerate case + $innerTable = reset( $table ); + $innerAlias = key( $table ); + $joinedTable = $this->tableNameWithAlias( + $innerTable, + is_string( $innerAlias ) ? $innerAlias : $innerTable + ); + } } else { $joinedTable = $this->tableNameWithAlias( $table, $alias ); } @@ -3273,14 +3302,15 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware * @see WANObjectCache::getWithSetCallback() * * @param IDatabase $db1 - * @param IDatabase $dbs,... + * @param IDatabase $db2 [optional] * @return array Map of values: * - lag: highest lag of any of the DBs or false on error (e.g. replication stopped) * - since: oldest UNIX timestamp of any of the DB lag estimates * - pending: whether any of the DBs have uncommitted changes + * @throws DBError * @since 1.27 */ - public static function getCacheSetOptions( IDatabase $db1 ) { + public static function getCacheSetOptions( IDatabase $db1, IDatabase $db2 = null ) { $res = [ 'lag' => 0, 'since' => INF, 'pending' => false ]; foreach ( func_get_args() as $db ) { /** @var IDatabase $db */ @@ -3362,6 +3392,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware $fname = __METHOD__, callable $inputCallback = null ) { + $delimiterReset = new ScopedCallback( + function ( $delimiter ) { + $this->delimiter = $delimiter; + }, + [ $this->delimiter ] + ); $cmd = ''; while ( !feof( $fp ) ) { @@ -3390,7 +3426,15 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware if ( $done || feof( $fp ) ) { $cmd = $this->replaceVars( $cmd ); - if ( !$inputCallback || call_user_func( $inputCallback, $cmd ) ) { + if ( $inputCallback ) { + $callbackResult = call_user_func( $inputCallback, $cmd ); + + if ( is_string( $callbackResult ) || !$callbackResult ) { + $cmd = $callbackResult; + } + } + + if ( $cmd ) { $res = $this->query( $cmd, $fname ); if ( $resultCallback ) { @@ -3407,6 +3451,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware } } + ScopedCallback::consume( $delimiterReset ); return true; }