Break long lines and formatting updates for includes/db/
[lhc/web/wiklou.git] / includes / db / DatabaseMysqlBase.php
index d33d7c7..e0ad003 100644 (file)
@@ -76,6 +76,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                } catch ( Exception $ex ) {
                        wfProfileOut( "dbconnect-$server" );
                        wfProfileOut( __METHOD__ );
+                       $this->restoreErrorHandler();
                        throw $ex;
                }
                $error = $this->restoreErrorHandler();
@@ -93,6 +94,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                                substr( $password, 0, 3 ) . "..., error: " . $error . "\n" );
 
                        wfProfileOut( __METHOD__ );
+
                        return $this->reportConnectionError( $error );
                }
 
@@ -106,6 +108,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                                        "from client host " . wfHostname() . "\n" );
 
                                wfProfileOut( __METHOD__ );
+
                                return $this->reportConnectionError( "Error selecting database $dbName" );
                        }
                }
@@ -113,9 +116,9 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                // Tell the server we're communicating with it in UTF-8.
                // This may engage various charset conversions.
                if ( $wgDBmysql5 ) {
-                       $this->query( 'SET NAMES utf8', __METHOD__ );
+                       $this->mysqlSetCharset( 'utf8' );
                } else {
-                       $this->query( 'SET NAMES binary', __METHOD__ );
+                       $this->mysqlSetCharset( 'binary' );
                }
                // Set SQL mode, default is turning them all off, can be overridden or skipped with null
                if ( is_string( $wgSQLMode ) ) {
@@ -125,6 +128,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
 
                $this->mOpened = true;
                wfProfileOut( __METHOD__ );
+
                return true;
        }
 
@@ -137,6 +141,14 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         */
        abstract protected function mysqlConnect( $realServer );
 
+       /**
+        * Set the character set of the MySQL link
+        *
+        * @param string $charset
+        * @return bool
+        */
+       abstract protected function mysqlSetCharset( $charset );
+
        /**
         * @param $res ResultWrapper
         * @throws DBUnexpectedError
@@ -180,8 +192,12 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                // these are the only errors mysql_fetch_object can cause.
                // See http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
                if ( $errno == 2000 || $errno == 2013 ) {
-                       throw new DBUnexpectedError( $this, 'Error in fetchObject(): ' . htmlspecialchars( $this->lastError() ) );
+                       throw new DBUnexpectedError(
+                               $this,
+                               'Error in fetchObject(): ' . htmlspecialchars( $this->lastError() )
+                       );
                }
+
                return $row;
        }
 
@@ -212,8 +228,12 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                // these are the only errors mysql_fetch_array can cause.
                // See http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
                if ( $errno == 2000 || $errno == 2013 ) {
-                       throw new DBUnexpectedError( $this, 'Error in fetchRow(): ' . htmlspecialchars( $this->lastError() ) );
+                       throw new DBUnexpectedError(
+                               $this,
+                               'Error in fetchRow(): ' . htmlspecialchars( $this->lastError() )
+                       );
                }
+
                return $row;
        }
 
@@ -237,6 +257,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                wfSuppressWarnings();
                $n = $this->mysqlNumRows( $res );
                wfRestoreWarnings();
+
                // Unfortunately, mysql_num_rows does not reset the last errno.
                // We are not checking for any errors here, since
                // these are no errors mysql_num_rows can cause.
@@ -261,6 +282,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
+
                return $this->mysqlNumFields( $res );
        }
 
@@ -281,6 +303,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
+
                return $this->mysqlFieldName( $res, $n );
        }
 
@@ -302,6 +325,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
+
                return $this->mysqlDataSeek( $res, $row );
        }
 
@@ -332,6 +356,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                if ( $error ) {
                        $error .= ' (' . $this->mServer . ')';
                }
+
                return $error;
        }
 
@@ -366,7 +391,9 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param $options string|array
         * @return int
         */
-       public function estimateRowCount( $table, $vars = '*', $conds = '', $fname = __METHOD__, $options = array() ) {
+       public function estimateRowCount( $table, $vars = '*', $conds = '',
+               $fname = __METHOD__, $options = array()
+       ) {
                $options['EXPLAIN'] = true;
                $res = $this->select( $table, $vars, $conds, $fname, $options );
                if ( $res === false ) {
@@ -380,6 +407,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                foreach ( $res as $plan ) {
                        $rows *= $plan->rows > 0 ? $plan->rows : 1; // avoid resetting to zero
                }
+
                return $rows;
        }
 
@@ -401,6 +429,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                                return new MySQLField( $meta );
                        }
                }
