Commit b0253c33 authored by Eloy Lafuente's avatar Eloy Lafuente
Browse files

Merge branch 'wip-MDL-48228-master-v2' of git://github.com/abgreeve/moodle

parents b239dfd9 8c1288db
...@@ -134,11 +134,13 @@ before_script: ...@@ -134,11 +134,13 @@ before_script:
sed -i \ sed -i \
-e "s%= 'pgsql'%= 'mysqli'%" \ -e "s%= 'pgsql'%= 'mysqli'%" \
-e "s%= 'username'%= 'travis'%" \ -e "s%= 'username'%= 'travis'%" \
-e "s%=> 'utf8mb4_unicode_ci'%=> 'utf8mb4_bin'%" \
config.php; config.php;
mysql -u root -e 'SET GLOBAL innodb_file_format=barracuda;' ; mysql -u root -e 'SET GLOBAL innodb_file_format=barracuda;' ;
mysql -u root -e 'SET GLOBAL innodb_file_per_table=ON;' ; mysql -u root -e 'SET GLOBAL innodb_file_per_table=ON;' ;
mysql -e 'CREATE DATABASE travis_ci_test DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_bin;' ; mysql -u root -e 'SET GLOBAL innodb_large_prefix=ON;' ;
mysql -e 'CREATE DATABASE travis_ci_test DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_bin;' ;
fi fi
fi fi
......
...@@ -64,6 +64,71 @@ if (!empty($options['collation'])) { ...@@ -64,6 +64,71 @@ if (!empty($options['collation'])) {
cli_error("Error: collation '$collation' is not available on this server!"); cli_error("Error: collation '$collation' is not available on this server!");
} }
$collationinfo = explode('_', $collation);
$charset = reset($collationinfo);
$engine = strtolower($DB->get_dbengine());
// Do checks for utf8mb4.
if (strpos($collation, 'utf8mb4') === 0) {
// Do we have the right engine?
if ($engine !== 'innodb' && $engine !== 'xtradb') {
cli_error("Error: '$collation' requires InnoDB or XtraDB set as the engine.");
}
// Are we using Barracuda?
if ($DB->get_row_format() != 'Barracuda') {
// Try setting it here.
try {
$DB->execute("SET GLOBAL innodb_file_format=Barracuda");
} catch (dml_exception $e) {
cli_error("Error: '$collation' requires the file format to be set to Barracuda.
An attempt was made to change the format, but it failed. Please try doing this manually.");
}
echo "GLOBAL SETTING: innodb_file_format changed to Barracuda\n";
}
// Is one file per table being used?
if (!$DB->is_file_per_table_enabled()) {
try {
$DB->execute("SET GLOBAL innodb_file_per_table=1");
} catch (dml_exception $e) {
cli_error("Error: '$collation' requires the setting 'innodb_file_per_table' be set to 'ON'.
An attempt was made to change the format, but it failed. Please try doing this manually.");
}
echo "GLOBAL SETTING: innodb_file_per_table changed to 1\n";
}
// Is large prefix set?
if (!$DB->is_large_prefix_enabled()) {
try {
$DB->execute("SET GLOBAL innodb_large_prefix=1");
} catch (dml_exception $e) {
cli_error("Error: '$collation' requires the setting 'innodb_large_prefix' be set to 'ON'.
An attempt was made to change the format, but it failed. Please try doing this manually.");
}
echo "GLOBAL SETTING: innodb_large_prefix changed to 1\n";
}
}
$sql = "SHOW VARIABLES LIKE 'collation_database'";
if (!$dbcollation = $DB->get_record_sql($sql)) {
cli_error("Error: Could not access collation information on the database.");
}
$sql = "SHOW VARIABLES LIKE 'character_set_database'";
if (!$dbcharset = $DB->get_record_sql($sql)) {
cli_error("Error: Could not access character set information on the database.");
}
if ($dbcollation->value !== $collation || $dbcharset->value !== $charset) {
// Try to convert the DB.
echo "Converting database to '$collation' for $CFG->wwwroot:\n";
$sql = "ALTER DATABASE $CFG->dbname DEFAULT CHARACTER SET $charset DEFAULT COLLATE = $collation";
try {
$DB->change_database_structure($sql);
} catch (exception $e) {
cli_error("Error: Tried to alter the database with no success. Please try manually changing the database
to the new collation and character set and then run this script again.");
}
echo "DATABASE CONVERTED\n";
}
echo "Converting tables and columns to '$collation' for $CFG->wwwroot:\n"; echo "Converting tables and columns to '$collation' for $CFG->wwwroot:\n";
$prefix = $DB->get_prefix(); $prefix = $DB->get_prefix();
$prefix = str_replace('_', '\\_', $prefix); $prefix = str_replace('_', '\\_', $prefix);
...@@ -80,7 +145,7 @@ if (!empty($options['collation'])) { ...@@ -80,7 +145,7 @@ if (!empty($options['collation'])) {
$skipped++; $skipped++;
} else { } else {
$DB->change_database_structure("ALTER TABLE $table->name DEFAULT COLLATE = $collation"); $DB->change_database_structure("ALTER TABLE $table->name DEFAULT CHARACTER SET $charset DEFAULT COLLATE = $collation");
echo "CONVERTED\n"; echo "CONVERTED\n";
$converted++; $converted++;
} }
...@@ -96,18 +161,32 @@ if (!empty($options['collation'])) { ...@@ -96,18 +161,32 @@ if (!empty($options['collation'])) {
continue; continue;
} }
// Check for utf8mb4 collation.
$rowformat = $DB->get_row_format_sql($engine, $collation);
if ($column->type === 'tinytext' or $column->type === 'mediumtext' or $column->type === 'text' or $column->type === 'longtext') { if ($column->type === 'tinytext' or $column->type === 'mediumtext' or $column->type === 'text' or $column->type === 'longtext') {
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL'; $notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
$default = (!is_null($column->default) and $column->default !== '') ? "DEFAULT '$column->default'" : ''; $default = (!is_null($column->default) and $column->default !== '') ? "DEFAULT '$column->default'" : '';
// primary, unique and inc are not supported for texts // primary, unique and inc are not supported for texts
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default"; $sql = "ALTER TABLE $table->name
MODIFY COLUMN $column->field $column->type
CHARACTER SET $charset
COLLATE $collation $notnull $default";
$DB->change_database_structure($sql); $DB->change_database_structure($sql);
} else if (strpos($column->type, 'varchar') === 0) { } else if (strpos($column->type, 'varchar') === 0) {
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL'; $notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
$default = !is_null($column->default) ? "DEFAULT '$column->default'" : ''; $default = !is_null($column->default) ? "DEFAULT '$column->default'" : '';
// primary, unique and inc are not supported for texts
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default"; if ($rowformat != '') {
$sql = "ALTER TABLE $table->name $rowformat";
$DB->change_database_structure($sql);
}
$sql = "ALTER TABLE $table->name
MODIFY COLUMN $column->field $column->type
CHARACTER SET $charset
COLLATE $collation $notnull $default";
$DB->change_database_structure($sql); $DB->change_database_structure($sql);
} else { } else {
echo "ERROR (unknown column type: $column->type)\n"; echo "ERROR (unknown column type: $column->type)\n";
...@@ -180,7 +259,9 @@ function mysql_get_collations() { ...@@ -180,7 +259,9 @@ function mysql_get_collations() {
global $DB; global $DB;
$collations = array(); $collations = array();
$sql = "SHOW COLLATION WHERE Collation LIKE 'utf8\_%' AND Charset = 'utf8'"; $sql = "SHOW COLLATION
WHERE Collation LIKE 'utf8\_%' AND Charset = 'utf8'
OR Collation LIKE 'utf8mb4\_%' AND Charset = 'utf8mb4'";
$rs = $DB->get_recordset_sql($sql); $rs = $DB->get_recordset_sql($sql);
foreach ($rs as $collation) { foreach ($rs as $collation) {
$collations[$collation->collation] = $collation->collation; $collations[$collation->collation] = $collation->collation;
......
...@@ -1723,6 +1723,21 @@ ...@@ -1723,6 +1723,21 @@
<ON_CHECK message="libcurlwarning" /> <ON_CHECK message="libcurlwarning" />
</FEEDBACK> </FEEDBACK>
</CUSTOM_CHECK> </CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfileformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfilepertable" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddblargeprefix" />
</FEEDBACK>
</CUSTOM_CHECK>
</CUSTOM_CHECKS> </CUSTOM_CHECKS>
</MOODLE> </MOODLE>
<MOODLE version="3.2" requires="2.7"> <MOODLE version="3.2" requires="2.7">
...@@ -1873,6 +1888,21 @@ ...@@ -1873,6 +1888,21 @@
<ON_CHECK message="libcurlwarning" /> <ON_CHECK message="libcurlwarning" />
</FEEDBACK> </FEEDBACK>
</CUSTOM_CHECK> </CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfileformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfilepertable" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddblargeprefix" />
</FEEDBACK>
</CUSTOM_CHECK>
</CUSTOM_CHECKS> </CUSTOM_CHECKS>
</MOODLE> </MOODLE>
</COMPATIBILITY_MATRIX> </COMPATIBILITY_MATRIX>
...@@ -63,6 +63,13 @@ $CFG->dboptions = array( ...@@ -63,6 +63,13 @@ $CFG->dboptions = array(
// support advanced options on connection. // support advanced options on connection.
// If you set those in the database then // If you set those in the database then
// the advanced settings will not be sent. // the advanced settings will not be sent.
'dbcollation' => 'utf8mb4_unicode_ci', // MySQL has partial and full UTF-8
// support. If you wish to use partial UTF-8
// (three bytes) then set this option to
// 'utf8_unicode_ci', otherwise this option
// can be removed for MySQL (by default it will
// use 'utf8mb4_unicode_ci'. This option should
// be removed for all other databases.
); );
......
...@@ -596,6 +596,7 @@ $string['htmlsettings'] = 'HTML settings'; ...@@ -596,6 +596,7 @@ $string['htmlsettings'] = 'HTML settings';
$string['http'] = 'HTTP'; $string['http'] = 'HTTP';
$string['httpsecurity'] = 'HTTP security'; $string['httpsecurity'] = 'HTTP security';
$string['hubs'] = 'Hubs'; $string['hubs'] = 'Hubs';
$string['incompleteunicodesupport'] = 'The current setup of MySQL or MariaDB is using \'utf8\'. This character set does not support four byte characters which include some emoji. Trying to use these characters will result in an error when updating a record, and any information being sent to the database will be lost. Please consider changing your settings to \'utf8mb4\'. See the documentation for full details.';
$string['change'] = 'change'; $string['change'] = 'change';
$string['checkboxno'] = 'No'; $string['checkboxno'] = 'No';
$string['checkboxyes'] = 'Yes'; $string['checkboxyes'] = 'Yes';
...@@ -1133,6 +1134,9 @@ $string['unlockaccount'] = 'Unlock account'; ...@@ -1133,6 +1134,9 @@ $string['unlockaccount'] = 'Unlock account';
$string['unoconvwarning'] = 'The version of unoconv you have installed is not supported. Moodle\'s assignment grading feature requires version 0.7 or higher.'; $string['unoconvwarning'] = 'The version of unoconv you have installed is not supported. Moodle\'s assignment grading feature requires version 0.7 or higher.';
$string['unsettheme'] = 'Unset theme'; $string['unsettheme'] = 'Unset theme';
$string['unsupported'] = 'Unsupported'; $string['unsupported'] = 'Unsupported';
$string['unsupporteddbfileformat'] = 'Your database has tables using Antelope as the file format. Full UTF-8 support in MySQL and MariaDB requires the Barracuda file format. Please convert the tables to the Barracuda file format. See the documentation <a href="https://docs.moodle.org/en/cli">Administration via command line</a> for details of a tool for converting InnoDB tables to Barracuda.';
$string['unsupporteddbfilepertable'] = 'For full support of UTF-8 both MySQL and MariaDB require you to change your MySQL setting \'innodb_file_per_table\' to \'ON\'. See the documentation for further details.';
$string['unsupporteddblargeprefix'] = 'For full support of UTF-8 both MySQL and MariaDB require you to change your MySQL setting \'innodb_large_prefix\' to \'ON\'. See the documentation for further details.';
$string['unsupporteddbstorageengine'] = 'The database storage engine being used is no longer supported.'; $string['unsupporteddbstorageengine'] = 'The database storage engine being used is no longer supported.';
$string['unsupporteddbtablerowformat'] = 'Your database has tables using Antelope as the file format. You are recommended to convert the tables to the Barracuda file format. See the documentation <a href="https://docs.moodle.org/en/cli">Administration via command line</a> for details of a tool for converting InnoDB tables to Barracuda.'; $string['unsupporteddbtablerowformat'] = 'Your database has tables using Antelope as the file format. You are recommended to convert the tables to the Barracuda file format. See the documentation <a href="https://docs.moodle.org/en/cli">Administration via command line</a> for details of a tool for converting InnoDB tables to Barracuda.';
$string['unsupportedphpversion7'] = 'PHP version 7 is not supported.'; $string['unsupportedphpversion7'] = 'PHP version 7 is not supported.';
......
...@@ -218,6 +218,9 @@ class mysql_sql_generator extends sql_generator { ...@@ -218,6 +218,9 @@ class mysql_sql_generator extends sql_generator {
} }
} }
$utf8mb4rowformat = $this->mdb->get_row_format_sql($engine, $collation);
$rowformat = ($utf8mb4rowformat == '') ? $rowformat : $utf8mb4rowformat;
$sqlarr = parent::getCreateTableSQL($xmldb_table); $sqlarr = parent::getCreateTableSQL($xmldb_table);
// This is a very nasty hack that tries to use just one query per created table // This is a very nasty hack that tries to use just one query per created table
...@@ -238,7 +241,7 @@ class mysql_sql_generator extends sql_generator { ...@@ -238,7 +241,7 @@ class mysql_sql_generator extends sql_generator {
if (strpos($collation, 'utf8_') === 0) { if (strpos($collation, 'utf8_') === 0) {
$sql .= "\n DEFAULT CHARACTER SET utf8"; $sql .= "\n DEFAULT CHARACTER SET utf8";
} }
$sql .= "\n DEFAULT COLLATE = $collation"; $sql .= "\n DEFAULT COLLATE = $collation ";
} }
if ($rowformat) { if ($rowformat) {
$sql .= $rowformat; $sql .= $rowformat;
...@@ -326,10 +329,13 @@ class mysql_sql_generator extends sql_generator { ...@@ -326,10 +329,13 @@ class mysql_sql_generator extends sql_generator {
* @return array of sql statements * @return array of sql statements
*/ */
public function getCreateTempTableSQL($xmldb_table) { public function getCreateTempTableSQL($xmldb_table) {
$engine = $this->mdb->get_dbengine();
// Do we know collation? // Do we know collation?
$collation = $this->mdb->get_dbcollation(); $collation = $this->mdb->get_dbcollation();
$this->temptables->add_temptable($xmldb_table->getName()); $this->temptables->add_temptable($xmldb_table->getName());
$rowformat = $this->mdb->get_row_format_sql($engine, $collation);
$sqlarr = parent::getCreateTableSQL($xmldb_table); $sqlarr = parent::getCreateTableSQL($xmldb_table);
// Let's inject the extra MySQL tweaks. // Let's inject the extra MySQL tweaks.
...@@ -341,7 +347,7 @@ class mysql_sql_generator extends sql_generator { ...@@ -341,7 +347,7 @@ class mysql_sql_generator extends sql_generator {
if (strpos($collation, 'utf8_') === 0) { if (strpos($collation, 'utf8_') === 0) {
$sqlarr[$i] .= " DEFAULT CHARACTER SET utf8"; $sqlarr[$i] .= " DEFAULT CHARACTER SET utf8";
} }
$sqlarr[$i] .= " DEFAULT COLLATE $collation"; $sqlarr[$i] .= " DEFAULT COLLATE $collation $rowformat";
} }
} }
} }
......
...@@ -584,7 +584,7 @@ class core_ddl_testcase extends database_driver_testcase { ...@@ -584,7 +584,7 @@ class core_ddl_testcase extends database_driver_testcase {
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('name', XMLDB_TYPE_CHAR, '30', null, null, null, null); $table->add_field('name', XMLDB_TYPE_CHAR, '30', null, null, null, null);
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
for ($i = 0; $i < 15; $i++) { for ($i = 0; $i < 12; $i++) {
$table->add_field('text'.$i, XMLDB_TYPE_CHAR, '1333', null, null, null, null); $table->add_field('text'.$i, XMLDB_TYPE_CHAR, '1333', null, null, null, null);
$data->{'text'.$i} = $text; $data->{'text'.$i} = $text;
} }
......
...@@ -85,13 +85,19 @@ class mysqli_native_moodle_database extends moodle_database { ...@@ -85,13 +85,19 @@ class mysqli_native_moodle_database extends moodle_database {
throw new dml_connection_exception($dberr); throw new dml_connection_exception($dberr);
} }
if (isset($dboptions['dbcollation']) and strpos($dboptions['dbcollation'], 'utf8_') === 0) { // Normally a check would be done before setting utf8mb4, but the database can be created
// before the enviroment checks are done. We'll proceed with creating the database and then do checks next.
$charset = 'utf8mb4';
if (isset($dboptions['dbcollation']) and (strpos($dboptions['dbcollation'], 'utf8_') === 0
|| strpos($dboptions['dbcollation'], 'utf8mb4_') === 0)) {
$collation = $dboptions['dbcollation']; $collation = $dboptions['dbcollation'];
$collationinfo = explode('_', $dboptions['dbcollation']);
$charset = reset($collationinfo);
} else { } else {
$collation = 'utf8_unicode_ci'; $collation = 'utf8mb4_unicode_ci';
} }
$result = $conn->query("CREATE DATABASE $dbname DEFAULT CHARACTER SET utf8 DEFAULT COLLATE ".$collation); $result = $conn->query("CREATE DATABASE $dbname DEFAULT CHARACTER SET $charset DEFAULT COLLATE ".$collation);
$conn->close(); $conn->close();
...@@ -246,6 +252,7 @@ class mysqli_native_moodle_database extends moodle_database { ...@@ -246,6 +252,7 @@ class mysqli_native_moodle_database extends moodle_database {
} }
$result->close(); $result->close();
if (!$collation) { if (!$collation) {
// Get the default database collation, but only if using UTF-8. // Get the default database collation, but only if using UTF-8.
$sql = "SELECT @@collation_database"; $sql = "SELECT @@collation_database";
...@@ -253,7 +260,7 @@ class mysqli_native_moodle_database extends moodle_database { ...@@ -253,7 +260,7 @@ class mysqli_native_moodle_database extends moodle_database {
$result = $this->mysqli->query($sql); $result = $this->mysqli->query($sql);
$this->query_end($result); $this->query_end($result);
if ($rec = $result->fetch_assoc()) { if ($rec = $result->fetch_assoc()) {
if (strpos($rec['@@collation_database'], 'utf8_') === 0) { if (strpos($rec['@@collation_database'], 'utf8_') === 0 || strpos($rec['@@collation_database'], 'utf8mb4_') === 0) {
$collation = $rec['@@collation_database']; $collation = $rec['@@collation_database'];
} }
} }
...@@ -263,7 +270,7 @@ class mysqli_native_moodle_database extends moodle_database { ...@@ -263,7 +270,7 @@ class mysqli_native_moodle_database extends moodle_database {
if (!$collation) { if (!$collation) {
// We want only utf8 compatible collations. // We want only utf8 compatible collations.
$collation = null; $collation = null;
$sql = "SHOW COLLATION WHERE Collation LIKE 'utf8\_%' AND Charset = 'utf8'"; $sql = "SHOW COLLATION WHERE Collation LIKE 'utf8mb4\_%' AND Charset = 'utf8mb4'";
$this->query_start($sql, NULL, SQL_QUERY_AUX); $this->query_start($sql, NULL, SQL_QUERY_AUX);
$result = $this->mysqli->query($sql); $result = $this->mysqli->query($sql);
$this->query_end($result); $this->query_end($result);
...@@ -288,17 +295,25 @@ class mysqli_native_moodle_database extends moodle_database { ...@@ -288,17 +295,25 @@ class mysqli_native_moodle_database extends moodle_database {
* @param string $table * @param string $table
* @return string row_format name or null if not known or table does not exist. * @return string row_format name or null if not known or table does not exist.
*/ */
public function get_row_format($table) { public function get_row_format($table = null) {
$rowformat = null; $rowformat = null;
$table = $this->mysqli->real_escape_string($table); if (isset($table)) {
$sql = "SELECT row_format $table = $this->mysqli->real_escape_string($table);
FROM INFORMATION_SCHEMA.TABLES $sql = "SELECT row_format
WHERE table_schema = DATABASE() AND table_name = '{$this->prefix}$table'"; FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = DATABASE() AND table_name = '{$this->prefix}$table'";
} else {
$sql = "SHOW VARIABLES LIKE 'innodb_file_format'";
}
$this->query_start($sql, NULL, SQL_QUERY_AUX); $this->query_start($sql, NULL, SQL_QUERY_AUX);
$result = $this->mysqli->query($sql); $result = $this->mysqli->query($sql);
$this->query_end($result); $this->query_end($result);
if ($rec = $result->fetch_assoc()) { if ($rec = $result->fetch_assoc()) {
$rowformat = $rec['row_format']; if (isset($table)) {
$rowformat = $rec['row_format'];
} else {
$rowformat = $rec['Value'];
}
} }
$result->close(); $result->close();
...@@ -329,16 +344,10 @@ class mysqli_native_moodle_database extends moodle_database { ...@@ -329,16 +344,10 @@ class mysqli_native_moodle_database extends moodle_database {
// Other engines are not supported, most probably not compatible. // Other engines are not supported, most probably not compatible.
$this->compressedrowformatsupported = false; $this->compressedrowformatsupported = false;
} else if (!$filepertable = $this->get_record_sql("SHOW VARIABLES LIKE 'innodb_file_per_table'")) { } else if (!$this->is_file_per_table_enabled()) {
$this->compressedrowformatsupported = false; $this->compressedrowformatsupported = false;
} else if ($filepertable->value !== 'ON') { } else if ($this->get_row_format() !== 'Barracuda') {
$this->compressedrowformatsupported = false;
} else if (!$fileformat = $this->get_record_sql("SHOW VARIABLES LIKE 'innodb_file_format'")) {
$this->compressedrowformatsupported = false;
} else if ($fileformat->value !== 'Barracuda') {
$this->compressedrowformatsupported = false; $this->compressedrowformatsupported = false;
} else { } else {
...@@ -349,6 +358,67 @@ class mysqli_native_moodle_database extends moodle_database { ...@@ -349,6 +358,67 @@ class mysqli_native_moodle_database extends moodle_database {
return $this->compressedrowformatsupported; return $this->compressedrowformatsupported;
} }
/**
* Check the database to see if innodb_file_per_table is on.
*
* @return bool True if on otherwise false.
*/
public function is_file_per_table_enabled() {
if ($filepertable = $this->get_record_sql("SHOW VARIABLES LIKE 'innodb_file_per_table'")) {
if ($filepertable->value == 'ON') {
return true;
}
}
return false;
}
/**
* Check the database to see if innodb_large_prefix is on.
*
* @return bool True if on otherwise false.
*/
public function is_large_prefix_enabled() {
if ($largeprefix = $this->get_record_sql("SHOW VARIABLES LIKE 'innodb_large_prefix'")) {
if ($largeprefix->value == 'ON') {
return true;
}
}
return false;
}
/**
* Determine if the row format should be set to compressed, dynamic, or default.
*
* Terrible kludge. If we're using utf8mb4 AND we're using InnoDB, we need to specify row format to
* be either dynamic or compressed (default is compact) in order to allow for bigger indexes (MySQL
* errors #1709 and #1071).
*
* @param string $engine The database engine being used. Will be looked up if not supplied.
* @param string $collation The database collation to use. Will look up the current collation if not supplied.
* @return string An sql fragment to add to sql statements.
*/
public function get_row_format_sql($engine = null, $collation = null) {
if (!isset($engine)) {
$engine = $this->get_dbengine();
}
$engine = strtolower($engine);
if (!isset($collation)) {
$collation = $this->get_dbcollation();
}
$rowformat = '';
if (($engine === 'innodb' || $engine === 'xtradb') && strpos($collation, 'utf8mb4_') === 0) {
if ($this->is_compressed_row_format_supported()) {
$rowformat = "ROW_FORMAT=Compressed";
} else {
$rowformat = "ROW_FORMAT=Dynamic";
}
}
return $rowformat;
}
/** /**
* Returns localised database type name * Returns localised database type name
* Note: can be used before connect() * Note: can be used before connect()
...@@ -449,11 +519,19 @@ class mysqli_native_moodle_database extends moodle_database { ...@@ -449,11 +519,19 @@ class mysqli_native_moodle_database extends moodle_database {
throw new dml_connection_exception($dberr); throw new dml_connection_exception($dberr);
} }
if (isset($dboptions['dbcollation'])) {
$collationinfo = explode('_', $dboptions['dbcollation']);
$this->dboptions['dbcollation'] = $dboptions['dbcollation'];
} else {
$collationinfo = explode('_', $this->get_dbcollation());
}
$charset = reset($collationinfo);
// Disable logging until we are fully setup. // Disable logging until we are fully setup.
$this->query_log_prevent(); $this->query_log_prevent();
$this->query_start("--set_charset()", null, SQL_QUERY_AUX); $this->query_start("--set_charset()", null, SQL_QUERY_AUX);
$this->mysqli->set_charset('utf8'); $this->mysqli->set_charset($charset);
$this->query_end(true); $this->query_end(true);
// If available, enforce strict mode for the session. That guaranties // If available, enforce strict mode for the session. That guaranties
...@@ -885,7 +963,10 @@ class mysqli_native_moodle_database extends moodle_database { ...@@ -885,7 +963,10 @@ class mysqli_native_moodle_database extends moodle_database {
// if config table already exists it has this collation too. // if config table already exists it has this collation too.
$collation = $this->get_dbcollation(); $collation = $this->get_dbcollation();
$sql = "SHOW COLLATION WHERE Collation ='$collation' AND Charset = 'utf8'"; $collationinfo = explode('_', $collation);
$charset = reset($collationinfo);
$sql = "SHOW COLLATION WHERE Collation ='$collation' AND Charset = '$charset'";
$this->query_start($sql, NULL, SQL_QUERY_AUX); $this->query_start($sql, NULL, SQL_QUERY_AUX);
$result = $this->mysqli->query($sql); $result = $this->mysqli->query($sql);
$this->query_end($result); $this->query_end($result);
...@@ -1519,17 +1600,23 @@ class mysqli_native_moodle_database extends moodle_database { ...@@ -1519,17 +1600,23 @@ class mysqli_native_moodle_database extends moodle_database {