]> source.dussan.org Git - sonarqube.git/commitdiff
Improve management of indexes and faux models in database migrations
authorSimon Brandhof <simon.brandhof@gmail.com>
Wed, 15 Feb 2012 10:40:59 +0000 (11:40 +0100)
committerSimon Brandhof <simon.brandhof@gmail.com>
Wed, 15 Feb 2012 10:40:59 +0000 (11:40 +0100)
24 files changed:
sonar-server/src/main/webapp/WEB-INF/db/migrate/118_add_snapshots_qualifier_index.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/119_add_measures_sid_metric_index.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/167_add_index_to_measure_data_snapshot.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/190_add_permanent_id_and_switched_off_to_rule_failures.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/200_add_index_to_characteristic_property.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/201_change_false_positive_on_reviews.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/212_move_async_measures.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/214_add_index_on_manual_measures.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/216_set_nullable_rule_name.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/220_update_events_table.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/221_attach_events_to_snapshots.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/231_refactor_rule_measures.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/232_add_rule_columns_to_reviews.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/235_create_loaded_templates.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/236_delete_value_type_from_widget_properties.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/239_delete_duplications_id.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/240_delete_resource_orphans.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/252_add_rule_and_active_rule_notes.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/254_add_metrics_delete_historical_data.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/255_rename_dbcleaner_properties.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/257_add_active_field_on_users.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/258_add_index_on_review_resource_id.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/260_clean_reviews_with_deleted_users_or_resources.rb
sonar-server/src/main/webapp/WEB-INF/db/migrate/README.txt

index 1ee67cf96f131b173a5859e02b5d3ba7a54de7aa..aab8eeffda4224fdd262c37ccb4ed927d5ab1efe 100644 (file)
 class AddSnapshotsQualifierIndex < ActiveRecord::Migration
 
   def self.up
-    add_index :snapshots, :qualifier, :name => 'snapshots_qualifier'
+    begin
+      add_index :snapshots, :qualifier, :name => 'snapshots_qualifier'
+    rescue
+      # already exists
+    end
   end
 
 end
index 6387ea36c7d3f3117efc6b5fb38c86457ffa55c5..cf8d6907908b1cbac6f3737245e6d9bf5e24f2f3 100644 (file)
 class AddMeasuresSidMetricIndex < ActiveRecord::Migration
 
   def self.up
-    add_index :project_measures, [:snapshot_id, :metric_id], :name => 'measures_sid_metric'
+    begin
+      add_index :project_measures, [:snapshot_id, :metric_id], :name => 'measures_sid_metric'
+    rescue
+      # already exists
+    end
   end
 
 end
index 0c858571c9ccd6eacda49e82e02cf421dfa6f314..fc83ebdfcc5fb462153fb76eba27e32319b53919 100644 (file)
 class AddIndexToMeasureDataSnapshot < ActiveRecord::Migration
 
   def self.up
-    add_index :measure_data, :snapshot_id, :name => 'm_data_sid'
+    begin
+      add_index :measure_data, :snapshot_id, :name => 'm_data_sid'
+    rescue
+      # already exists
+    end
   end
 
 end
index 69ce668446a481b6061e48972ffd98709ae023d5..be6f9ff3dd10bf1eb700c1c227b26e4d58eeb3e9 100644 (file)
@@ -26,9 +26,7 @@ class AddPermanentIdAndSwitchedOffToRuleFailures < ActiveRecord::Migration
   def self.up
     add_column 'rule_failures', 'permanent_id', :integer, :null => true
     add_column 'rule_failures', 'switched_off', :boolean, :null => true
-
     add_index 'rule_failures', 'permanent_id', :name => 'rf_permanent_id'
-    RuleFailure.reset_column_information
   end
 
 end
index 6f45c9d9f7118efc2e7efcfb789dc009458f62c1..e2868bd88e73633a298e3fa45ee2038bd1fa353a 100644 (file)
 class AddIndexToCharacteristicProperty < ActiveRecord::Migration
 
   def self.up
-    add_index :characteristic_properties, :characteristic_id, :name => 'characteristic_properties_cid'
+    begin
+      add_index :characteristic_properties, :characteristic_id, :name => 'characteristic_properties_cid'
+    rescue
+      # already exists
+    end
   end
 
 end
index 3bfae85db62c13abc4cb2ae46cc11f661b52e890..5e3a4b686f062231eefa5d2cb7528e961156bfe8 100644 (file)
 #
 class ChangeFalsePositiveOnReviews < ActiveRecord::Migration
 
