From 4b2860f18be76bef3c316ecc77de454130a4e581 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Thu, 5 Sep 2013 15:32:11 +0200 Subject: [PATCH] SONAR-4633 When SonarQube doesn't have the required rights to create Oracle triggers, the migration should fail with a meaningful message --- .../core/persistence/DatabaseVersion.java | 2 +- .../org/sonar/core/persistence/rows-h2.sql | 1 + .../main/webapp/WEB-INF/config/environment.rb | 41 ++---- .../db/migrate/410_add_oracle_id_triggers.rb | 99 ++++++------- .../migrate/432_fix_oracle_trigger_names.rb | 132 ++++++++++++++++++ 5 files changed, 192 insertions(+), 83 deletions(-) create mode 100644 sonar-server/src/main/webapp/WEB-INF/db/migrate/432_fix_oracle_trigger_names.rb diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java index 5d526a5b0cf..d43610feba2 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java @@ -33,7 +33,7 @@ import java.util.List; */ public class DatabaseVersion implements BatchComponent, ServerComponent { - public static final int LAST_VERSION = 431; + public static final int LAST_VERSION = 432; public static enum Status { UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql index 3793aea1b2c..09c80a569ee 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql @@ -174,6 +174,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('418'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('419'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('430'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('431'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('432'); INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null); ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2; diff --git a/sonar-server/src/main/webapp/WEB-INF/config/environment.rb b/sonar-server/src/main/webapp/WEB-INF/config/environment.rb index 98b97b52c8e..764e1ed7c80 100644 --- a/sonar-server/src/main/webapp/WEB-INF/config/environment.rb +++ b/sonar-server/src/main/webapp/WEB-INF/config/environment.rb @@ -129,29 +129,22 @@ class ActiveRecord::Migration # SONAR-4178 def self.create_table(table_name, options = {}) + # Oracle constraint (see names of triggers and indices) + raise ArgumentError, "Table name is too long: #{table_name}" if table_name.to_s.length>25 + super(table_name, options) - case dialect() - when "oracle" - create_id_trigger(table_name) unless options[:id] == false - else - # Do nothing - end + create_id_trigger(table_name) if dialect()=='oracle' && options[:id] != false end def drop_table(table_name, options = {}) super(table_name, options) - case dialect() - when "oracle" - drop_id_trigger(table_name) - else - # Do nothing - end + drop_id_trigger(table_name) if dialect()=='oracle' end def self.create_id_trigger(table) execute_ddl("create trigger for table #{table}", - %{CREATE OR REPLACE TRIGGER #{table}_id_trg + %{CREATE OR REPLACE TRIGGER #{table}_idt BEFORE INSERT ON #{table} FOR EACH ROW BEGIN @@ -163,28 +156,18 @@ class ActiveRecord::Migration def self.drop_id_trigger(table) - execute_ddl("drop trigger for table #{table}", + drop_trigger("#{table}_idt") + end - %{DECLARE - e EXCEPTION; - PRAGMA EXCEPTION_INIT(e,-4080); - BEGIN - EXECUTE IMMEDIATE 'DROP TRIGGER #{table}_id_trg'; - EXCEPTION - WHEN e THEN - NULL; - END;}) + def self.drop_trigger(trigger_name) + execute_ddl("drop trigger #{trigger_name}", "DROP TRIGGER #{trigger_name}") end private def self.execute_ddl(message, ddl) - begin - say_with_time(message) do - ActiveRecord::Base.connection.execute(ddl) - end - rescue - # already executed + say_with_time(message) do + ActiveRecord::Base.connection.execute(ddl) end end end diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/410_add_oracle_id_triggers.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/410_add_oracle_id_triggers.rb index 414681bd917..7b2c28bf9c3 100644 --- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/410_add_oracle_id_triggers.rb +++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/410_add_oracle_id_triggers.rb @@ -24,61 +24,54 @@ class AddOracleIdTriggers < ActiveRecord::Migration def self.up - case dialect() - when 'oracle' - upgrade_oracle() - else - # Do nothing + if dialect()=='oracle' + create_id_trigger('action_plans') + create_id_trigger('active_dashboards') + create_id_trigger('active_rule_changes') + create_id_trigger('active_rule_notes') + create_id_trigger('active_rule_param_changes') + create_id_trigger('active_rule_parameters') + create_id_trigger('active_rules') + create_id_trigger('alerts') + create_id_trigger('authors') + create_id_trigger('characteristic_properties') + create_id_trigger('characteristics') + create_id_trigger('dashboards') + create_id_trigger('dependencies') + create_id_trigger('duplications_index') + create_id_trigger('events') + create_id_trigger('graphs') + create_id_trigger('group_roles') + create_id_trigger('groups') + create_id_trigger('issue_changes') + create_id_trigger('issues') + create_id_trigger('loaded_templates') + create_id_trigger('manual_measures') + create_id_trigger('measure_data') + create_id_trigger('measure_filter_favourites') + create_id_trigger('measure_filters') + create_id_trigger('metrics') + create_id_trigger('notifications') + create_id_trigger('project_links') + create_id_trigger('project_measures') + create_id_trigger('projects') + create_id_trigger('properties') + create_id_trigger('quality_models') + create_id_trigger('resource_index') + create_id_trigger('rule_notes') + create_id_trigger('rules') + create_id_trigger('rules_parameters') + create_id_trigger('rules_profiles') + create_id_trigger('semaphores') + create_id_trigger('snapshot_data') + create_id_trigger('snapshot_sources') + create_id_trigger('snapshots') + create_id_trigger('user_roles') + create_id_trigger('users') + create_id_trigger('widget_properties') + create_id_trigger('widgets') end end - def self.upgrade_oracle - create_id_trigger('action_plans') - create_id_trigger('active_dashboards') - create_id_trigger('active_rule_changes') - create_id_trigger('active_rule_notes') - create_id_trigger('active_rule_param_changes') - create_id_trigger('active_rule_parameters') - create_id_trigger('active_rules') - create_id_trigger('alerts') - create_id_trigger('authors') - create_id_trigger('characteristic_properties') - create_id_trigger('characteristics') - create_id_trigger('dashboards') - create_id_trigger('dependencies') - create_id_trigger('duplications_index') - create_id_trigger('events') - create_id_trigger('graphs') - create_id_trigger('group_roles') - create_id_trigger('groups') - create_id_trigger('issue_changes') - create_id_trigger('issues') - create_id_trigger('loaded_templates') - create_id_trigger('manual_measures') - create_id_trigger('measure_data') - create_id_trigger('measure_filter_favourites') - create_id_trigger('measure_filters') - create_id_trigger('metrics') - create_id_trigger('notifications') - create_id_trigger('project_links') - create_id_trigger('project_measures') - create_id_trigger('projects') - create_id_trigger('properties') - create_id_trigger('quality_models') - create_id_trigger('resource_index') - create_id_trigger('rule_notes') - create_id_trigger('rules') - create_id_trigger('rules_parameters') - create_id_trigger('rules_profiles') - create_id_trigger('semaphores') - create_id_trigger('snapshot_data') - create_id_trigger('snapshot_sources') - create_id_trigger('snapshots') - create_id_trigger('user_roles') - create_id_trigger('users') - create_id_trigger('widget_properties') - create_id_trigger('widgets') - end - end diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/432_fix_oracle_trigger_names.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/432_fix_oracle_trigger_names.rb new file mode 100644 index 00000000000..9c739b287eb --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/432_fix_oracle_trigger_names.rb @@ -0,0 +1,132 @@ +# +# Sonar, entreprise quality control tool. +# Copyright (C) 2008-2013 SonarSource +# mailto:contact AT sonarsource DOT com +# +# SonarQube is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 3 of the License, or (at your option) any later version. +# +# SonarQube is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +# +# Sonar 4.0 +# SONAR-4633 +# +class FixOracleTriggerNames < ActiveRecord::Migration + + def self.up + if dialect()=='oracle' + # sonar 3.7 creates triggers with names longer than max allowed (30 characters) + # Drop them and re-create them with shorter names. + # The triggers active_rule_param_changes_id_trg, characteristic_properties_id_trg and measure_filter_favourites_id_trg + # are not supposed to exist. + drop_trigger_quietly('action_plans_id_trg') + drop_trigger_quietly('active_dashboards_id_trg') + drop_trigger_quietly('active_rule_changes_id_trg') + drop_trigger_quietly('active_rule_notes_id_trg') + drop_trigger_quietly('active_rule_parameters_id_trg') + drop_trigger_quietly('active_rules_id_trg') + drop_trigger_quietly('alerts_id_trg') + drop_trigger_quietly('authors_id_trg') + drop_trigger_quietly('characteristics_id_trg') + drop_trigger_quietly('dashboards_id_trg') + drop_trigger_quietly('dependencies_id_trg') + drop_trigger_quietly('duplications_index_id_trg') + drop_trigger_quietly('events_id_trg') + drop_trigger_quietly('graphs_id_trg') + drop_trigger_quietly('group_roles_id_trg') + drop_trigger_quietly('groups_id_trg') + drop_trigger_quietly('issue_changes_id_trg') + drop_trigger_quietly('issues_id_trg') + drop_trigger_quietly('loaded_templates_id_trg') + drop_trigger_quietly('manual_measures_id_trg') + drop_trigger_quietly('measure_data_id_trg') + drop_trigger_quietly('measure_filters_id_trg') + drop_trigger_quietly('metrics_id_trg') + drop_trigger_quietly('notifications_id_trg') + drop_trigger_quietly('project_links_id_trg') + drop_trigger_quietly('project_measures_id_trg') + drop_trigger_quietly('projects_id_trg') + drop_trigger_quietly('properties_id_trg') + drop_trigger_quietly('quality_models_id_trg') + drop_trigger_quietly('resource_index_id_trg') + drop_trigger_quietly('rule_notes_id_trg') + drop_trigger_quietly('rules_id_trg') + drop_trigger_quietly('rules_parameters_id_trg') + drop_trigger_quietly('rules_profiles_id_trg') + drop_trigger_quietly('semaphores_id_trg') + drop_trigger_quietly('snapshot_data_id_trg') + drop_trigger_quietly('snapshot_sources_id_trg') + drop_trigger_quietly('snapshots_id_trg') + drop_trigger_quietly('user_roles_id_trg') + drop_trigger_quietly('users_id_trg') + drop_trigger_quietly('widget_properties_id_trg') + drop_trigger_quietly('widgets_id_trg') + + create_id_trigger('action_plans') + create_id_trigger('active_dashboards') + create_id_trigger('active_rule_changes') + create_id_trigger('active_rule_notes') + create_id_trigger('active_rule_param_changes') + create_id_trigger('active_rule_parameters') + create_id_trigger('active_rules') + create_id_trigger('alerts') + create_id_trigger('authors') + create_id_trigger('characteristic_properties') + create_id_trigger('characteristics') + create_id_trigger('dashboards') + create_id_trigger('dependencies') + create_id_trigger('duplications_index') + create_id_trigger('events') + create_id_trigger('graphs') + create_id_trigger('group_roles') + create_id_trigger('groups') + create_id_trigger('issue_changes') + create_id_trigger('issues') + create_id_trigger('loaded_templates') + create_id_trigger('manual_measures') + create_id_trigger('measure_data') + create_id_trigger('measure_filter_favourites') + create_id_trigger('measure_filters') + create_id_trigger('metrics') + create_id_trigger('notifications') + create_id_trigger('project_links') + create_id_trigger('project_measures') + create_id_trigger('projects') + create_id_trigger('properties') + create_id_trigger('quality_models') + create_id_trigger('resource_index') + create_id_trigger('rule_notes') + create_id_trigger('rules') + create_id_trigger('rules_parameters') + create_id_trigger('rules_profiles') + create_id_trigger('semaphores') + create_id_trigger('snapshot_data') + create_id_trigger('snapshot_sources') + create_id_trigger('snapshots') + create_id_trigger('user_roles') + create_id_trigger('users') + create_id_trigger('widget_properties') + create_id_trigger('widgets') + end + end + + def self.drop_trigger_quietly(trigger_name) + begin + drop_trigger(trigger_name) + rescue + # name is too long, trigger does not exist, ... + end + end +end + -- 2.39.5