+
                return false;
        }
 
@@ -443,6 +472,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                                $result[] = $row;
                        }
                }
+
                return empty( $result ) ? false : $result;
        }
 
@@ -458,6 +488,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                        $this->ping();
                        $sQuoted = $this->mysqlRealEscapeString( $s );
                }
+
                return $sQuoted;
        }
 
@@ -471,7 +502,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
        public function addIdentifierQuotes( $s ) {
                // Characters in the range \u0001-\uFFFF are valid in a quoted identifier
                // Remove NUL bytes and escape backticks by doubling
-               return '`' . str_replace( array( "\0", '`' ), array( '', '``' ), $s )  . '`';
+               return '`' . str_replace( array( "\0", '`' ), array( '', '``' ), $s ) . '`';
        }
 
        /**
@@ -495,6 +526,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                $this->mOpened = false;
                $this->mConn = false;
                $this->open( $this->mServer, $this->mUser, $this->mPassword, $this->mDBname );
+
                return true;
        }
 
@@ -515,6 +547,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
        function getLag() {
                if ( !is_null( $this->mFakeSlaveLag ) ) {
                        wfDebug( "getLag: fake slave lagged {$this->mFakeSlaveLag} seconds\n" );
+
                        return $this->mFakeSlaveLag;
                }
 
@@ -568,7 +601,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                                $row->State != 'Waiting to reconnect after a failed master event read' &&
                                $row->State != 'Reconnecting after a failed master event read' &&
                                $row->State != 'Registering slave on master'
-                               ) {
+                       ) {
                                # This is it, return the time (except -ve)
                                if ( $row->Time > 0x7fffffff ) {
                                        return false;
@@ -577,6 +610,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                                }
                        }
                }
+
                return false;
        }
 
@@ -600,6 +634,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                if ( !is_null( $this->mFakeSlaveLag ) ) {
                        $status = parent::masterPosWait( $pos, $timeout );
                        wfProfileOut( __METHOD__ );
+
                        return $status;
                }
 
@@ -618,6 +653,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                }
 
                wfProfileOut( __METHOD__ );
+
                return $status;
        }
 
@@ -635,7 +671,10 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                $row = $this->fetchObject( $res );
 
                if ( $row ) {
-                       $pos = isset( $row->Exec_master_log_pos ) ? $row->Exec_master_log_pos : $row->Exec_Master_Log_Pos;
+                       $pos = isset( $row->Exec_master_log_pos )
+                               ? $row->Exec_master_log_pos
+                               : $row->Exec_Master_Log_Pos;
+
                        return new MySQLMasterPos( $row->Relay_Master_Log_File, $pos );
                } else {
                        return false;
@@ -701,6 +740,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                        $this->delimiter = $m[1];
                        $newLine = '';
                }
+
                return parent::streamStatementEnd( $sql, $newLine );
        }
 
@@ -716,6 +756,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                $lockName = $this->addQuotes( $lockName );
                $result = $this->query( "SELECT IS_FREE_LOCK($lockName) AS lockstatus", $method );
                $row = $this->fetchObject( $result );
+
                return ( $row->lockstatus == 1 );
        }
 
@@ -734,12 +775,14 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                        return true;
                } else {
                        wfDebug( __METHOD__ . " failed to acquire lock\n" );
+
                        return false;
                }
        }
 
        /**
-        * FROM MYSQL DOCS: http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_release-lock
+        * 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
@@ -748,6 +791,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                $lockName = $this->addQuotes( $lockName );
                $result = $this->query( "SELECT RELEASE_LOCK($lockName) as lockstatus", $method );
                $row = $this->fetchObject( $result );
+
                return ( $row->lockstatus == 1 );
        }
 
@@ -763,8 +807,8 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
 
                foreach ( $write as $table ) {
                        $tbl = $this->tableName( $table ) .
-                                       ( $lowPriority ? ' LOW_PRIORITY' : '' ) .
-                                       ' WRITE';
+                               ( $lowPriority ? ' LOW_PRIORITY' : '' ) .
+                               ' WRITE';
                        $items[] = $tbl;
                }
                foreach ( $read as $table ) {
@@ -772,6 +816,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                }
                $sql = "LOCK TABLES " . implode( ',', $items );
                $this->query( $sql, $method );
+
                return true;
        }
 
@@ -781,6 +826,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         */
        public function unlockTables( $method ) {
                $this->query( "UNLOCK TABLES", $method );
+
                return true;
        }
 
