Commit 7d7efe38 authored by Gábor Hojtsy's avatar Gábor Hojtsy
Browse files

Issue #3213533 by greg.1.anderson, Gábor Hojtsy, mihaic: Fix incorrect MariaDB...

Issue #3213533 by greg.1.anderson, Gábor Hojtsy, mihaic: Fix incorrect MariaDB version reports when used on Drupal 8
parent 33bde829
......@@ -6,6 +6,7 @@ use Composer\Semver\Semver;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Extension\Extension;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\Database\Connection;
use Drupal\Core\Datetime\DateFormatter;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
......@@ -17,6 +18,7 @@ use Drupal\Core\Url;
use Drupal\upgrade_status\DeprecationAnalyzer;
use Drupal\upgrade_status\ProjectCollector;
use Drupal\upgrade_status\ScanResultFormatter;
use Drupal\upgrade_status\Util\CorrectDbServerVersion;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Cookie\SetCookie;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -102,6 +104,13 @@ class UpgradeStatusForm extends FormBase {
*/
protected $nextMajor;
/**
* Database connection
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* {@inheritdoc}
*/
......@@ -116,7 +125,8 @@ class UpgradeStatusForm extends FormBase {
$container->get('upgrade_status.deprecation_analyzer'),
$container->get('state'),
$container->get('date.formatter'),
$container->get('redirect.destination')
$container->get('redirect.destination'),
$container->get('database')
);
}
......@@ -143,6 +153,8 @@ class UpgradeStatusForm extends FormBase {
* The date formatter.
* @param \Drupal\Core\Routing\RedirectDestination $destination
* The destination service.
* @param \Drupal\Core\Database\Connection $connection
* The database connection
*/
public function __construct(
ProjectCollector $project_collector,
......@@ -154,7 +166,8 @@ class UpgradeStatusForm extends FormBase {
DeprecationAnalyzer $deprecation_analyzer,
StateInterface $state,
DateFormatter $date_formatter,
RedirectDestination $destination
RedirectDestination $destination,
Connection $database
) {
$this->projectCollector = $project_collector;
$this->releaseStore = $key_value_expirable->get('update_available_releases');
......@@ -167,6 +180,7 @@ class UpgradeStatusForm extends FormBase {
$this->dateFormatter = $date_formatter;
$this->destination = $destination;
$this->nextMajor = ProjectCollector::getDrupalCoreMajorVersion() + 1;
$this->database = $database;
}
/**
......@@ -682,7 +696,7 @@ MARKUP
$class = 'no-known-error';
$requirement = $this->t('Supported.');
try {
\Drupal::database()->query('SELECT JSON_TYPE(\'1\')');
$this->database->query('SELECT JSON_TYPE(\'1\')');
}
catch (\Exception $e) {
$class = 'known-error';
......@@ -785,9 +799,15 @@ MARKUP
];
// Check database version.
$database = \Drupal::database();
$type = $database->databaseType();
$version = $database->version();
$type = $this->database->databaseType();
$version = $this->database->version();
// If running on Drupal 8, the mysql driver might
// mis-report the database version.
if ($this->nextMajor == 9) {
$versionFixer = new CorrectDbServerVersion($this->database);
$version = $versionFixer->getCorrectedDbServerVersion($version);
}
// MariaDB databases report as MySQL. Detect MariaDB separately based on code from
// https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Database%21Driver%21mysql%21Connection.php/function/Connection%3A%3AgetMariaDbVersionMatch/9.0.x
......
<?php
namespace Drupal\upgrade_status\Util;
use Drupal\Core\Database\Connection;
class CorrectDbServerVersion {
/**
* Database connection
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* Cached database version (Used in Drupal 8.9.x only)
*
* @var string
*/
protected $databaseServerVersion;
/**
* Constructs a Drupal\upgrade_status\Util\MariaDbServerVersion.
*
* @param \Drupal\Core\Database\Connection $connection
* The database connection
*/
public function __construct(
Connection $database
) {
$this->database = $database;
}
/**
* Returns corrected version of database.
*
* When running on MariaDb on Drupal 8.9.x, the version
* from $database->version() is not reported correctly.
* This is fixed in Drupal 9 directly in the Mysql database
* driver. In Drupal 8.9.x, however, the fix exists only in
* the Status Report page. We therefore need to replicate
* the same logic here.
*
* @see https://www.drupal.org/project/drupal/issues/3213482
*
* @return string
* Returns the MariaDb server version if applicable, or the passed-in
* version if not.
*/
public function getCorrectedDbServerVersion($version) {
if ($this->isMariaDb()) {
return $this->getMariaDbVersionMatch();
}
return $version;
}
/**
* Determines whether the MySQL distribution is MariaDB or not.
*
* @return bool
* Returns TRUE if the distribution is MariaDB, or FALSE if not.
*/
protected function isMariaDb(): bool {
return (bool) $this->getMariaDbVersionMatch();
}
/**
* Gets the MariaDB portion of the server version.
*
* @return string
* The MariaDB portion of the server version if present, or NULL if not.
*/
protected function getMariaDbVersionMatch(): ?string {
// MariaDB may prefix its version string with '5.5.5-', which should be
// ignored.
// @see https://github.com/MariaDB/server/blob/f6633bf058802ad7da8196d01fd19d75c53f7274/include/mysql_com.h#L42.
$regex = '/^(?:5\.5\.5-)?(\d+\.\d+\.\d+.*-mariadb.*)/i';
preg_match($regex, $this->getDatabaseServerVersion(), $matches);
return (empty($matches[1])) ? NULL : $matches[1];
}
/**
* Gets the database server version.
*
* @return string
* The database server version.
*/
protected function getDatabaseServerVersion(): string {
if (!$this->databaseServerVersion) {
$this->databaseServerVersion = $this->database->query('SELECT VERSION()')->fetchColumn();
}
return $this->databaseServerVersion;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment