diff options
author | Go MAEDA <maeda@farend.jp> | 2023-04-14 23:50:26 +0000 |
---|---|---|
committer | Go MAEDA <maeda@farend.jp> | 2023-04-14 23:50:26 +0000 |
commit | 404a5b1de03011f65bf172a7f01a7cadbcf3ba9b (patch) | |
tree | 8603c81c807a7d9c3a588e08e491862b873c26fd /app | |
parent | c54070cf18c8b0745ee6a08acb16310a702f6d5c (diff) | |
download | redmine-404a5b1de03011f65bf172a7f01a7cadbcf3ba9b.tar.gz redmine-404a5b1de03011f65bf172a7f01a7cadbcf3ba9b.zip |
"contains any of" operator for text filters to perform OR search of multiple terms (#38435).
Patch by Go MAEDA.
git-svn-id: https://svn.redmine.org/redmine/trunk@22188 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r-- | app/models/issue_query.rb | 8 | ||||
-rw-r--r-- | app/models/query.rb | 18 |
2 files changed, 21 insertions, 5 deletions
diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index 68ce1c104..cd363b5c8 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -791,8 +791,14 @@ class IssueQuery < Query projects = nil end + is_all_words = + case operator + when '~' then true + when '|~', '!~' then false + end + fetcher = Redmine::Search::Fetcher.new( - question, User.current, ['issue'], projects, all_words: (operator != '!~'), attachments: '0' + question, User.current, ['issue'], projects, all_words: is_all_words, attachments: '0' ) ids = fetcher.result_ids.map(&:last) if ids.present? diff --git a/app/models/query.rb b/app/models/query.rb index 289d683f6..10bd23adf 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -306,6 +306,7 @@ class Query < ActiveRecord::Base "t-" => :label_ago, "~" => :label_contains, "!~" => :label_not_contains, + "|~" => :label_contains_any_of, "^" => :label_starts_with, "$" => :label_ends_with, "=p" => :label_any_issues_in_project, @@ -323,9 +324,9 @@ class Query < ActiveRecord::Base :list_subprojects => [ "*", "!*", "=", "!" ], :date => [ "=", ">=", "<=", "><", "<t+", ">t+", "><t+", "t+", "nd", "t", "ld", "nw", "w", "lw", "l2w", "nm", "m", "lm", "y", ">t-", "<t-", "><t-", "t-", "!*", "*" ], :date_past => [ "=", ">=", "<=", "><", ">t-", "<t-", "><t-", "t-", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", "!*", "*" ], - :string => [ "~", "=", "!~", "!", "^", "$", "!*", "*" ], - :text => [ "~", "!~", "^", "$", "!*", "*" ], - :search => [ "~", "!~" ], + :string => [ "~", "|~", "=", "!~", "!", "^", "$", "!*", "*" ], + :text => [ "~", "|~", "!~", "^", "$", "!*", "*" ], + :search => [ "~", "|~", "!~" ], :integer => [ "=", ">=", "<=", "><", "!*", "*" ], :float => [ "=", ">=", "<=", "><", "!*", "*" ], :relation => ["=", "!", "=p", "=!p", "!p", "*o", "!o", "!*", "*"], @@ -1431,6 +1432,8 @@ class Query < ActiveRecord::Base sql = sql_contains("#{db_table}.#{db_field}", value.first) when "!~" sql = sql_contains("#{db_table}.#{db_field}", value.first, :match => false) + when "|~" + sql = sql_contains("#{db_table}.#{db_field}", value.first, :all_words => false) when "^" sql = sql_contains("#{db_table}.#{db_field}", value.first, :starts_with => true) when "$" @@ -1443,6 +1446,12 @@ class Query < ActiveRecord::Base end # Returns a SQL LIKE statement with wildcards + # + # valid options: + # * :match - use NOT LIKE if false + # * :starts_with - use LIKE 'value%' if true + # * :ends_with - use LIKE '%value' if true + # * :all_words - use OR instead of AND if false def sql_contains(db_field, value, options={}) options = {} unless options.is_a?(Hash) options.symbolize_keys! @@ -1465,10 +1474,11 @@ class Query < ActiveRecord::Base def self.tokenized_like_conditions(db_field, value, **options) tokens = Redmine::Search::Tokenizer.new(value).tokens tokens = [value] unless tokens.present? + logical_opr = options.delete(:all_words) == false ? ' OR ' : ' AND ' sql, values = tokens.map do |token| [Redmine::Database.like(db_field, '?', options), "%#{sanitize_sql_like token}%"] end.transpose - [sql.join(" AND "), *values] + [sql.join(logical_opr), *values] end # rubocop:enable Lint/IneffectiveAccessModifier |