@@ -878,6 +924,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         */
        function getServerUptime() {
                $vars = $this->getMysqlStatus( 'Uptime' );
+
                return (int)$vars['Uptime'];
        }
 
@@ -966,6 +1013,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                if ( !$this->tableExists( $tableName, $fName ) ) {
                        return false;
                }
+
                return $this->query( "DROP TABLE IF EXISTS " . $this->tableName( $tableName ), $fName );
        }
 
@@ -975,7 +1023,12 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
        protected function getDefaultSchemaVars() {
                $vars = parent::getDefaultSchemaVars();
                $vars['wgDBTableOptions'] = str_replace( 'TYPE', 'ENGINE', $GLOBALS['wgDBTableOptions'] );
-               $vars['wgDBTableOptions'] = str_replace( 'CHARSET=mysql4', 'CHARSET=binary', $vars['wgDBTableOptions'] );
+               $vars['wgDBTableOptions'] = str_replace(
+                       'CHARSET=mysql4',
+                       'CHARSET=binary',
+                       $vars['wgDBTableOptions']
+               );
+
                return $vars;
        }
 
@@ -996,9 +1049,56 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                return $status;
        }
 
-}
+       /**
+        * Lists VIEWs in the database
+        *
+        * @param string $prefix Only show VIEWs with this prefix, eg.
+        * unit_test_, or $wgDBprefix. Default: null, would return all views.
+        * @param string $fname Name of calling function
+        * @return array
+        * @since 1.22
+        */
+       public function listViews( $prefix = null, $fname = __METHOD__ ) {
+
+               if ( !isset( $this->allViews ) ) {
+
+                       // The name of the column containing the name of the VIEW
+                       $propertyName = 'Tables_in_' . $this->mDBname;
+
+                       // Query for the VIEWS
+                       $result = $this->query( 'SHOW FULL TABLES WHERE TABLE_TYPE = "VIEW"' );
+                       $this->allViews = array();
+                       while ( ( $row = $this->fetchRow( $result ) ) !== false ) {
+                               array_push( $this->allViews, $row[$propertyName] );
+                       }
+               }
+
+               if ( is_null( $prefix ) || $prefix === '' ) {
+                       return $this->allViews;
+               }
 
+               $filteredViews = array();
+               foreach ( $this->allViews as $viewName ) {
+                       // Does the name of this VIEW start with the table-prefix?
+                       if ( strpos( $viewName, $prefix ) === 0 ) {
+                               array_push( $filteredViews, $viewName );
+                       }
+               }
 
+               return $filteredViews;
+       }
+
+       /**
+        * Differentiates between a TABLE and a VIEW.
+        *
+        * @param $name string: Name of the TABLE/VIEW to test
+        * @return bool
+        * @since 1.22
+        */
+       public function isView( $name, $prefix = null ) {
+               return in_array( $name, $this->listViews( $prefix ) );
+       }
+}
 
 /**
  * Utility class.
@@ -1006,7 +1106,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
  */
 class MySQLField implements Field {
        private $name, $tablename, $default, $max_length, $nullable,
-               $is_pk, $is_unique, $is_multiple, $is_key, $type;
+               $is_pk, $is_unique, $is_multiple, $is_key, $type, $binary;
 
        function __construct( $info ) {
                $this->name = $info->name;
@@ -1019,6 +1119,7 @@ class MySQLField implements Field {
                $this->is_multiple = $info->multiple_key;
                $this->is_key = ( $this->is_pk || $this->is_unique || $this->is_multiple );
                $this->type = $info->type;
+               $this->binary = isset( $info->binary ) ? $info->binary : false;
        }
 
        /**
@@ -1066,6 +1167,10 @@ class MySQLField implements Field {
        function isMultipleKey() {
                return $this->is_multiple;
        }
+
+       function isBinary() {
+               return $this->binary;
+       }
 }
 
 class MySQLMasterPos implements DBMasterPos {
@@ -1089,12 +1194,14 @@ class MySQLMasterPos implements DBMasterPos {
                if ( preg_match( '!\.(\d+)/(\d+)$!', (string)$this, $m ) ) {
                        return array( (int)$m[1], (int)$m[2] );
                }
+
                return false;
        }
 
        function hasReached( MySQLMasterPos $pos ) {
                $thisPos = $this->getCoordinates();
                $thatPos = $pos->getCoordinates();
+
                return ( $thisPos && $thatPos && $thisPos >= $thatPos );
        }
 }