From: Jean-Philippe Lang Date: Tue, 8 Dec 2009 20:47:52 +0000 (+0000) Subject: Optimize updates of issue's shared versions. X-Git-Tag: 0.9.0~125 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=0fe389b8417fe9ad17682a39cdd7c183005f5a5e;p=redmine.git Optimize updates of issue's shared versions. git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3137 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- diff --git a/app/models/issue.rb b/app/models/issue.rb index 27029af13..e98369d06 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -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) diff --git a/app/models/project.rb b/app/models/project.rb index 9e2f4830d..e6ec19efb 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -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 diff --git a/app/models/version.rb b/app/models/version.rb index 4ed6a4e9e..bc0e17e22 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -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