From 8da7f321aabe95470944bc23aeed9a06ef6793a5 Mon Sep 17 00:00:00 2001 From: "justdave%bugzilla.org" <> Date: Sun, 15 Apr 2007 06:35:56 +0000 Subject: 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 --- Bugzilla/DB.pm | 44 +++++++++++++++++++++++++++++++++++++++++++- Bugzilla/DB/Schema.pm | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ Bugzilla/DB/Schema/Pg.pm | 15 +++++++++++++++ Bugzilla/Field.pm | 2 +- Bugzilla/Install/DB.pm | 21 +++++++++++++++++++++ 5 files changed, 128 insertions(+), 2 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm index ffa3e96d1..c87ecbdf5 100644 --- a/Bugzilla/DB.pm +++ b/Bugzilla/DB.pm @@ -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 + +=over + +=item B + +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 + +=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 (nothing) + +=back + =back =head2 Schema Information Methods diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm index 15d7dd8b2..44bda1acb 100644 --- a/Bugzilla/DB/Schema.pm +++ b/Bugzilla/DB/Schema.pm @@ -1911,6 +1911,37 @@ sub get_rename_column_ddl { . " has not implemented a method."; } + +sub get_rename_table_sql { + +=item C + +=over + +=item B + +Gets SQL to rename a table in the database. + +=item B + +=over + +=item C<$old_name> - The current name of the table. + +=item C<$new_name> - The new name of the table. + +=back + +=item B: 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 Description: Deletes a table from this Schema object. @@ -2062,6 +2093,23 @@ sub add_table { } } + + +sub rename_table { + +=item C + +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 diff --git a/Bugzilla/DB/Schema/Pg.pm b/Bugzilla/DB/Schema/Pg.pm index 0101a1e43..7a951e2db 100644 --- a/Bugzilla/DB/Schema/Pg.pm +++ b/Bugzilla/DB/Schema/Pg.pm @@ -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; diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm index dd885cd55..9177ae423 100644 --- a/Bugzilla/Field.pm +++ b/Bugzilla/Field.pm @@ -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. diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm index 96bc161ac..f05f1722e 100644 --- a/Bugzilla/Install/DB.pm +++ b/Bugzilla/Install/DB.pm @@ -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__ -- cgit v1.2.3-24-g4f1b