Commit 8da7f321 authored by justdave%bugzilla.org's avatar justdave%bugzilla.org

Bug 373869: Custom field names must be all lowercase or buglist.cgi sorting throws an error

Patch by mkanat and justdave r=LpSolit,mkanat; a=mkanat
parent b3630da1
......@@ -749,7 +749,7 @@ sub bz_rename_column {
if ($old_col_exists) {
my $already_renamed = $self->bz_column_info($table, $new_name);
ThrowCodeError('column_rename_conflict',
ThrowCodeError('db_rename_conflict',
{ old => "$table.$old_name",
new => "$table.$new_name" }) if $already_renamed;
my @statements = $self->_bz_real_schema->get_rename_column_ddl(
......@@ -767,6 +767,23 @@ sub bz_rename_column {
}
}
sub bz_rename_table {
my ($self, $old_name, $new_name) = @_;
my $old_table = $self->bz_table_info($old_name);
return if !$old_table;
my $new = $self->bz_table_info($new_name);
ThrowCodeError('db_rename_conflict', { old => $old_name,
new => $new_name }) if $new;
my @sql = $self->_bz_real_schema->get_rename_table_sql($old_name, $new_name);
print get_text('install_table_rename',
{ old => $old_name, new => $new_name }) . "\n"
if Bugzilla->usage_mode == USAGE_MODE_CMDLINE;
$self->do($_) foreach @sql;
$self->_bz_real_schema->rename_table($old_name, $new_name);
$self->_bz_store_real_schema;
}
#####################################################################
# Schema Information Methods
#####################################################################
......@@ -2155,6 +2172,31 @@ that you want to rename
=back
=item C<bz_rename_table>
=over
=item B<Description>
Renames a table in the database. Does nothing if the table doesn't exist.
Throws an error if the old table exists and there is already a table
with the new name.
=item B<Params>
=over
=item C<$old_name> - The current name of the table.
=item C<$new_name> - What you're renaming the table to.
=back
=item B<Returns> (nothing)
=back
=back
=head2 Schema Information Methods
......
......@@ -1911,6 +1911,37 @@ sub get_rename_column_ddl {
. " has not implemented a method.";
}
sub get_rename_table_sql {
=item C<get_rename_table_sql>
=over
=item B<Description>
Gets SQL to rename a table in the database.
=item B<Params>
=over
=item C<$old_name> - The current name of the table.
=item C<$new_name> - The new name of the table.
=back
=item B<Returns>: An array of SQL statements to rename a table.
=back
=cut
my ($self, $old_name, $new_name) = @_;
return ("ALTER TABLE $old_name RENAME TO $new_name");
}
=item C<delete_table($name)>
Description: Deletes a table from this Schema object.
......@@ -2062,6 +2093,23 @@ sub add_table {
}
}
sub rename_table {
=item C<rename_table>
Renames a table from C<$old_name> to C<$new_name> in this Schema object.
=cut
my ($self, $old_name, $new_name) = @_;
my $table = $self->get_table_abstract($old_name);
$self->delete_table($old_name);
$self->add_table($new_name, $table);
}
sub delete_column {
=item C<delete_column($table, $column)>
......
......@@ -92,6 +92,11 @@ sub _initialize {
sub get_rename_column_ddl {
my ($self, $table, $old_name, $new_name) = @_;
if (lc($old_name) eq lc($new_name)) {
# if the only change is a case change, return an empty list, since Pg
# is case-insensitive and will return an error about a duplicate name
return ();
}
my @sql = ("ALTER TABLE $table RENAME COLUMN $old_name TO $new_name");
my $def = $self->get_column_abstract($table, $old_name);
if ($def->{TYPE} =~ /SERIAL/i) {
......@@ -104,6 +109,16 @@ sub get_rename_column_ddl {
return @sql;
}
sub get_rename_table_sql {
my ($self, $old_name, $new_name) = @_;
if (lc($old_name) eq lc($new_name)) {
# if the only change is a case change, return an empty list, since Pg
# is case-insensitive and will return an error about a duplicate name
return ();
}
return ("ALTER TABLE $old_name RENAME TO $new_name");
}
sub _get_alter_type_sql {
my ($self, $table, $column, $new_def, $old_def) = @_;
my @statements;
......
......@@ -208,7 +208,7 @@ sub _check_mailhead { return $_[1] ? 1 : 0; }
sub _check_name {
my ($invocant, $name, $is_custom) = @_;
$name = clean_text($name);
$name = lc(clean_text($name));
$name || ThrowUserError('field_missing_name');
# Don't want to allow a name that might mess up SQL.
......
......@@ -503,6 +503,8 @@ sub update_table_definitions {
$dbh->bz_add_column('milestones', 'id',
{TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1});
_fix_uppercase_custom_field_names();
################################################################
# New --TABLE-- changes should go *** A B O V E *** this point #
################################################################
......@@ -2732,6 +2734,25 @@ sub _update_longdescs_who_index {
}
}
sub _fix_uppercase_custom_field_names {
# Before the final release of 3.0, custom fields could be
# created with mixed-case names.
my $dbh = Bugzilla->dbh;
my $fields = $dbh->selectall_arrayref(
'SELECT name, type FROM fielddefs WHERE custom = 1');
foreach my $row (@$fields) {
my ($name, $type) = @$row;
if ($name ne lc($name)) {
$dbh->bz_rename_column('bugs', $name, lc($name));
$dbh->bz_rename_table($name, lc($name))
if $type == FIELD_TYPE_SINGLE_SELECT;
$dbh->do('UPDATE fielddefs SET name = ? WHERE name = ?',
undef, lc($name), $name);
}
}
}
1;
__END__
......
......@@ -118,7 +118,7 @@
without specifying a default or something for $set_nulls_to, because
there are NULL values currently in it.
[% ELSIF error == "column_rename_conflict" %]
[% ELSIF error == "db_rename_conflict" %]
Name conflict: Cannot rename [% old FILTER html %] to
[% new FILTER html %] because [% new FILTER html %] already exists.
......
......@@ -394,6 +394,9 @@
[% ELSIF message_tag == "install_table_drop" %]
Dropping the '[% name FILTER html %]' table...
[% ELSIF message_tag == "install_table_rename" %]
Renaming the '[% old FILTER html %]' table to '[% new FILTER html %]'...
[% ELSIF message_tag == "install_urlbase_default" %]
Now that you have installed [% terms.Bugzilla %], you should visit the
'Parameters' page (linked in the footer of the Administrator
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment