diff --git a/core/Db/Schema/Mysql.php b/core/Db/Schema/Mysql.php index 44b66fc4ddb..7c3cd280f94 100644 --- a/core/Db/Schema/Mysql.php +++ b/core/Db/Schema/Mysql.php @@ -672,6 +672,9 @@ public function supportsComplexColumnUpdates(): bool /** * Returns the default collation for a charset. * + * Will return an empty string for an unknown charset + * (can happen for alias charsets like "utf8"). + * * @param string $charset * * @return string @@ -679,19 +682,9 @@ public function supportsComplexColumnUpdates(): bool */ public function getDefaultCollationForCharset(string $charset): string { - $result = $this->getDb()->fetchRow( - 'SHOW COLLATION WHERE `Default` = "Yes" AND `Charset` = ?', - [$charset] - ); + $result = $this->getDb()->fetchRow('SHOW CHARACTER SET WHERE `Charset` = ?', [$charset]); - if (!isset($result['Collation'])) { - throw new Exception(sprintf( - 'Failed to detect default collation for character set "%s"', - $charset - )); - } - - return $result['Collation']; + return $result['Default collation'] ?? ''; } public function getDefaultPort(): int @@ -797,7 +790,13 @@ protected function getDatabaseCreateOptions(): string $charset = DbHelper::getDefaultCharset(); $collation = $this->getDefaultCollationForCharset($charset); - return "DEFAULT CHARACTER SET $charset COLLATE $collation"; + $options = "DEFAULT CHARACTER SET $charset"; + + if ('' !== $collation) { + $options .= " COLLATE $collation"; + } + + return $options; } protected function getTableEngine() diff --git a/plugins/Diagnostics/Diagnostic/DatabaseAbilitiesCheck.php b/plugins/Diagnostics/Diagnostic/DatabaseAbilitiesCheck.php index 6465633b278..71ee03b51bd 100644 --- a/plugins/Diagnostics/Diagnostic/DatabaseAbilitiesCheck.php +++ b/plugins/Diagnostics/Diagnostic/DatabaseAbilitiesCheck.php @@ -105,15 +105,17 @@ protected function checkCollation(): DiagnosticResultItem $collationConnection = Db::get()->fetchOne('SELECT @@collation_connection'); $collationCharset = DbHelper::getDefaultCollationForCharset($dbSettings->getUsedCharset()); - return new DiagnosticResultItem( - DiagnosticResult::STATUS_WARNING, - sprintf( - 'Connection collation

%s

%s
%s
', - $this->translator->translate('Diagnostics_DatabaseCollationNotConfigured'), - $this->translator->translate('Diagnostics_DatabaseCollationConnection', [$collationConnection]), - $this->translator->translate('Diagnostics_DatabaseCollationCharset', [$collationCharset]) - ) + $message = sprintf( + 'Connection collation

%s

%s
', + $this->translator->translate('Diagnostics_DatabaseCollationNotConfigured'), + $this->translator->translate('Diagnostics_DatabaseCollationConnection', [$collationConnection]) ); + + if ('' !== $collationCharset) { + $message .= $this->translator->translate('Diagnostics_DatabaseCollationCharset', [$collationCharset]) . '
'; + } + + return new DiagnosticResultItem(DiagnosticResult::STATUS_WARNING, $message); } protected function checkLoadDataInfile() diff --git a/tests/PHPUnit/Integration/DbHelperTest.php b/tests/PHPUnit/Integration/DbHelperTest.php index de20af974db..5b0da00973a 100644 --- a/tests/PHPUnit/Integration/DbHelperTest.php +++ b/tests/PHPUnit/Integration/DbHelperTest.php @@ -130,12 +130,9 @@ public function testGetDefaultCollationForCharset(): void self::assertStringStartsWith($expectedPrefix, $collation); } - public function testGetDefaultCollationForCharsetThrowsForInvalidCharset(): void + public function testGetDefaultCollationForCharsetWithoutDefault(): void { - self::expectException(\Exception::class); - self::expectExceptionMessage('Failed to detect default collation for character set "invalid"'); - - DbHelper::getDefaultCollationForCharset('invalid'); + self::assertSame('', DbHelper::getDefaultCollationForCharset('invalid')); } private function assertDbExists($dbName)