+  class Review < ActiveRecord::Base
+  end
+
   def self.up
     add_column 'reviews', 'resolution', :string, :limit => 200, :null => true
-    Review.reset_column_information
 
+    Review.reset_column_information
     Review.update_all("status='RESOLVED', resolution='FALSE-POSITIVE'", "review_type='FALSE_POSITIVE'")
     
     remove_column 'reviews', 'review_type'
-    Review.reset_column_information
   end
 
 end
index 17de99f74d6bfdb3e9395e8b5d2dfff49c423df4..dc720113b3d78adb57f2f3ff90c74207f5b733ed 100644 (file)
@@ -30,8 +30,10 @@ class MoveAsyncMeasures < ActiveRecord::Migration
   end
 
   def self.up
+    ProjectMeasure.reset_column_information
     deprecated_measures=ProjectMeasure.find_by_sql("select p1.* from project_measures p1 where p1.snapshot_id is null and p1.measure_date is not null and not exists(select id from project_measures p2 where p2.project_id=p1.project_id and p2.metric_id=p1.metric_id and p2.measure_date is not null and p2.measure_date>p1.measure_date)")
 
+    ManualMeasure.reset_column_information
     say_with_time "Moving #{deprecated_measures.size} measures" do
       deprecated_measures.each do |dm|
         if dm.project_id
index c30fdd264b3d2f8765bb0e61b582fbd258664cb1..22dc78fa47242ab3d69d1be09f5fc1e925edf2e2 100644 (file)
 class AddIndexOnManualMeasures < ActiveRecord::Migration
 
   def self.up
-    add_index('manual_measures', 'resource_id', :name => 'manual_measures_resource_id')
+    begin
+      add_index 'manual_measures', 'resource_id', :name => 'manual_measures_resource_id'
+    rescue
+      # already exists
+    end
   end
 
 end
index f1d7ed79184e32dce7b419df802f30fa9308b346..0bd4490e04968c5d064dd3cd6cd1a66e1fc7f112 100644 (file)
 #
 class SetNullableRuleName < ActiveRecord::Migration
 
+  class Rule < ActiveRecord::Base
+  end
+
   def self.up
     add_column(:rules, :temp_name, :string, :limit => 200, :null => true)
-    Rule.reset_column_information
 
+    Rule.reset_column_information
     Rule.update_all('temp_name=name')
 
     remove_column(:rules, :name)
     rename_column(:rules, :temp_name, :name)
-    Rule.reset_column_information
   end
 
 end
index cc4d1e1b78ba8e0253ccc3b1e6efd74663457740..5b9d623dcf3b0ce829ecf9e17a13b820d6000841 100644 (file)
@@ -27,8 +27,6 @@ class UpdateEventsTable < ActiveRecord::Migration
     remove_column :events, :data
     change_column :events, :name, :string, :limit => 400, :null => true
     change_column :events, :description, :string, :limit => 4000, :null => true
-    
-    Event.reset_column_information
   end
 
 end
index f0926a1a573db54011fb78b6127b31ceef805ab7..ff5f9dcb6451926fbf2ea49fa735eef7ff8ef661 100644 (file)
 # Sonar 2.12
 #
 class AttachEventsToSnapshots < ActiveRecord::Migration
-  
+
+  class Event < ActiveRecord::Base
+  end
+
+
   def self.up
     logger = RAILS_DEFAULT_LOGGER
+    Event.reset_column_information
+
     Event.find(:all, :conditions => "snapshot_id IS NULL").each do |event|
       begin
         next_snapshot = Snapshot.find(:first, :conditions => ["created_at >= ? AND project_id = ?", event.event_date, event.resource_id], :order => :created_at)
index 26a31dac2c98302507c874744a21cd174d624fe8..191953072a4fbf6da5beca124a41cbe4f26bfd7d 100644 (file)
 #
 class RefactorRuleMeasures < ActiveRecord::Migration
 
+  class ProjectMeasure < ActiveRecord::Base
+  end
+
+  class Metric < ActiveRecord::Base
+  end
+
   def self.up
+    Metric.reset_column_information
+    ProjectMeasure.reset_column_information
+
     replace('violations', 0, 'info_violations')
     replace('violations', 1, 'minor_violations')
     replace('violations', 2, 'major_violations')
index 6eb0114da10951e7d62011c15813cab70dc2729c..1dc5d46040ba09c5b209a95b8394599e9bb977fe 100644 (file)
@@ -26,7 +26,6 @@ class AddRuleColumnsToReviews < ActiveRecord::Migration
   def self.up
     add_column 'reviews', 'rule_id', :integer, :null => true
     add_column 'reviews', 'manual_violation', :boolean, :null => true
