diff options
author | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2011-07-20 17:44:10 +0000 |
---|---|---|
committer | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2011-07-20 17:44:10 +0000 |
commit | 18103cafbc38fdbacb89b218827c1e198cfc0aa5 (patch) | |
tree | 8609b7adf42431074c3e1405704c61c2b46d3913 | |
parent | 5f79a6a19069a538d12509ae66f8811c6bba69fb (diff) | |
download | redmine-18103cafbc38fdbacb89b218827c1e198cfc0aa5.tar.gz redmine-18103cafbc38fdbacb89b218827c1e198cfc0aa5.zip |
Refactor: extract specific filter statements to methods.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@6301 e93f8b46-1217-0410-a6f0-8f06a7374b81
-rw-r--r-- | app/models/query.rb | 121 |
1 files changed, 63 insertions, 58 deletions
diff --git a/app/models/query.rb b/app/models/query.rb index 4ea344b5a..3cb4c4507 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -482,68 +482,16 @@ class Query < ActiveRecord::Base v.push(User.current.logged? ? User.current.id.to_s : "0") if v.delete("me") end - sql = '' if field =~ /^cf_(\d+)$/ # custom field - db_table = CustomValue.table_name - db_field = 'value' - is_custom_filter = true - sql << "#{Issue.table_name}.id IN (SELECT #{Issue.table_name}.id FROM #{Issue.table_name} LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='Issue' AND #{db_table}.customized_id=#{Issue.table_name}.id AND #{db_table}.custom_field_id=#{$1} WHERE " - sql << sql_for_field(field, operator, v, db_table, db_field, true) + ')' - elsif field == 'watcher_id' - db_table = Watcher.table_name - db_field = 'user_id' - sql << "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND " - sql << sql_for_field(field, '=', v, db_table, db_field) + ')' - elsif field == "member_of_group" # named field - if operator == '*' # Any group - groups = Group.all - operator = '=' # Override the operator since we want to find by assigned_to - elsif operator == "!*" - groups = Group.all - operator = '!' # Override the operator since we want to find by assigned_to - else - groups = Group.find_all_by_id(v) - end - groups ||= [] - - members_of_groups = groups.inject([]) {|user_ids, group| - if group && group.user_ids.present? - user_ids << group.user_ids - end - user_ids.flatten.uniq.compact - }.sort.collect(&:to_s) - - sql << '(' + sql_for_field("assigned_to_id", operator, members_of_groups, Issue.table_name, "assigned_to_id", false) + ')' - - elsif field == "assigned_to_role" # named field - if operator == "*" # Any Role - roles = Role.givable - operator = '=' # Override the operator since we want to find by assigned_to - elsif operator == "!*" # No role - roles = Role.givable - operator = '!' # Override the operator since we want to find by assigned_to - else - roles = Role.givable.find_all_by_id(v) - end - roles ||= [] - - members_of_roles = roles.inject([]) {|user_ids, role| - if role && role.members - user_ids << role.members.collect(&:user_id) - end - user_ids.flatten.uniq.compact - }.sort.collect(&:to_s) - - sql << '(' + sql_for_field("assigned_to_id", operator, members_of_roles, Issue.table_name, "assigned_to_id", false) + ')' + filters_clauses << sql_for_custom_field(field, operator, v, $1) + elsif respond_to?("sql_for_#{field}_field") + # specific statement + filters_clauses << send("sql_for_#{field}_field", field, operator, v) else # regular field - db_table = Issue.table_name - db_field = field - sql << '(' + sql_for_field(field, operator, v, db_table, db_field) + ')' + filters_clauses << '(' + sql_for_field(field, operator, v, Issue.table_name, field) + ')' end - filters_clauses << sql - end if filters and valid? filters_clauses << project_statement @@ -614,9 +562,66 @@ class Query < ActiveRecord::Base rescue ::ActiveRecord::StatementInvalid => e raise StatementInvalid.new(e.message) end + + def sql_for_watcher_id_field(field, operator, value) + db_table = Watcher.table_name + "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND " + + sql_for_field(field, '=', value, db_table, 'user_id') + ')' + end + + def sql_for_member_of_group_field(field, operator, value) + if operator == '*' # Any group + groups = Group.all + operator = '=' # Override the operator since we want to find by assigned_to + elsif operator == "!*" + groups = Group.all + operator = '!' # Override the operator since we want to find by assigned_to + else + groups = Group.find_all_by_id(value) + end + groups ||= [] + + members_of_groups = groups.inject([]) {|user_ids, group| + if group && group.user_ids.present? + user_ids << group.user_ids + end + user_ids.flatten.uniq.compact + }.sort.collect(&:to_s) + + '(' + sql_for_field("assigned_to_id", operator, members_of_groups, Issue.table_name, "assigned_to_id", false) + ')' + end + + def sql_for_assigned_to_role_field(field, operator, value) + if operator == "*" # Any Role + roles = Role.givable + operator = '=' # Override the operator since we want to find by assigned_to + elsif operator == "!*" # No role + roles = Role.givable + operator = '!' # Override the operator since we want to find by assigned_to + else + roles = Role.givable.find_all_by_id(value) + end + roles ||= [] - private + members_of_roles = roles.inject([]) {|user_ids, role| + if role && role.members + user_ids << role.members.collect(&:user_id) + end + user_ids.flatten.uniq.compact + }.sort.collect(&:to_s) + + '(' + sql_for_field("assigned_to_id", operator, members_of_roles, Issue.table_name, "assigned_to_id", false) + ')' + end + private + + def sql_for_custom_field(field, operator, value, custom_field_id) + db_table = CustomValue.table_name + db_field = 'value' + "#{Issue.table_name}.id IN (SELECT #{Issue.table_name}.id FROM #{Issue.table_name} LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='Issue' AND #{db_table}.customized_id=#{Issue.table_name}.id AND #{db_table}.custom_field_id=#{custom_field_id} WHERE " + + sql_for_field(field, operator, value, db_table, db_field, true) + ')' + end + # Helper method to generate the WHERE sql for a +field+, +operator+ and a +value+ def sql_for_field(field, operator, value, db_table, db_field, is_custom_filter=false) sql = '' |