Skip to content

Commit

Permalink
Merge pull request #5 from zjw/pr4872test
Browse files Browse the repository at this point in the history
Additional utf8mb4 fixes
  • Loading branch information
roland-d committed Nov 21, 2015
2 parents 14b7e21 + 90bb176 commit 3f56944
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 104 deletions.
65 changes: 1 addition & 64 deletions administrator/components/com_admin/script.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function update($installer)

$this->deleteUnexistingFiles();
$this->updateManifestCaches();
$this->updateDatabase();
$this->uninstallEosPlugin();
$this->clearRadCache();
$this->updateAssets();
$this->clearStatsCache();
Expand Down Expand Up @@ -97,69 +97,6 @@ protected function clearStatsCache()
}
}

/**
* Method to update Database
*
* @return void
*/
protected function updateDatabase()
{
$db = JFactory::getDbo();

if (strpos($db->name, 'mysql') !== false)
{
$this->updateDatabaseMysql();
}

$this->uninstallEosPlugin();
}

/**
* Method to update MySQL Database
*
* @return void
*/
protected function updateDatabaseMysql()
{
$db = JFactory::getDbo();

$db->setQuery('SHOW ENGINES');

try
{
$results = $db->loadObjectList();
}
catch (Exception $e)
{
echo JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '<br />';

return;
}

foreach ($results as $result)
{
if ($result->Support != 'DEFAULT')
{
continue;
}

$db->setQuery('ALTER TABLE #__update_sites_extensions ENGINE = ' . $result->Engine);

try
{
$db->execute();
}
catch (Exception $e)
{
echo JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '<br />';

return;
}

break;
}
}

/**
* Uninstall the 2.5 EOS plugin
*
Expand Down
17 changes: 11 additions & 6 deletions administrator/components/com_installer/models/database.php
Original file line number Diff line number Diff line change
Expand Up @@ -287,13 +287,18 @@ public function convertTablesToUtf8mb4()

foreach ($queries as $query)
{
try
{
$db->setQuery($query)->execute();
}
catch (Exception $e)
$query = trim($query);

if ($query != '' && $query{0} != '#')
{
// If the query fails we will go on. It probably means we've already done this conversion.
try
{
$db->setQuery($query)->execute();
}
catch (RuntimeException $e)
{
JFactory::getApplication()->enqueueMessage(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $e->getCode(), $e->getMessage()));
}
}
}
}
Expand Down
19 changes: 13 additions & 6 deletions libraries/joomla/database/driver/mysql.php
Original file line number Diff line number Diff line change
Expand Up @@ -510,17 +510,24 @@ private function hasProfiling()
private function serverClaimsUtf8mb4Support()
{
$client_version = mysql_get_client_info();
$server_support = version_compare($this->getVersion(), '5.5.3', '>=');
$server_version = $this->getVersion();

if (strpos($client_version, 'mysqlnd') !== false && $server_support)
if (version_compare($server_version, '5.5.3', '<'))
{
$client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version);

return version_compare($client_version, '5.0.9', '>=');
return false;
}
else
{
return $server_support;
if (strpos($client_version, 'mysqlnd') !== false)
{
$client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version);

return version_compare($client_version, '5.0.9', '>=');
}
else
{
return version_compare($client_version, '5.5.3', '>=');
}
}
}

Expand Down
19 changes: 13 additions & 6 deletions libraries/joomla/database/driver/mysqli.php
Original file line number Diff line number Diff line change
Expand Up @@ -952,17 +952,24 @@ private function hasProfiling()
private function serverClaimsUtf8mb4Support()
{
$client_version = mysqli_get_client_info();
$server_support = version_compare($this->getVersion(), '5.5.3', '>=');
$server_version = $this->getVersion();

if (strpos($client_version, 'mysqlnd') !== false && $server_support)
if (version_compare($server_version, '5.5.3', '<'))
{
$client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version);

return version_compare($client_version, '5.0.9', '>=');
return false;
}
else
{
return $server_support;
if (strpos($client_version, 'mysqlnd') !== false)
{
$client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version);

return version_compare($client_version, '5.0.9', '>=');
}
else
{
return version_compare($client_version, '5.5.3', '>=');
}
}
}

Expand Down
57 changes: 35 additions & 22 deletions libraries/joomla/database/driver/pdomysql.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,20 @@ class JDatabaseDriverPdomysql extends JDatabaseDriverPdo
*/
public function __construct($options)
{
/**
* Pre-populate the UTF-8 Multibyte compatibility flag. Unfortunately PDO won't report the server version
* unless we're connected to it and we cannot connect to it unless we know if it supports utf8mb4 which requires
* us knowing the server version. Between this chicken and egg issue we _assume_ it's supported and we'll just
* catch any problems at connection time.
*/
$this->utf8mb4 = true;

// Get some basic values from the options.
$options['driver'] = 'mysql';
$options['charset'] = (isset($options['charset'])) ? $options['charset'] : 'utf8';

if ($this->utf8mb4 && ($options['charset'] == 'utf8'))
if (!isset($options['charset']) || $options['charset'] == 'utf8')
{
$options['charset'] = 'utf8mb4';
}

$this->charset = $options['charset'];
/**
* Pre-populate the UTF-8 Multibyte compatibility flag. Unfortunately PDO won't report the server version
* unless we're connected to it, and we cannot connect to it unless we know if it supports utf8mb4, which requires
* us knowing the server version. Because of this chicken and egg issue, we _assume_ it's supported and we'll just
* catch any problems at connection time.
*/
$this->utf8mb4 = ($options['charset'] == 'utf8mb4');

// Finalize initialisation.
parent::__construct($options);
Expand All @@ -112,27 +108,44 @@ public function connect()
}
catch (\RuntimeException $e)
{
// If the connection failed but not because of the wrong character set bubble up the exception
if (!$this->utf8mb4 || ($this->options['charset'] != 'utf8mb4'))
// If the connection failed, but not because of the wrong character set, then bubble up the exception.
if (!$this->utf8mb4)
{
throw $e;
}

/**
* If the connection failed and I was trying to use the utf8mb4 charset then it is likely that the server
* doesn't support utf8mb4 despite claiming otherwise.
*
* This happens on old MySQL server versions (less than 5.5.3) using the mysqlnd PHP driver. Since mysqlnd
* masks the server version and reports only its own we can not be sure if the server actually does support
* UTF-8 Multibyte (i.e. it's MySQL 5.5.3 or later). Since the utf8mb4 charset is undefined in this case we
* catch the error and determine that utf8mb4 is not supported!
/*
* Otherwise, try connecting again without using
* utf8mb4 and see if maybe that was the problem. If the
* connection succeeds, then we will have learned that the
* client end of the connection does not support utf8mb4.
*/

$this->utf8mb4 = false;
$this->options['charset'] = 'utf8';

parent::connect();
}

if ($this->utf8mb4)
{
/*
* At this point we know the client supports utf8mb4. Now
* we must check if the server supports utf8mb4 as well.
*/

$serverVersion = $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION);
$this->utf8mb4 = version_compare($serverVersion, '5.5.3', '>=');

if (!$this->utf8mb4)
{
// Reconnect with the utf8 character set.
parent::disconnect();
$this->options['charset'] = 'utf8';
parent::connect();
}
}

$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
}
Expand Down

0 comments on commit 3f56944

Please sign in to comment.