-    Review.reset_column_information
   end
 
 end
index b4da00171a7f026216fc1ea06a7cb2bf6b30925a..69c6dd45ca41bae0affe0e27e5e4b9b29274ea0c 100644 (file)
 #
 class CreateLoadedTemplates < ActiveRecord::Migration
 
+  class Dashboard < ActiveRecord::Base
+  end
+
+  class LoadedTemplate < ActiveRecord::Base
+  end
+
   def self.up
     create_table 'loaded_templates' do |t|
       t.column 'kee', :string, :null => true, :limit => 200
@@ -30,8 +36,9 @@ class CreateLoadedTemplates < ActiveRecord::Migration
     end
 
     # if this is a migration, then the default dashboard already exists in the DB so it should not be loaded again
-    default_dashboard = Dashboard.find(:first, :conditions => {:name => 'Dashboard', :user_id => nil})
-    if default_dashboard
+    Dashboard.reset_column_information
+    if Dashboard.exists?(:name => 'Dashboard', :user_id => nil)
+      LoadedTemplate.reset_column_information
       LoadedTemplate.create({:template_type => 'DASHBOARD', :kee => 'Dashboard'})
     end
   end
index 64361abfea5d5c2a33589e82aa9e2d97d71c1145..fc6b91ed8c722ac7ba0fc95d1697a9eb3d78a03e 100644 (file)
@@ -25,7 +25,6 @@ class DeleteValueTypeFromWidgetProperties < ActiveRecord::Migration
 
   def self.up
     remove_column('widget_properties', 'value_type')
-    WidgetProperty.reset_column_information()
   end
 
 end
index b7510faa0ae797cf5387d60e8dca8543a9dc6ed3..47b2bd7ff426e96a98580e84abf3b1659a67d957 100644 (file)
@@ -24,9 +24,7 @@
 class DeleteDuplicationsId < ActiveRecord::Migration
 
   def self.up
-    begin
-      remove_column('duplications_index', 'id')
-    end
+    remove_column('duplications_index', 'id')
   end
 
 end
index 5c6d92a1bd4c7ed12543c9682ec331c2b3429754..42a4e89300a3b47805a8402d7957cca3536ef8ab 100644 (file)
 #
 class DeleteResourceOrphans < ActiveRecord::Migration
 
+  class Project < ActiveRecord::Base
+  end
+
   def self.up
+    Project.reset_column_information
     ids=Project.find_by_sql(["select id from projects p where qualifier<>'LIB' and not exists (select * from snapshots s where s.project_id = p.id and s.islast=?)", true])
     say_with_time "Delete #{ids.size} resources" do
       # partition ids because of the Oracle limitation on IN statements
index db934a2d24f973fdf24ed335b3dea8596ac778e9..75ab8d5c467ac2e8a6436dcdfffe4ec4b7e48d80 100644 (file)
@@ -30,8 +30,7 @@ class AddRuleAndActiveRuleNotes < ActiveRecord::Migration
       t.column :user_login,         :string,      :null => true,    :limit => 40
       t.column :data,               :binary,      :null => true
     end
-    add_index :active_rule_notes, :active_rule_id
-    
+    add_index :active_rule_notes, :active_rule_id, :name => 'active_rule_notes_active_rule_id'
     
     create_table :rule_notes do |t|
       t.timestamps
@@ -39,7 +38,7 @@ class AddRuleAndActiveRuleNotes < ActiveRecord::Migration
       t.column :user_login,     :string,      :null => true,    :limit => 40
       t.column :data,           :binary,      :null => true
     end
-    add_index :rule_notes, :rule_id
+    add_index :rule_notes, :rule_id, :name => 'rule_notes_rule_id'
   end
 
 end
index 41d8f665889e6623451e4dc1d0d2609a39152578..7794feae48f6735806268ca008893c6a8e975fed 100644 (file)
@@ -25,7 +25,6 @@ class AddMetricsDeleteHistoricalData < ActiveRecord::Migration
 
   def self.up
     add_column 'metrics', 'delete_historical_data', :boolean, :null => true
-    Metric.reset_column_information
   end
 
 end
index c1b60665f4a2acb428a305b36e960e162235a666..95338bd38f8cd427b13f0dda65a9292c1f5e22d9 100644 (file)
@@ -28,6 +28,7 @@ class RenameDbcleanerProperties < ActiveRecord::Migration
 
 
   def self.up
