From d9022f63880ce039446fba8364f68e656b7bf4cb Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Thu, 3 May 2012 13:01:35 +0200 Subject: Update to MediaWiki 1.19.0 --- includes/db/DatabaseMysql.php | 329 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 270 insertions(+), 59 deletions(-) (limited to 'includes/db/DatabaseMysql.php') diff --git a/includes/db/DatabaseMysql.php b/includes/db/DatabaseMysql.php index 6a81f234..c179b724 100644 --- a/includes/db/DatabaseMysql.php +++ b/includes/db/DatabaseMysql.php @@ -14,10 +14,18 @@ * @see Database */ class DatabaseMysql extends DatabaseBase { + + /** + * @return string + */ function getType() { return 'mysql'; } + /** + * @param $sql string + * @return resource + */ protected function doQuery( $sql ) { if( $this->bufferResults() ) { $ret = mysql_query( $sql, $this->mConn ); @@ -27,6 +35,14 @@ class DatabaseMysql extends DatabaseBase { return $ret; } + /** + * @param $server string + * @param $user string + * @param $password string + * @param $dbName string + * @return bool + * @throws DBConnectionError + */ function open( $server, $user, $password, $dbName ) { global $wgAllDBsAreLocalhost; wfProfileIn( __METHOD__ ); @@ -110,22 +126,19 @@ class DatabaseMysql extends DatabaseBase { } if ( $success ) { - $version = $this->getServerVersion(); - if ( version_compare( $version, '4.1' ) >= 0 ) { - // Tell the server we're communicating with it in UTF-8. - // This may engage various charset conversions. - global $wgDBmysql5; - if( $wgDBmysql5 ) { - $this->query( 'SET NAMES utf8', __METHOD__ ); - } else { - $this->query( 'SET NAMES binary', __METHOD__ ); - } - // Set SQL mode, default is turning them all off, can be overridden or skipped with null - global $wgSQLMode; - if ( is_string( $wgSQLMode ) ) { - $mode = $this->addQuotes( $wgSQLMode ); - $this->query( "SET sql_mode = $mode", __METHOD__ ); - } + // Tell the server we're communicating with it in UTF-8. + // This may engage various charset conversions. + global $wgDBmysql5; + if( $wgDBmysql5 ) { + $this->query( 'SET NAMES utf8', __METHOD__ ); + } else { + $this->query( 'SET NAMES binary', __METHOD__ ); + } + // Set SQL mode, default is turning them all off, can be overridden or skipped with null + global $wgSQLMode; + if ( is_string( $wgSQLMode ) ) { + $mode = $this->addQuotes( $wgSQLMode ); + $this->query( "SET sql_mode = $mode", __METHOD__ ); } // Turn off strict mode if it is on @@ -138,6 +151,9 @@ class DatabaseMysql extends DatabaseBase { return $success; } + /** + * @return bool + */ function close() { $this->mOpened = false; if ( $this->mConn ) { @@ -150,6 +166,10 @@ class DatabaseMysql extends DatabaseBase { } } + /** + * @param $res ResultWrapper + * @throws DBUnexpectedError + */ function freeResult( $res ) { if ( $res instanceof ResultWrapper ) { $res = $res->result; @@ -162,6 +182,11 @@ class DatabaseMysql extends DatabaseBase { } } + /** + * @param $res ResultWrapper + * @return object|stdClass + * @throws DBUnexpectedError + */ function fetchObject( $res ) { if ( $res instanceof ResultWrapper ) { $res = $res->result; @@ -175,7 +200,12 @@ class DatabaseMysql extends DatabaseBase { return $row; } - function fetchRow( $res ) { + /** + * @param $res ResultWrapper + * @return array + * @throws DBUnexpectedError + */ + function fetchRow( $res ) { if ( $res instanceof ResultWrapper ) { $res = $res->result; } @@ -188,6 +218,11 @@ class DatabaseMysql extends DatabaseBase { return $row; } + /** + * @throws DBUnexpectedError + * @param $res ResultWrapper + * @return int + */ function numRows( $res ) { if ( $res instanceof ResultWrapper ) { $res = $res->result; @@ -201,6 +236,10 @@ class DatabaseMysql extends DatabaseBase { return $n; } + /** + * @param $res ResultWrapper + * @return int + */ function numFields( $res ) { if ( $res instanceof ResultWrapper ) { $res = $res->result; @@ -208,6 +247,11 @@ class DatabaseMysql extends DatabaseBase { return mysql_num_fields( $res ); } + /** + * @param $res ResultWrapper + * @param $n string + * @return string + */ function fieldName( $res, $n ) { if ( $res instanceof ResultWrapper ) { $res = $res->result; @@ -215,8 +259,18 @@ class DatabaseMysql extends DatabaseBase { return mysql_field_name( $res, $n ); } - function insertId() { return mysql_insert_id( $this->mConn ); } + /** + * @return int + */ + function insertId() { + return mysql_insert_id( $this->mConn ); + } + /** + * @param $res ResultWrapper + * @param $row + * @return bool + */ function dataSeek( $res, $row ) { if ( $res instanceof ResultWrapper ) { $res = $res->result; @@ -224,6 +278,9 @@ class DatabaseMysql extends DatabaseBase { return mysql_data_seek( $res, $row ); } + /** + * @return int + */ function lastErrno() { if ( $this->mConn ) { return mysql_errno( $this->mConn ); @@ -232,6 +289,9 @@ class DatabaseMysql extends DatabaseBase { } } + /** + * @return string + */ function lastError() { if ( $this->mConn ) { # Even if it's non-zero, it can still be invalid @@ -250,8 +310,20 @@ class DatabaseMysql extends DatabaseBase { return $error; } - function affectedRows() { return mysql_affected_rows( $this->mConn ); } + /** + * @return int + */ + function affectedRows() { + return mysql_affected_rows( $this->mConn ); + } + /** + * @param $table string + * @param $uniqueIndexes + * @param $rows array + * @param $fname string + * @return ResultWrapper + */ function replace( $table, $uniqueIndexes, $rows, $fname = 'DatabaseMysql::replace' ) { return $this->nativeReplace( $table, $rows, $fname ); } @@ -260,6 +332,13 @@ class DatabaseMysql extends DatabaseBase { * Estimate rows in dataset * Returns estimated count, based on EXPLAIN output * Takes same arguments as Database::select() + * + * @param $table string|array + * @param $vars string|array + * @param $conds string|array + * @param $fname string + * @param $options string|array + * @return int */ public function estimateRowCount( $table, $vars='*', $conds='', $fname = 'DatabaseMysql::estimateRowCount', $options = array() ) { $options['EXPLAIN'] = true; @@ -278,6 +357,11 @@ class DatabaseMysql extends DatabaseBase { return $rows; } + /** + * @param $table string + * @param $field string + * @return bool|MySQLField + */ function fieldInfo( $table, $field ) { $table = $this->tableName( $table ); $res = $this->query( "SELECT * FROM $table LIMIT 1", __METHOD__, true ); @@ -297,6 +381,11 @@ class DatabaseMysql extends DatabaseBase { /** * Get information about an index into an object * Returns false if the index does not exist + * + * @param $table string + * @param $index string + * @param $fname string + * @return false|array */ function indexInfo( $table, $index, $fname = 'DatabaseMysql::indexInfo' ) { # SHOW INDEX works in MySQL 3.23.58, but SHOW INDEXES does not. @@ -322,11 +411,20 @@ class DatabaseMysql extends DatabaseBase { return empty( $result ) ? false : $result; } + /** + * @param $db + * @return bool + */ function selectDB( $db ) { $this->mDBname = $db; return mysql_select_db( $db, $this->mConn ); } + /** + * @param $s string + * + * @return string + */ function strencode( $s ) { $sQuoted = mysql_real_escape_string( $s, $this->mConn ); @@ -339,15 +437,26 @@ class DatabaseMysql extends DatabaseBase { /** * MySQL uses `backticks` for identifier quoting instead of the sql standard "double quotes". + * + * @param $s string + * + * @return string */ public function addIdentifierQuotes( $s ) { return "`" . $this->strencode( $s ) . "`"; } + /** + * @param $name string + * @return bool + */ public function isQuotedIdentifier( $name ) { - return strlen($name) && $name[0] == '`' && substr( $name, -1, 1 ) == '`'; + return strlen( $name ) && $name[0] == '`' && substr( $name, -1, 1 ) == '`'; } + /** + * @return bool + */ function ping() { $ping = mysql_ping( $this->mConn ); if ( $ping ) { @@ -364,11 +473,9 @@ class DatabaseMysql extends DatabaseBase { /** * Returns slave lag. * - * On MySQL 4.1.9 and later, this will do a SHOW SLAVE STATUS. On earlier - * versions of MySQL, it uses SHOW PROCESSLIST, which requires the PROCESS - * privilege. + * This will do a SHOW SLAVE STATUS * - * @result int + * @return int */ function getLag() { if ( !is_null( $this->mFakeSlaveLag ) ) { @@ -376,13 +483,12 @@ class DatabaseMysql extends DatabaseBase { return $this->mFakeSlaveLag; } - if ( version_compare( $this->getServerVersion(), '4.1.9', '>=' ) ) { - return $this->getLagFromSlaveStatus(); - } else { - return $this->getLagFromProcesslist(); - } + return $this->getLagFromSlaveStatus(); } + /** + * @return bool|int + */ function getLagFromSlaveStatus() { $res = $this->query( 'SHOW SLAVE STATUS', __METHOD__ ); if ( !$res ) { @@ -399,7 +505,13 @@ class DatabaseMysql extends DatabaseBase { } } + /** + * @deprecated in 1.19, use getLagFromSlaveStatus + * + * @return bool|int + */ function getLagFromProcesslist() { + wfDeprecated( __METHOD__, '1.19' ); $res = $this->query( 'SHOW PROCESSLIST', __METHOD__ ); if( !$res ) { return false; @@ -432,12 +544,13 @@ class DatabaseMysql extends DatabaseBase { } return false; } - + /** * Wait for the slave to catch up to a given master position. * * @param $pos DBMasterPos object * @param $timeout Integer: the maximum number of seconds to wait for synchronisation + * @return bool|string */ function masterPosWait( DBMasterPos $pos, $timeout ) { $fname = 'DatabaseBase::masterPosWait'; @@ -510,31 +623,68 @@ class DatabaseMysql extends DatabaseBase { } } + /** + * @return string + */ function getServerVersion() { return mysql_get_server_info( $this->mConn ); } + /** + * @param $index + * @return string + */ function useIndexClause( $index ) { return "FORCE INDEX (" . $this->indexName( $index ) . ")"; } + /** + * @return string + */ function lowPriorityOption() { return 'LOW_PRIORITY'; } + /** + * @return string + */ public static function getSoftwareLink() { return '[http://www.mysql.com/ MySQL]'; } + /** + * @return bool + */ function standardSelectDistinct() { return false; } - public function setTimeout( $timeout ) { - $this->query( "SET net_read_timeout=$timeout" ); - $this->query( "SET net_write_timeout=$timeout" ); + /** + * @param $options array + */ + public function setSessionOptions( array $options ) { + if ( isset( $options['connTimeout'] ) ) { + $timeout = (int)$options['connTimeout']; + $this->query( "SET net_read_timeout=$timeout" ); + $this->query( "SET net_write_timeout=$timeout" ); + } } + public function streamStatementEnd( &$sql, &$newLine ) { + if ( strtoupper( substr( $newLine, 0, 9 ) ) == 'DELIMITER' ) { + preg_match( '/^DELIMITER\s+(\S+)/' , $newLine, $m ); + $this->delimiter = $m[1]; + $newLine = ''; + } + return parent::streamStatementEnd( $sql, $newLine ); + } + + /** + * @param $lockName string + * @param $method string + * @param $timeout int + * @return bool + */ public function lock( $lockName, $method, $timeout = 5 ) { $lockName = $this->addQuotes( $lockName ); $result = $this->query( "SELECT GET_LOCK($lockName, $timeout) AS lockstatus", $method ); @@ -550,6 +700,9 @@ class DatabaseMysql extends DatabaseBase { /** * FROM MYSQL DOCS: http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_release-lock + * @param $lockName string + * @param $method string + * @return bool */ public function unlock( $lockName, $method ) { $lockName = $this->addQuotes( $lockName ); @@ -558,6 +711,12 @@ class DatabaseMysql extends DatabaseBase { return $row->lockstatus; } + /** + * @param $read array + * @param $write array + * @param $method string + * @param $lowPriority bool + */ public function lockTables( $read, $write, $method, $lowPriority = true ) { $items = array(); @@ -574,6 +733,9 @@ class DatabaseMysql extends DatabaseBase { $this->query( $sql, $method ); } + /** + * @param $method string + */ public function unlockTables( $method ) { $this->query( "UNLOCK TABLES", $method ); } @@ -588,6 +750,10 @@ class DatabaseMysql extends DatabaseBase { return 'SearchMySQL'; } + /** + * @param bool $value + * @return mixed + */ public function setBigSelects( $value = true ) { if ( $value === 'default' ) { if ( $this->mDefaultBigSelects === null ) { @@ -605,6 +771,13 @@ class DatabaseMysql extends DatabaseBase { /** * DELETE where the condition is a join. MySql uses multi-table deletes. + * @param $delTable string + * @param $joinTable string + * @param $delVar string + * @param $joinVar string + * @param $conds array|string + * @param $fname bool + * @return bool|ResultWrapper */ function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = 'DatabaseBase::deleteJoin' ) { if ( !$conds ) { @@ -622,16 +795,39 @@ class DatabaseMysql extends DatabaseBase { return $this->query( $sql, $fname ); } + /** + * Determines how long the server has been up + * + * @return int + */ + function getServerUptime() { + $vars = $this->getMysqlStatus( 'Uptime' ); + return (int)$vars['Uptime']; + } + /** * Determines if the last failure was due to a deadlock + * + * @return bool */ function wasDeadlock() { return $this->lastErrno() == 1213; } + /** + * Determines if the last failure was due to a lock timeout + * + * @return bool + */ + function wasLockTimeout() { + return $this->lastErrno() == 1205; + } + /** * Determines if the last query error was something that should be dealt * with by pinging the connection and reissuing the query + * + * @return bool */ function wasErrorReissuable() { return $this->lastErrno() == 2013 || $this->lastErrno() == 2006; @@ -639,45 +835,34 @@ class DatabaseMysql extends DatabaseBase { /** * Determines if the last failure was due to the database being read-only. + * + * @return bool */ function wasReadOnlyError() { return $this->lastErrno() == 1223 || ( $this->lastErrno() == 1290 && strpos( $this->lastError(), '--read-only' ) !== false ); } + /** + * @param $oldName + * @param $newName + * @param $temporary bool + * @param $fname string + */ function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = 'DatabaseMysql::duplicateTableStructure' ) { $tmp = $temporary ? 'TEMPORARY ' : ''; - if ( strcmp( $this->getServerVersion(), '4.1' ) < 0 ) { - # Hack for MySQL versions < 4.1, which don't support - # "CREATE TABLE ... LIKE". Note that - # "CREATE TEMPORARY TABLE ... SELECT * FROM ... LIMIT 0" - # would not create the indexes we need.... - # - # Note that we don't bother changing around the prefixes here be- - # cause we know we're using MySQL anyway. - - $res = $this->query( 'SHOW CREATE TABLE ' . $this->addIdentifierQuotes( $oldName ) ); - $row = $this->fetchRow( $res ); - $oldQuery = $row[1]; - $query = preg_replace( '/CREATE TABLE `(.*?)`/', - "CREATE $tmp TABLE " . $this->addIdentifierQuotes( $newName ), $oldQuery ); - if ($oldQuery === $query) { - # Couldn't do replacement - throw new MWException( "could not create temporary table $newName" ); - } - } else { - $newName = $this->addIdentifierQuotes( $newName ); - $oldName = $this->addIdentifierQuotes( $oldName ); - $query = "CREATE $tmp TABLE $newName (LIKE $oldName)"; - } + $newName = $this->addIdentifierQuotes( $newName ); + $oldName = $this->addIdentifierQuotes( $oldName ); + $query = "CREATE $tmp TABLE $newName (LIKE $oldName)"; $this->query( $query, $fname ); } - + /** * List all tables on the database * * @param $prefix Only show tables with this prefix, e.g. mw_ * @param $fname String: calling function name + * @return array */ function listTables( $prefix = null, $fname = 'DatabaseMysql::listTables' ) { $result = $this->query( "SHOW TABLES", $fname); @@ -692,12 +877,17 @@ class DatabaseMysql extends DatabaseBase { $endArray[] = $table; } } - + return $endArray; } + /** + * @param $tableName + * @param $fName string + * @return bool|ResultWrapper + */ public function dropTable( $tableName, $fName = 'DatabaseMysql::dropTable' ) { - if( !$this->tableExists( $tableName ) ) { + if( !$this->tableExists( $tableName, $fName ) ) { return false; } return $this->query( "DROP TABLE IF EXISTS " . $this->tableName( $tableName ), $fName ); @@ -716,6 +906,7 @@ class DatabaseMysql extends DatabaseBase { /** * Get status information from SHOW STATUS in an associative array * + * @param $which string * @return array */ function getMysqlStatus( $which = "%" ) { @@ -733,6 +924,8 @@ class DatabaseMysql extends DatabaseBase { /** * Legacy support: Database == DatabaseMysql + * + * @deprecated in 1.16 */ class Database extends DatabaseMysql {} @@ -757,18 +950,30 @@ class MySQLField implements Field { $this->type = $info->type; } + /** + * @return string + */ function name() { return $this->name; } + /** + * @return string + */ function tableName() { return $this->tableName; } + /** + * @return string + */ function type() { return $this->type; } + /** + * @return bool + */ function isNullable() { return $this->nullable; } @@ -777,10 +982,16 @@ class MySQLField implements Field { return $this->default; } + /** + * @return bool + */ function isKey() { return $this->is_key; } + /** + * @return bool + */ function isMultipleKey() { return $this->is_multiple; } -- cgit v1.2.3-54-g00ecf