Skip to content

Commit

Permalink
Merge pull request #28777 from nextcloud/backport/28677/stable22
Browse files Browse the repository at this point in the history
[stable22] make it possible to  override the default collation on mysql
  • Loading branch information
blizzz authored Sep 10, 2021
2 parents c7159f9 + f353dd9 commit c57a621
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 9 deletions.
18 changes: 18 additions & 0 deletions config/config.sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -1543,6 +1543,24 @@
*/
'mysql.utf8mb4' => false,

/**
* For search queries in the database, a default collation – depending on the
* character set – is chosen. In some cases a different behaviour is desired,
* for instances when a accent sensitive search is desired.
*
* MariaDB and MySQL have an overlap in available collations, but also
* incompatible ones, also depending on the version of the database server.
*
* This option allows to override the automatic choice. Example:
*
* 'mysql.collation' => 'utf8mb4_0900_as_ci',
*
* This setting has no effect on setup or creating tables. In those cases
* always utf8[mb4]_bin is being used. This setting is only taken into
* consideration in SQL queries that utilize LIKE comparison operators.
*/
'mysql.collation' => null,

/**
* Database types that are supported for installation.
*
Expand Down
12 changes: 6 additions & 6 deletions lib/private/DB/AdapterMySQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
class AdapterMySQL extends Adapter {

/** @var string */
protected $charset;
protected $collation;

/**
* @param string $tableName
Expand All @@ -39,16 +39,16 @@ public function unlockTable() {
}

public function fixupStatement($statement) {
$statement = str_replace(' ILIKE ', ' COLLATE ' . $this->getCharset() . '_general_ci LIKE ', $statement);
$statement = str_replace(' ILIKE ', ' COLLATE ' . $this->getCollation() . ' LIKE ', $statement);
return $statement;
}

protected function getCharset() {
if (!$this->charset) {
protected function getCollation(): string {
if (!$this->collation) {
$params = $this->conn->getParams();
$this->charset = isset($params['charset']) ? $params['charset'] : 'utf8';
$this->collation = $params['collation'] ?? (($params['charset'] ?? 'utf8') . '_general_ci');
}

return $this->charset;
return $this->collation;
}
}
4 changes: 4 additions & 0 deletions lib/private/DB/ConnectionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ public function __construct(SystemConfig $systemConfig) {
if ($this->config->getValue('mysql.utf8mb4', false)) {
$this->defaultConnectionParams['mysql']['charset'] = 'utf8mb4';
}
$collationOverride = $this->config->getValue('mysql.collation', null);
if ($collationOverride) {
$this->defaultConnectionParams['mysql']['collation'] = $collationOverride;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
class MySqlExpressionBuilder extends ExpressionBuilder {

/** @var string */
protected $charset;
protected $collation;

/**
* @param ConnectionAdapter $connection
Expand All @@ -41,7 +41,7 @@ public function __construct(ConnectionAdapter $connection, IQueryBuilder $queryB
parent::__construct($connection, $queryBuilder);

$params = $connection->getInner()->getParams();
$this->charset = isset($params['charset']) ? $params['charset'] : 'utf8';
$this->collation = $params['collation'] ?? (($params['charset'] ?? 'utf8') . '_general_ci');
}

/**
Expand All @@ -50,6 +50,6 @@ public function __construct(ConnectionAdapter $connection, IQueryBuilder $queryB
public function iLike($x, $y, $type = null): string {
$x = $this->helper->quoteColumnName($x);
$y = $this->helper->quoteColumnName($y);
return $this->expressionBuilder->comparison($x, ' COLLATE ' . $this->charset . '_general_ci LIKE', $y);
return $this->expressionBuilder->comparison($x, ' COLLATE ' . $this->collation . ' LIKE', $y);
}
}

0 comments on commit c57a621

Please sign in to comment.