+    Property.reset_column_information
     rename('sonar.dbcleaner.monthsBeforeKeepingOnlyOneSnapshotByWeek', 'sonar.dbcleaner.weeksBeforeKeepingOnlyOneSnapshotByWeek')
     rename('sonar.dbcleaner.monthsBeforeKeepingOnlyOneSnapshotByMonth', 'sonar.dbcleaner.weeksBeforeKeepingOnlyOneSnapshotByMonth')
     rename('sonar.dbcleaner.monthsBeforeDeletingAllSnapshots', 'sonar.dbcleaner.weeksBeforeDeletingAllSnapshots')
index ddcb1b06d41dc0bbace849b02761ab86d6a99bf5..2a7da8f1afd4bf9fafd360244c5722e21d716a78 100644 (file)
 #
 class AddActiveFieldOnUsers < ActiveRecord::Migration
 
+  class User < ActiveRecord::Base
+  end
+
   def self.up
     add_column 'users', 'active', :boolean, :null => true, :default => true
+
     User.reset_column_information
-    
     User.find(:all).each do |user|
       user.active = true
       user.save
index 40810ba2a7fc370b222f43f0b801b0f6bf5bda89..192777d5a63aa480687d889e8568d670697e9551 100644 (file)
@@ -25,7 +25,7 @@ class AddIndexOnReviewResourceId < ActiveRecord::Migration
 
   def self.up
     begin
-      add_index('reviews', 'resource_id', :name => 'reviews_rid')
+      add_index('reviews', 'resource_id', :name => 'reviews_resource_id')
     rescue
       # already exists
     end
index b73a34f896b289f40ca4d8f3cf30188c03f8edac..68c5fc5b5dd29ceebbdc8ef11d8780f08d309d49 100644 (file)
 #
 class CleanReviewsWithDeletedUsersOrResources < ActiveRecord::Migration
 
+  class Review < ActiveRecord::Base
+  end
+
+  class ReviewComment < ActiveRecord::Base
+  end
+
   def self.up
-    
+    Review.reset_column_information
     Review.find(:all, :include => ['resource', 'assignee', 'user']).each do |review|
       if review.resource_id && !review.resource
         # For http://jira.codehaus.org/browse/SONAR-3223
@@ -45,6 +51,7 @@ class CleanReviewsWithDeletedUsersOrResources < ActiveRecord::Migration
     end
 
     # For http://jira.codehaus.org/browse/SONAR-3102
+    ReviewComment.reset_column_information
     ReviewComment.find(:all, :include => 'user').each do |comment|
       comment.delete if comment.user_id && !comment.user
     end   
index a5a7e8fcd9148f1d86e4e89d54982d2eca82d798..1c3a2d850bbf9aaa7b9badd11e7397eaa195457e 100644 (file)
@@ -10,14 +10,36 @@ HOW TO ADD A MIGRATION
 
 
 
-RECOMMANDATIONS
+RECOMMENDATIONS
 
-* Don't forget that index name limited to 30 characters in Oracle DB.
 * Prefer to add nullable columns to avoid problems during migration.
-* When adding index, do not forget to name the index (so that it is possible later to delete it)
-  + Example: 
-      add_index "action_plans", "project_id", :name => "ap_project_id"
-* When modifying columns in a table, do not forget to reset the column information on the Ruby model if you use it 
-  + Example:
-      add_column 'users', 'active', :boolean, :null => true, :default => true
-      User.reset_column_information
+
+* Always create an index with a name : add_index "action_plans", "project_id", :name => "action_plans_project_id"
+  Note that this name is limited to 30 characters because of Oracle constraint.
+
+* Silently ignore failures when adding an index that has already been created by users. It can occur when the index
+  is not created in the same migration script than the table.
+
+  begin
+    add_index "action_plans", "project_id", :name => "action_plans_project_id"
+  rescue
+    # ignore
+  end
+
+* Use faux models when touching rows (SELECT/INSERT/UPDATE/DELETE). See http://guides.rubyonrails.org/migrations.html#using-models-in-your-migrations
+  for more details.
+
+  class MyMigration < ActiveRecord::Migration
+    # This is the faux model. It only maps columns. No functional methods.
+    class Metric < ActiveRecord::Base
+    end
+
+    def self.up
+      # it’s a good idea to call reset_column_information to refresh the ActiveRecord cache for the model prior to
+      # updating data in the database
+      Metric.reset_column_information
+      Metric.find(:all) do |m|
+        m.save
+      end
+    end
+  end
\ No newline at end of file