* Detect at installation/upgrade time how the database refers to the utf8 variant Bugzilla wants to use so that we don't accidentally reconvert the database to the same encoding it's already using on every run on checksetup.pl
* Change the default charset on new installs to utf8mb4.
a=dylan
sub check_utf8 {
my ($utf8, $entry) = @_;
-
# You cannot turn off the UTF-8 parameter.
+ my $current_utf8 = Bugzilla->params->{'utf8'};
if (!$utf8) {
return "You cannot disable UTF-8 support.";
}
- elsif ($entry eq 'utf8mb4' && $utf8 ne 'utf8mb4') {
+ elsif ($current_utf8 eq 'utf8mb3' && $utf8 ne 'utf8mb3' && $utf8 ne 'utf8mb4') {
+ return "You cannot downgrade from utf8mb3 support, only keep it or change to utf8mb4.";
+ }
+ elsif ($current_utf8 eq 'utf8mb4' && $utf8 ne 'utf8mb4') {
return "You cannot disable UTF8-MB4 support.";
}
{
name => 'utf8',
type => 's',
- choices => ['1', 'utf8', 'utf8mb4'],
- default => 'utf8',
+ choices => ['1', 'utf8', 'utf8mb3', 'utf8mb4'],
+ default => 'utf8mb4',
checker => \&check_utf8
},
+ {
+ name => 'utf8_collate',
+ type => 'r',
+ no_reset => '1',
+ default => 'utf8mb4_unicode_520_ci',
+ },
+
+
{name => 'shutdownhtml', type => 'l', default => ''},
{name => 'announcehtml', type => 'l', default => ''},
use Bugzilla::Constants;
use Bugzilla::Install::Util qw(install_string);
+use Bugzilla::Config;
use Bugzilla::Util;
use Bugzilla::Error;
use Bugzilla::DB::Schema::MariaDB;
sub bz_setup_database {
my ($self) = @_;
+ # Before touching anything else, find out whether this database server does
+ # any aliasing of the character set we plan to use so we can check for
+ # already converted tables properly. We do this by creating a table as our
+ # intended charset and then test how it reads back.
+ my $db_name = Bugzilla->localconfig->{db_name};
+ my $charset = $self->utf8_charset;
+ my $collate = $self->utf8_collate;
+ $self->do("CREATE TABLE `utf8_test` (id tinyint) CHARACTER SET ? COLLATE ?", undef, $charset, $collate);
+ my ($found_collate) = $self->selectrow_array("SELECT TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA=? AND TABLE_NAME='utf8_test'", undef, $db_name);
+ $self->do("DROP TABLE `utf8_test`");
+ my ($found_charset) = ($found_collate =~ m/^([a-z0-9]+)_/);
+ Bugzilla->params->{'utf8'} = $found_charset;
+ Bugzilla->params->{'utf8_collate'} = $found_collate;
+ Bugzilla::Config::write_params();
+ # reload these because they get used later.
+ $charset = $self->utf8_charset;
+ $collate = $self->utf8_collate;
+
# The "comments" field of the bugs_fulltext table could easily exceed
# MySQL's default max_allowed_packet. Also, MySQL should never have
# a max_allowed_packet smaller than our max_attachment_size. So, we
}
# Upgrade tables from MyISAM to InnoDB
- my $db_name = Bugzilla->localconfig->{db_name};
my $myisam_tables = $self->selectcol_arrayref(
'SELECT TABLE_NAME FROM information_schema.TABLES
WHERE TABLE_SCHEMA = ? AND ENGINE = ?', undef, $db_name, 'MyISAM'
# the table charsets.
#
# TABLE_COLLATION IS NOT NULL prevents us from trying to convert views.
- my $charset = $self->utf8_charset;
- my $collate = $self->utf8_collate;
my $non_utf8_tables = $self->selectrow_array(
"SELECT 1 FROM information_schema.TABLES
WHERE TABLE_SCHEMA = ? AND TABLE_COLLATION IS NOT NULL
}
sub utf8_charset {
- return 'utf8' unless Bugzilla->params->{'utf8'};
- return Bugzilla->params->{'utf8'} eq 'utf8mb4' ? 'utf8mb4' : 'utf8mb3';
+ return 'utf8mb4' unless Bugzilla->params->{'utf8'};
+ return 'utf8mb4' if Bugzilla->params->{'utf8'} eq '1';
+ return Bugzilla->params->{'utf8'};
}
sub utf8_collate {
my $charset = utf8_charset();
- if ($charset eq 'utf8') {
- return 'utf8_general_ci';
- }
- elsif ($charset eq 'utf8mb3') {
- return 'utf8mb3_general_ci';
- }
- elsif ($charset eq 'utf8mb4') {
- return 'utf8mb4_unicode_520_ci';
- }
- else {
- croak "invalid charset: $charset";
- }
+ return $charset . '_unicode_520_ci' unless Bugzilla->params->{'utf8_collate'};
+ return $charset . '_unicode_520_ci' unless (Bugzilla->params->{'utf8_collate'} =~ /^${charset}_/);
+ return Bugzilla->params->{'utf8_collate'};
}
sub default_row_format {
use Bugzilla::Constants;
use Bugzilla::Install::Util qw(install_string);
+use Bugzilla::Config;
use Bugzilla::Util;
use Bugzilla::Error;
use Bugzilla::DB::Schema::Mysql;
sub bz_setup_database {
my ($self) = @_;
+ # Before touching anything else, find out whether this database server does
+ # any aliasing of the character set we plan to use so we can check for
+ # already converted tables properly. We do this by creating a table as our
+ # intended charset and then test how it reads back.
+ my $db_name = Bugzilla->localconfig->{db_name};
+ my $charset = $self->utf8_charset;
+ my $collate = $self->utf8_collate;
+ $self->do("CREATE TABLE `utf8_test` (id tinyint) CHARACTER SET ? COLLATE ?", undef, $charset, $collate);
+ my ($found_collate) = $self->selectrow_array("SELECT TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA=? AND TABLE_NAME='utf8_test'", undef, $db_name);
+ $self->do("DROP TABLE `utf8_test`");
+ my ($found_charset) = ($found_collate =~ m/^([a-z0-9]+)_/);
+ Bugzilla->params->{'utf8'} = $found_charset;
+ Bugzilla->params->{'utf8_collate'} = $found_collate;
+ Bugzilla::Config::write_params();
+ # reload these because they get used later.
+ $charset = $self->utf8_charset;
+ $collate = $self->utf8_collate;
+
# The "comments" field of the bugs_fulltext table could easily exceed
# MySQL's default max_allowed_packet. Also, MySQL should never have
# a max_allowed_packet smaller than our max_attachment_size. So, we
}
# Upgrade tables from MyISAM to InnoDB
- my $db_name = Bugzilla->localconfig->{db_name};
my $myisam_tables = $self->selectcol_arrayref(
'SELECT TABLE_NAME FROM information_schema.TABLES
WHERE TABLE_SCHEMA = ? AND ENGINE = ?', undef, $db_name, 'MyISAM'
# the table charsets.
#
# TABLE_COLLATION IS NOT NULL prevents us from trying to convert views.
- my $charset = $self->utf8_charset;
- my $collate = $self->utf8_collate;
my $non_utf8_tables = $self->selectrow_array(
"SELECT 1 FROM information_schema.TABLES
WHERE TABLE_SCHEMA = ? AND TABLE_COLLATION IS NOT NULL
}
sub utf8_charset {
- return 'utf8' unless Bugzilla->params->{'utf8'};
- return Bugzilla->params->{'utf8'} eq 'utf8mb4' ? 'utf8mb4' : 'utf8';
+ return 'utf8mb4' unless Bugzilla->params->{'utf8'};
+ return 'utf8mb4' if Bugzilla->params->{'utf8'} eq '1';
+ return Bugzilla->params->{'utf8'};
}
sub utf8_collate {
my $charset = utf8_charset();
- if ($charset eq 'utf8') {
- return 'utf8_general_ci';
- }
- elsif ($charset eq 'utf8mb4') {
- return 'utf8mb4_unicode_520_ci';
- }
- else {
- croak "invalid charset: $charset";
- }
+ return $charset . '_unicode_520_ci' unless Bugzilla->params->{'utf8_collate'};
+ return $charset . '_unicode_520_ci' unless (Bugzilla->params->{'utf8_collate'} =~ /^${charset}_/);
+ return Bugzilla->params->{'utf8_collate'};
}
sub default_row_format {
($column->{NOTNULL} = 1) if $column_info->{NULLABLE} == 0;
- if ($column_info->{mysql_is_pri_key}) {
+ if ($column_info->{mariadb_is_pri_key}) {
# In MySQL, if a table has no PK, but it has a UNIQUE index,
# that index will show up as the PK. So we have to eliminate
if ($type =~ /CHAR$/ || $type eq 'DECIMAL') {
# This is nicely lowercase and has the size/precision appended.
- $type = $column_info->{mysql_type_name};
+ $type = $column_info->{mariadb_type_name};
}
# If we're a tinyint, we could be either a BOOLEAN or an INT1.
# doesn't touch the live DB.
my $ref_sth = $dbh->prepare("SELECT $col_name FROM $table LIMIT 1");
$ref_sth->execute;
- if ($ref_sth->{mysql_is_auto_increment}->[0]) {
+ if ($ref_sth->{mariadb_is_auto_increment}->[0]) {
if ($type eq 'MEDIUMINT') {
$type = 'MEDIUMSERIAL';
}
[% IF param.type == "t" %]
<input type="text" size="80" name="[% param.name FILTER html %]"
id="[% param.name FILTER html %]" value="[% Param(param.name) FILTER html %]">
+ [% ELSIF param.type == "r" %]
+ <input type="text" size="80" name="[% param.name FILTER html %]_readonly"
+ id="[% param.name FILTER html %]_readonly" value="[% Param(param.name) FILTER html %]" disabled>
+ <input type="hidden" name="[% param.name FILTER html %]" value="[% Param(param.name) FILTER html %]"><br>
+ This value is read-only and you can't change it.
[% ELSIF param.type == "p" %]
<input type="password" size="80" name="[% param.name FILTER html %]"
id="[% param.name FILTER html %]" value="[% Param(param.name) FILTER html %]"
_ " only after the data has been converted from existing legacy"
_ " character encodings to UTF-8, using the <kbd>contrib/recode.pl</kbd>"
_ " script</strong>."
- _ " <p>Note that if you turn this parameter from "off" to"
- _ " "on", you must re-run <kbd>checksetup.pl</kbd> immediately"
- _ " afterward.</p>",
+ _ " <p>Note that if you change this parameter you must re-run"
+ _ " <kbd>checksetup.pl</kbd> immediately afterward.</p>",
+
+ utf8_collate =>
+ "The collation to use in database tables. This parameter is"
+ _ " automatically set by checksetup.pl.",
shutdownhtml =>
"If this field is non-empty, then Bugzilla will be completely"