From fa17e0709c845e56e1a37e453bc267366ff7f0cb Mon Sep 17 00:00:00 2001 From: onli Date: Sun, 22 Mar 2020 22:12:57 +0100 Subject: [PATCH] Upgrade task to move utf8 mysql databases to utf8mb4 (#394) --- include/admin/upgrader.inc.php | 5 ++++ include/functions_upgrader.inc.php | 47 ++++++++++++++++++++++++++++++ serendipity_config.inc.php | 2 +- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/include/admin/upgrader.inc.php b/include/admin/upgrader.inc.php index 3050d40f..81e11022 100644 --- a/include/admin/upgrader.inc.php +++ b/include/admin/upgrader.inc.php @@ -275,6 +275,11 @@ $tasks = array(array('version' => '0.5.1', 'function' => 'serendipity_upgrader_spamblock_moveForce', 'title' => 'Swap value forcemoderation', 'desc' => 'If force moderation of comments is activated, activate the new option moderation_auto'), + + array('version' => '2.4-alpha2', + 'function' => 'serendipity_upgradeUTF8_UTF8mb4', + 'title' => 'Enable full Unicode support for MySQL', + 'desc' => 'Move MySQL databases from MyIsam and UTF8 to InnoDB and utf8mb4, enabling full unicode input.'), ); /* Fetch SQL files which needs to be run */ diff --git a/include/functions_upgrader.inc.php b/include/functions_upgrader.inc.php index e2b04375..2ca9916a 100644 --- a/include/functions_upgrader.inc.php +++ b/include/functions_upgrader.inc.php @@ -458,3 +458,50 @@ function serendipity_upgrader_move_syndication_config() { } } } + +# When mysql is used in a version new enough (at least 5.6.4/10.0.5), upgrade all UTF8 tables to utf8mb4. For that to work well +# we also need to set the storage engine to InnoDB. Earlier version set it to MyISAM. +function serendipity_upgradeUTF8_UTF8mb4() { + global $serendipity; + + # are we even using mysql? + if ($serendipity['dbType'] != 'mysqli') { + return false; + } + + if (serendipity_utf8mb4_ready()) { + # get all core tables + //$tables = serendipity_db_query("SHOW TABLES LIKE '" . str_replace('_', '\_', serendipity_db_escape_string($prefix)) . "%'"); + $tables = serendipity_db_query("SHOW TABLES LIKE 'serendipity_entries'"); + if (!is_array($tables)) { + echo 'Could not analyze existing tables via SHOW TABLES, please check permissions.' . $tables; + return false; + } + # now collect all their columns charsets + # they all need to be utf8 for us to be able to securely set them to utf8mb4 + foreach ($tables as $table) { + $table = $table[0]; + $columns = serendipity_db_query('SHOW FULL COLUMNS FROM ' . $table); + foreach($columns as $column) { + if ($column['Collation'] && ( ! ($column['Collation'] == 'utf8_unicode_ci' || $column['Collation'] == 'utf8_general_ci')) ) { + return false; + } + } + } + + # but before we can set them to utf8mb4, the storage engine needs to be set to innodb and the format to dynamic + # Without InnoDB the index size is just 1000 bytes, which would not work with our db schema + foreach ($tables AS $table) { + $table = $table[0]; + serendipity_db_query('ALTER TABLE `' . $table . '` ENGINE=InnoDB'); + serendipity_db_query('ALTER TABLE `' . $table . '` ROW_FORMAT=DYNAMIC'); + } + + # Good, now we can set it it utf8mb4. utf8mb4 is fully compatible with utf8, so there won't be broken chars + foreach ($tables AS $table) { + $table = $table[0]; + serendipity_db_query('ALTER TABLE `' . $table . '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci'); + } + return true; + } +} diff --git a/serendipity_config.inc.php b/serendipity_config.inc.php index aced8af5..564dac7a 100644 --- a/serendipity_config.inc.php +++ b/serendipity_config.inc.php @@ -47,7 +47,7 @@ if (defined('USE_MEMSNAP')) { } // The version string -$serendipity['version'] = '2.4-alpha1'; +$serendipity['version'] = '2.4-alpha2'; // Setting this to 'false' will enable debugging output. All alpha/beta/cvs snapshot versions will emit debug information by default. To increase the debug level (to enable Smarty debugging), set this flag to 'debug'.