diff options
-rw-r--r-- | Bugzilla/DB.pm | 44 | ||||
-rw-r--r-- | Bugzilla/DB/Schema.pm | 48 | ||||
-rw-r--r-- | Bugzilla/DB/Schema/Pg.pm | 15 | ||||
-rw-r--r-- | Bugzilla/Field.pm | 2 | ||||
-rw-r--r-- | Bugzilla/Install/DB.pm | 21 | ||||
-rw-r--r-- | template/en/default/global/code-error.html.tmpl | 2 | ||||
-rw-r--r-- | template/en/default/global/messages.html.tmpl | 3 |
7 files changed, 132 insertions, 3 deletions
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<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 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<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)> 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__ diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl index ad8c97e42..9cf5fd46e 100644 --- a/template/en/default/global/code-error.html.tmpl +++ b/template/en/default/global/code-error.html.tmpl @@ -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. diff --git a/template/en/default/global/messages.html.tmpl b/template/en/default/global/messages.html.tmpl index 2b14b3876..702bc8bad 100644 --- a/template/en/default/global/messages.html.tmpl +++ b/template/en/default/global/messages.html.tmpl @@ -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 |