Check minimum database server version when running update.php
authorKunal Mehta <legoktm@member.fsf.org>
Tue, 3 Oct 2017 05:14:33 +0000 (22:14 -0700)
committerKunal Mehta <legoktm@member.fsf.org>
Tue, 3 Oct 2017 05:23:32 +0000 (22:23 -0700)
If MediaWiki has increased the minimum database server version that is
required, check it when running update.php to ensure it is still
compatible. Previously this was only checked during the installer.

Bug: T162044
Change-Id: I47092c9557f4706a4dcb3a23150647e68af4317f

includes/installer/DatabaseInstaller.php
includes/installer/Installer.php
includes/installer/MssqlInstaller.php
includes/installer/MysqlInstaller.php
includes/installer/OracleInstaller.php
includes/installer/PostgresInstaller.php
includes/installer/SqliteInstaller.php
maintenance/update.php

index 6c56b3d..925d991 100644 (file)
@@ -41,6 +41,16 @@ abstract class DatabaseInstaller {
         */
        public $parent;
 
+       /**
+        * @var string Set by subclasses
+        */
+       public static $minimumVersion;
+
+       /**
+        * @var string Set by subclasses
+        */
+       protected static $notMiniumumVerisonMessage;
+
        /**
         * The database connection.
         *
@@ -62,6 +72,23 @@ abstract class DatabaseInstaller {
         */
        protected $globalNames = [];
 
+       /**
+        * Whether the provided version meets the necessary requirements for this type
+        *
+        * @param string $serverVersion Output of Database::getServerVersion()
+        * @return Status
+        * @since 1.30
+        */
+       public static function meetsMinimumRequirement( $serverVersion ) {
+               if ( version_compare( $serverVersion, static::$minimumVersion ) < 0 ) {
+                       return Status::newFatal(
+                               static::$notMiniumumVerisonMessage, static::$minimumVersion, $serverVersion
+                       );
+               }
+
+               return Status::newGood();
+       }
+
        /**
         * Return the internal name, e.g. 'mysql', or 'sqlite'.
         */
index 52be321..012b477 100644 (file)
@@ -546,6 +546,17 @@ abstract class Installer {
                return $this->compiledDBs;
        }
 
+       /**
+        * Get the DatabaseInstaller class name for this type
+        *
+        * @param string $type database type ($wgDBtype)
+        * @return string Class name
+        * @since 1.30
+        */
+       public static function getDBInstallerClass( $type ) {
+               return ucfirst( $type ) . 'Installer';
+       }
+
        /**
         * Get an instance of DatabaseInstaller for the specified DB type.
         *
@@ -561,7 +572,7 @@ abstract class Installer {
                $type = strtolower( $type );
 
                if ( !isset( $this->dbInstallers[$type] ) ) {
-                       $class = ucfirst( $type ) . 'Installer';
+                       $class = self::getDBInstallerClass( $type );
                        $this->dbInstallers[$type] = new $class( $this );
                }
 
index d01f954..e462220 100644 (file)
@@ -51,7 +51,8 @@ class MssqlInstaller extends DatabaseInstaller {
 
        // SQL Server 2005 RTM
        // @todo Are SQL Express version numbers different?)
-       public $minimumVersion = '9.00.1399';
+       public static $minimumVersion = '9.00.1399';
+       protected static $notMiniumumVerisonMessage = 'config-mssql-old';
 
        // These are schema-level privs
        // Note: the web user will be created will full permissions if possible, this permission
@@ -191,12 +192,7 @@ class MssqlInstaller extends DatabaseInstaller {
                $conn = $status->value;
 
                // Check version
-               $version = $conn->getServerVersion();
-               if ( version_compare( $version, $this->minimumVersion ) < 0 ) {
-                       return Status::newFatal( 'config-mssql-old', $this->minimumVersion, $version );
-               }
-
-               return $status;
+               return static::meetsMinimumRequirement( $conn->getServerVersion() );
        }
 
        /**
index c5dd4dc..ab5701a 100644 (file)
@@ -51,7 +51,8 @@ class MysqlInstaller extends DatabaseInstaller {
 
        public $supportedEngines = [ 'InnoDB', 'MyISAM' ];
 
-       public $minimumVersion = '5.5.8';
+       public static $minimumVersion = '5.5.8';
+       protected static $notMiniumumVerisonMessage = 'config-mysql-old';
 
        public $webUserPrivs = [
                'DELETE',
@@ -133,12 +134,7 @@ class MysqlInstaller extends DatabaseInstaller {
                $conn = $status->value;
 
                // Check version
-               $version = $conn->getServerVersion();
-               if ( version_compare( $version, $this->minimumVersion ) < 0 ) {
-                       return Status::newFatal( 'config-mysql-old', $this->minimumVersion, $version );
-               }
-
-               return $status;
+               return static::meetsMinimumRequirement( $conn->getServerVersion() );
        }
 
        /**
index 14683d6..05f078f 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Deployment
  */
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\DBConnectionError;
 
 /**
@@ -45,7 +46,8 @@ class OracleInstaller extends DatabaseInstaller {
                '_InstallUser' => 'SYSTEM',
        ];
 
-       public $minimumVersion = '9.0.1'; // 9iR1
+       public static $minimumVersion = '9.0.1'; // 9iR1
+       protected static $notMiniumumVerisonMessage = 'config-oracle-old';
 
        protected $connError = null;
 
@@ -152,15 +154,12 @@ class OracleInstaller extends DatabaseInstaller {
                }
 
                /**
-                * @var $conn Database
+                * @var Database $conn
                 */
                $conn = $status->value;
 
                // Check version
-               $version = $conn->getServerVersion();
-               if ( version_compare( $version, $this->minimumVersion ) < 0 ) {
-                       return Status::newFatal( 'config-oracle-old', $this->minimumVersion, $version );
-               }
+               $status->merge( static::meetsMinimumRequirement( $conn->getServerVersion() ) );
 
                return $status;
        }
