]> source.dussan.org Git - redmine.git/commitdiff
Optimize updates of issue's shared versions.
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Tue, 8 Dec 2009 20:47:52 +0000 (20:47 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Tue, 8 Dec 2009 20:47:52 +0000 (20:47 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3137 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/issue.rb
app/models/project.rb
app/models/version.rb

index 27029af13340f53ff60d334db123e43565916394..e98369d060cff51e3899c78e5caac9e0e9bc4994 100644 (file)
@@ -340,12 +340,31 @@ class Issue < ActiveRecord::Base
     s
   end
 
-  # Update all issues so their versions are not pointing to a
-  # fixed_version that is outside of the issue's project hierarchy.
-  #
-  # OPTIMIZE: does a full table scan of Issues with a fixed_version.
-  def self.update_fixed_versions_from_sharing_change(conditions=nil)
-    Issue.all(:conditions => merge_conditions('fixed_version_id IS NOT NULL', conditions),
+  # Unassigns issues from +version+ if it's no longer shared with issue's project
+  def self.update_versions_from_sharing_change(version)
+    # Update issues assigned to the version
+    update_versions(["#{Issue.table_name}.fixed_version_id = ?", version.id])
+  end
+  
+  # Unassigns issues from versions that are no longer shared
+  # after +project+ was moved
+  def self.update_versions_from_hierarchy_change(project)
+    moved_project_ids = project.self_and_descendants.reload.collect(&:id)
+    # Update issues of the moved projects and issues assigned to a version of a moved project
+    Issue.update_versions(["#{Version.table_name}.project_id IN (?) OR #{Issue.table_name}.project_id IN (?)", moved_project_ids, moved_project_ids])
+  end
+
+  private
+  
+  # Update issues so their versions are not pointing to a
+  # fixed_version that is not shared with the issue's project
+  def self.update_versions(conditions=nil)
+    # Only need to update issues with a fixed_version from
+    # a different project and that is not systemwide shared
+    Issue.all(:conditions => merge_conditions("#{Issue.table_name}.fixed_version_id IS NOT NULL" +
+                                                " AND #{Issue.table_name}.project_id <> #{Version.table_name}.project_id" +
+                                                " AND #{Version.table_name}.sharing <> 'system'",
+                                                conditions),
               :include => [:project, :fixed_version]
               ).each do |issue|
       next if issue.project.nil? || issue.fixed_version.nil?
@@ -357,8 +376,6 @@ class Issue < ActiveRecord::Base
     end
   end
   
-  private
-  
   # Callback on attachment deletion
   def attachment_removed(obj)
     journal = init_journal(User.current)
index 9e2f4830da28f027fdef24e708e2b0c1754b5d4c..e6ec19efb7e7d7782b82a537e499831e8908b782 100644 (file)
@@ -304,7 +304,7 @@ class Project < ActiveRecord::Base
         # move_to_child_of adds the project in last (ie.right) position
         move_to_child_of(p)
       end
-      Issue.update_fixed_versions_from_sharing_change
+      Issue.update_versions_from_hierarchy_change(self)
       true
     else
       # Can not move to the given target
index 4ed6a4e9e6f43686d077808438465fb567ead0bf..bc0e17e22fdd2d8e342ffefe863897d8d5d5da73 100644 (file)
@@ -166,7 +166,7 @@ private
       if VERSION_SHARINGS.index(sharing_was).nil? ||
           VERSION_SHARINGS.index(sharing).nil? ||
           VERSION_SHARINGS.index(sharing_was) > VERSION_SHARINGS.index(sharing)
-        Issue.update_fixed_versions_from_sharing_change ["fixed_version_id = ? AND #{Issue.table_name}.project_id <> ?", id, project_id]
+        Issue.update_versions_from_sharing_change self
       end
     end
   end