git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@10513 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
+65
-8
@@ -113,7 +113,9 @@ class Query < ActiveRecord::Base
|
||||
"<t-" => :label_more_than_ago,
|
||||
"t-" => :label_ago,
|
||||
"~" => :label_contains,
|
||||
"!~" => :label_not_contains }
|
||||
"!~" => :label_not_contains,
|
||||
"=p" => :label_any_issues_in_project,
|
||||
"=!p" => :label_any_issues_not_in_project}
|
||||
|
||||
cattr_reader :operators
|
||||
|
||||
@@ -126,7 +128,8 @@ class Query < ActiveRecord::Base
|
||||
:string => [ "=", "~", "!", "!~", "!*", "*" ],
|
||||
:text => [ "~", "!~", "!*", "*" ],
|
||||
:integer => [ "=", ">=", "<=", "><", "!*", "*" ],
|
||||
:float => [ "=", ">=", "<=", "><", "!*", "*" ] }
|
||||
:float => [ "=", ">=", "<=", "><", "!*", "*" ],
|
||||
:relation => ["=", "=p", "=!p", "!*", "*"]}
|
||||
|
||||
cattr_reader :operators_by_filter_type
|
||||
|
||||
@@ -147,6 +150,7 @@ class Query < ActiveRecord::Base
|
||||
QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours"),
|
||||
QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio", :groupable => true),
|
||||
QueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc'),
|
||||
QueryColumn.new(:relations, :caption => :label_related_issues)
|
||||
]
|
||||
cattr_reader :available_columns
|
||||
|
||||
@@ -233,6 +237,10 @@ class Query < ActiveRecord::Base
|
||||
"estimated_hours" => { :type => :float, :order => 13 },
|
||||
"done_ratio" => { :type => :integer, :order => 14 }}
|
||||
|
||||
IssueRelation::TYPES.each do |relation_type, options|
|
||||
@available_filters[relation_type] = {:type => :relation, :order => @available_filters.size + 100, :label => options[:name]}
|
||||
end
|
||||
|
||||
principals = []
|
||||
if project
|
||||
principals += project.principals.sort
|
||||
@@ -244,7 +252,6 @@ class Query < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
else
|
||||
all_projects = Project.visible.all
|
||||
if all_projects.any?
|
||||
# members of visible projects
|
||||
principals += Principal.member_of(all_projects)
|
||||
@@ -254,10 +261,7 @@ class Query < ActiveRecord::Base
|
||||
if User.current.logged? && User.current.memberships.any?
|
||||
project_values << ["<< #{l(:label_my_projects).downcase} >>", "mine"]
|
||||
end
|
||||
Project.project_tree(all_projects) do |p, level|
|
||||
prefix = (level > 0 ? ('--' * level + ' ') : '')
|
||||
project_values << ["#{prefix}#{p.name}", p.id.to_s]
|
||||
end
|
||||
project_values += all_projects_values
|
||||
@available_filters["project_id"] = { :type => :list, :order => 1, :values => project_values} unless project_values.empty?
|
||||
end
|
||||
end
|
||||
@@ -317,7 +321,7 @@ class Query < ActiveRecord::Base
|
||||
}
|
||||
|
||||
@available_filters.each do |field, options|
|
||||
options[:name] ||= l("field_#{field}".gsub(/_id$/, ''))
|
||||
options[:name] ||= l(options[:label] || "field_#{field}".gsub(/_id$/, ''))
|
||||
end
|
||||
|
||||
@available_filters
|
||||
@@ -332,6 +336,21 @@ class Query < ActiveRecord::Base
|
||||
json
|
||||
end
|
||||
|
||||
def all_projects
|
||||
@all_projects ||= Project.visible.all
|
||||
end
|
||||
|
||||
def all_projects_values
|
||||
return @all_projects_values if @all_projects_values
|
||||
|
||||
values = []
|
||||
Project.project_tree(all_projects) do |p, level|
|
||||
prefix = (level > 0 ? ('--' * level + ' ') : '')
|
||||
values << ["#{prefix}#{p.name}", p.id.to_s]
|
||||
end
|
||||
@all_projects_values = values
|
||||
end
|
||||
|
||||
def add_filter(field, operator, values)
|
||||
# values must be an array
|
||||
return unless values.nil? || values.is_a?(Array)
|
||||
@@ -635,6 +654,9 @@ class Query < ActiveRecord::Base
|
||||
if has_column?(:spent_hours)
|
||||
Issue.load_visible_spent_hours(issues)
|
||||
end
|
||||
if has_column?(:relations)
|
||||
Issue.load_visible_relations(issues)
|
||||
end
|
||||
issues
|
||||
rescue ::ActiveRecord::StatementInvalid => e
|
||||
raise StatementInvalid.new(e.message)
|
||||
@@ -729,6 +751,41 @@ class Query < ActiveRecord::Base
|
||||
"#{Issue.table_name}.is_private #{op} (#{va})"
|
||||
end
|
||||
|
||||
def sql_for_relations(field, operator, value, options={})
|
||||
relation_options = IssueRelation::TYPES[field]
|
||||
return relation_options unless relation_options
|
||||
|
||||
relation_type = field
|
||||
join_column, target_join_column = "issue_from_id", "issue_to_id"
|
||||
if relation_options[:reverse] || options[:reverse]
|
||||
relation_type = relation_options[:reverse] || relation_type
|
||||
join_column, target_join_column = target_join_column, join_column
|
||||
end
|
||||
|
||||
sql = case operator
|
||||
when "*", "!*"
|
||||
op = (operator == "*" ? 'IN' : 'NOT IN')
|
||||
"#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}')"
|
||||
when "=", "!"
|
||||
op = (operator == "=" ? 'IN' : 'NOT IN')
|
||||
"#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = #{value.first.to_i})"
|
||||
when "=p", "=!p"
|
||||
op = (operator == "=p" ? '=' : '<>')
|
||||
"#{Issue.table_name}.id IN (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{op} #{value.first.to_i})"
|
||||
end
|
||||
|
||||
if relation_options[:sym] == field && !options[:reverse]
|
||||
sqls = [sql, sql_for_relations(field, operator, value, :reverse => true)]
|
||||
sqls.join(["!", "!*"].include?(operator) ? " AND " : " OR ")
|
||||
else
|
||||
sql
|
||||
end
|
||||
end
|
||||
|
||||
IssueRelation::TYPES.keys.each do |relation_type|
|
||||
alias_method "sql_for_#{relation_type}_field".to_sym, :sql_for_relations
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sql_for_custom_field(field, operator, value, custom_field_id)
|
||||
|
||||
Reference in New Issue
Block a user