Skip to content

Commit

Permalink
Look at most recent archive table for update collation detection
Browse files Browse the repository at this point in the history
  • Loading branch information
mneudert committed Sep 12, 2024
1 parent d203ce8 commit 104c2dd
Showing 1 changed file with 58 additions and 20 deletions.
78 changes: 58 additions & 20 deletions core/Updates/5.2.0-b2.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use Piwik\Common;
use Piwik\Config;
use Piwik\DataAccess\ArchiveTableCreator;
use Piwik\Db;
use Piwik\Updater;
use Piwik\Updater\Migration\Factory as MigrationFactory;
Expand All @@ -37,26 +38,14 @@ public function getMigrations(Updater $updater)

// only run migration if config is not set
if (empty($dbConfig['collation'])) {
try {
$db = Db::get();
$userTable = Common::prefixTable('user');
$userTableStatus = $db->fetchRow('SHOW TABLE STATUS WHERE Name = ?', [$userTable]);
$connectionCollation = $db->fetchOne('SELECT @@collation_connection');

// only update config if user table and connection report same collation
if (
!empty($userTableStatus['Collation'])
&& !empty($connectionCollation)
&& $userTableStatus['Collation'] === $connectionCollation
) {
$migrations[] = $this->migration->config->set(
'database',
'collation',
$connectionCollation
);
}
} catch (\Exception $e) {
// rely on the system check if detection failed
$collation = $this->detectCollationForMigration();

if (null !== $collation) {
$migrations[] = $this->migration->config->set(
'database',
'collation',
$collation
);
}
}

Expand All @@ -67,4 +56,53 @@ public function doUpdate(Updater $updater)
{
$updater->executeMigrations(__FILE__, $this->getMigrations($updater));
}

private function detectCollationForMigration(): ?string
{
try {
$db = Db::get();
$userTable = Common::prefixTable('user');
$userTableStatus = $db->fetchRow('SHOW TABLE STATUS WHERE Name = ?', [$userTable]);

if (empty($userTableStatus['Collation'])) {
// if there is no user table, or no collation for it, abort detection
// this table should always exist and something must be wrong in this case
return null;
}

$userTableCollation = $userTableStatus['Collation'];
$connectionCollation = $db->fetchOne('SELECT @@collation_connection');

if ($userTableCollation === $connectionCollation) {
// if the connection is matching the user table
// we should be safe to assume we have already found a config value
return $userTableCollation;
}

$archiveTables = ArchiveTableCreator::getTablesArchivesInstalled(ArchiveTableCreator::NUMERIC_TABLE);

if (0 === count($archiveTables)) {
// skip if there is no archive table (yet)
return null;
}

// sort tables so we have them in order of their date
rsort($archiveTables);

$archiveTableStatus = $db->fetchRow('SHOW TABLE STATUS WHERE Name = ?', [$archiveTables[0]]);

if (
!empty($archiveTableStatus['Collation'])
&& $archiveTableStatus['Collation'] === $userTableCollation
) {
// the most recent numeric archive table is matching the collation
// of the users table, should be a good config value to choose
return $userTableCollation;
}
} catch (\Exception $e) {
// rely on the system check if detection failed
}

return null;
}
}

0 comments on commit 104c2dd

Please sign in to comment.