@@ -115,7 +115,8 class Query < ActiveRecord::Base | |||
|
115 | 115 | "~" => :label_contains, |
|
116 | 116 | "!~" => :label_not_contains, |
|
117 | 117 | "=p" => :label_any_issues_in_project, |
|
118 |
"=!p" => :label_any_issues_not_in_project |
|
|
118 | "=!p" => :label_any_issues_not_in_project, | |
|
119 | "!p" => :label_no_issues_in_project} | |
|
119 | 120 | |
|
120 | 121 | cattr_reader :operators |
|
121 | 122 | |
@@ -129,7 +130,7 class Query < ActiveRecord::Base | |||
|
129 | 130 | :text => [ "~", "!~", "!*", "*" ], |
|
130 | 131 | :integer => [ "=", ">=", "<=", "><", "!*", "*" ], |
|
131 | 132 | :float => [ "=", ">=", "<=", "><", "!*", "*" ], |
|
132 | :relation => ["=", "=p", "=!p", "!*", "*"]} | |
|
133 | :relation => ["=", "=p", "=!p", "!p", "!*", "*"]} | |
|
133 | 134 | |
|
134 | 135 | cattr_reader :operators_by_filter_type |
|
135 | 136 | |
@@ -807,14 +808,15 class Query < ActiveRecord::Base | |||
|
807 | 808 | when "=", "!" |
|
808 | 809 | op = (operator == "=" ? 'IN' : 'NOT IN') |
|
809 | 810 | "#{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})" |
|
810 | when "=p", "=!p" | |
|
811 |
op = (operator == " |
|
|
812 | "#{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})" | |
|
811 | when "=p", "=!p", "!p" | |
|
812 | op = (operator == "!p" ? 'NOT IN' : 'IN') | |
|
813 | comp = (operator == "=!p" ? '<>' : '=') | |
|
814 | "#{Issue.table_name}.id #{op} (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 #{comp} #{value.first.to_i})" | |
|
813 | 815 | end |
|
814 | 816 | |
|
815 | 817 | if relation_options[:sym] == field && !options[:reverse] |
|
816 | 818 | sqls = [sql, sql_for_relations(field, operator, value, :reverse => true)] |
|
817 | sqls.join(["!", "!*"].include?(operator) ? " AND " : " OR ") | |
|
819 | sqls.join(["!", "!*", "!p"].include?(operator) ? " AND " : " OR ") | |
|
818 | 820 | else |
|
819 | 821 | sql |
|
820 | 822 | end |
@@ -674,6 +674,7 en: | |||
|
674 | 674 | label_not_contains: doesn't contain |
|
675 | 675 | label_any_issues_in_project: any issues in project |
|
676 | 676 | label_any_issues_not_in_project: any issues not in project |
|
677 | label_no_issues_in_project: no issues in project | |
|
677 | 678 | label_day_plural: days |
|
678 | 679 | label_repository: Repository |
|
679 | 680 | label_repository_new: New repository |
@@ -664,6 +664,7 fr: | |||
|
664 | 664 | label_not_contains: ne contient pas |
|
665 | 665 | label_any_issues_in_project: une demande du projet |
|
666 | 666 | label_any_issues_not_in_project: une demande hors du projet |
|
667 | label_no_issues_in_project: aucune demande du projet | |
|
667 | 668 | label_day_plural: jours |
|
668 | 669 | label_repository: Dépôt |
|
669 | 670 | label_repository_new: Nouveau dépôt |
@@ -260,6 +260,7 function toggleOperator(field) { | |||
|
260 | 260 | break; |
|
261 | 261 | case "=p": |
|
262 | 262 | case "=!p": |
|
263 | case "!p": | |
|
263 | 264 | enableValues(field, [1]); |
|
264 | 265 | break; |
|
265 | 266 | default: |
@@ -672,6 +672,22 class QueryTest < ActiveSupport::TestCase | |||
|
672 | 672 | assert_equal [1], find_issues_with_query(query).map(&:id).sort |
|
673 | 673 | end |
|
674 | 674 | |
|
675 | def test_filter_on_relations_with_no_issues_in_a_project | |
|
676 | IssueRelation.delete_all | |
|
677 | with_settings :cross_project_issue_relations => '1' do | |
|
678 | IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first) | |
|
679 | IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(3).issues.first) | |
|
680 | IssueRelation.create!(:relation_type => "relates", :issue_to => Project.find(2).issues.first, :issue_from => Issue.find(3)) | |
|
681 | end | |
|
682 | ||
|
683 | query = Query.new(:name => '_') | |
|
684 | query.filters = {"relates" => {:operator => '!p', :values => ['2']}} | |
|
685 | ids = find_issues_with_query(query).map(&:id).sort | |
|
686 | assert_include 2, ids | |
|
687 | assert_not_include 1, ids | |
|
688 | assert_not_include 3, ids | |
|
689 | end | |
|
690 | ||
|
675 | 691 | def test_filter_on_relations_with_no_issues |
|
676 | 692 | IssueRelation.delete_all |
|
677 | 693 | IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2)) |
General Comments 0
You need to be logged in to leave comments.
Login now