index 1a3fb10..129dbf8 100644 (file)
@@ -46,7 +46,8 @@ class PostgresInstaller extends DatabaseInstaller {
                '_InstallUser' => 'postgres',
        ];
 
-       public $minimumVersion = '8.3';
+       public static $minimumVersion = '8.3';
+       protected static $notMiniumumVerisonMessage = 'config-postgres-old';
        public $maxRoleSearchDepth = 5;
 
        protected $pgConns = [];
@@ -124,8 +125,9 @@ class PostgresInstaller extends DatabaseInstaller {
 
                // Check version
                $version = $conn->getServerVersion();
-               if ( version_compare( $version, $this->minimumVersion ) < 0 ) {
-                       return Status::newFatal( 'config-postgres-old', $this->minimumVersion, $version );
+               $status = static::meetsMinimumRequirement( $conn->getServerVersion() );
+               if ( !$status->isOK() ) {
+                       return $status;
                }
 
                $this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) );
index d60d801..d5909f4 100644 (file)
@@ -33,7 +33,8 @@ use Wikimedia\Rdbms\DBConnectionError;
  */
 class SqliteInstaller extends DatabaseInstaller {
 
-       public $minimumVersion = '3.3.7';
+       public static $minimumVersion = '3.3.7';
+       protected static $notMiniumumVerisonMessage = 'config-outdated-sqlite';
 
        /**
         * @var DatabaseSqlite
@@ -58,12 +59,9 @@ class SqliteInstaller extends DatabaseInstaller {
         * @return Status
         */
        public function checkPrerequisites() {
-               $result = Status::newGood();
                // Bail out if SQLite is too old
                $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
-               if ( version_compare( $db->getServerVersion(), $this->minimumVersion, '<' ) ) {
-                       $result->fatal( 'config-outdated-sqlite', $db->getServerVersion(), $this->minimumVersion );
-               }
+               $result = static::meetsMinimumRequirement( $db->getServerVersion() );
                // Check for FTS3 full-text search module
                if ( DatabaseSqlite::getFulltextSearchModule() != 'FTS3' ) {
                        $result->warning( 'config-no-fts3' );
index 5f705ba..9f2fb92 100755 (executable)
@@ -145,6 +145,16 @@ class UpdateMediaWiki extends Maintenance {
                # This will vomit up an error if there are permissions problems
                $db = $this->getDB( DB_MASTER );
 
+               # Check to see whether the database server meets the minimum requirements
+               /** @var DatabaseInstaller $dbInstallerClass */
+               $dbInstallerClass = Installer::getDBInstallerClass( $db->getType() );
+               $status = $dbInstallerClass::meetsMinimumRequirement( $db->getServerVersion() );
+               if ( !$status->isOK() ) {
+                       // This might output some wikitext like <strong> but it should be comprehensible
+                       $text = $status->getWikiText();
+                       $this->error( $text, 1 );
+               }
+
                $this->output( "Going to run database updates for " . wfWikiID() . "\n" );
                if ( $db->getType() === 'sqlite' ) {
                        /** @var IMaintainableDatabase|DatabaseSqlite $db */