forked from GNUsocial/gnu-social
[DATABASE] Change collation handling
Before now table definitions could define collations only for MariaDB using the MariaDB's collation names directly. Now instead definitions get a slightly more abstract collation name syntax, but only supporting the collations utf8mb4_bin and utf8mb4_unicode_(cs|ci) (wrapped as utf8_bin, utf8_general_(cs|ci)), because those are the ones that have practical use for GNU social. Which also means that on MariaDB the formerly used utf8mb4_general_(cs|ci) have been superseded by utf8mb4_unicode_(cs|ci), as they are the more modern replacement. Introduce collation support on PostgreSQL which results in use of the C (POSIX) collation as utf8_bin and the und-x-icu collation as utf8_general_cs. utf8_general_ci is also mapped to und-x-icu, which makes it case-sensitive, unfortunately.
This commit is contained in:
@@ -891,6 +891,48 @@ class Schema
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this column a string type?
|
||||
*
|
||||
* @param array $cd
|
||||
* @return bool
|
||||
*/
|
||||
protected function isStringType(array $cd): bool
|
||||
{
|
||||
$strings = ['char', 'varchar', 'text'];
|
||||
$strings[] = 'bpchar'; // PostgreSQL
|
||||
$strings[] = 'enum'; // MariaDB
|
||||
return in_array(strtolower($cd['type']), $strings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collation in our format from MariaDB format
|
||||
*
|
||||
* @param string $collate
|
||||
* @return string
|
||||
*/
|
||||
protected function collationFromMySQL(string $collate): string
|
||||
{
|
||||
if (substr($collate, 0, 8) === 'utf8mb4_') {
|
||||
$collate = 'utf8_' . substr($collate, 8);
|
||||
}
|
||||
if (substr($collate, 0, 13) === 'utf8_unicode_') {
|
||||
$collate = 'utf8_general_' . substr($collate, 13);
|
||||
}
|
||||
if (!in_array($collate, [
|
||||
'utf8_bin',
|
||||
'utf8_general_cs',
|
||||
'utf8_general_ci',
|
||||
])) {
|
||||
common_log(
|
||||
LOG_ERR,
|
||||
'Collation not supported: "' . $collate . '"'
|
||||
);
|
||||
$collate = 'utf8_bin';
|
||||
}
|
||||
return $collate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the proper SQL for creating or
|
||||
* altering a column.
|
||||
@@ -1059,6 +1101,15 @@ class Schema
|
||||
if (array_key_exists('not null', $col) && $col['not null'] !== true) {
|
||||
unset($col['not null']);
|
||||
}
|
||||
|
||||
if ($this->isStringType($col)) {
|
||||
// Default collation
|
||||
if (empty($col['collate'])) {
|
||||
$col['collate'] = 'utf8_bin';
|
||||
}
|
||||
// Migration from direct MariaDB collations
|
||||
$col['collate'] = $this->collationFromMySQL($col['collate']);
|
||||
}
|
||||
}
|
||||
|
||||
if (common_config('search', 'type') !== 'fulltext') {
|
||||
|
Reference in New Issue
Block a user