mirror of
https://github.com/meineerde/redmine.git
synced 2026-01-31 19:47:14 +00:00
OR search with multiple terms for "starts with" and "ends with" filter operators (#38456).
Patch by Go MAEDA. git-svn-id: https://svn.redmine.org/redmine/trunk@22202 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
141f34f795
commit
0e19e183b1
@ -1452,31 +1452,33 @@ class Query < ActiveRecord::Base
|
||||
# * :starts_with - use LIKE 'value%' if true
|
||||
# * :ends_with - use LIKE '%value' if true
|
||||
# * :all_words - use OR instead of AND if false
|
||||
# (ignored if :starts_with or :ends_with is true)
|
||||
def sql_contains(db_field, value, options={})
|
||||
options = {} unless options.is_a?(Hash)
|
||||
options.symbolize_keys!
|
||||
prefix = suffix = nil
|
||||
prefix = '%' if options[:ends_with]
|
||||
suffix = '%' if options[:starts_with]
|
||||
if prefix || suffix
|
||||
value = queried_class.sanitize_sql_like value
|
||||
queried_class.sanitize_sql_for_conditions(
|
||||
[Redmine::Database.like(db_field, '?', :match => options[:match]), "#{prefix}#{value}#{suffix}"]
|
||||
)
|
||||
else
|
||||
queried_class.sanitize_sql_for_conditions(
|
||||
::Query.tokenized_like_conditions(db_field, value, **options)
|
||||
)
|
||||
end
|
||||
queried_class.sanitize_sql_for_conditions(
|
||||
::Query.tokenized_like_conditions(db_field, value, **options)
|
||||
)
|
||||
end
|
||||
|
||||
# rubocop:disable Lint/IneffectiveAccessModifier
|
||||
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 '
|
||||
|
||||
if options[:starts_with]
|
||||
prefix, suffix = nil, '%'
|
||||
logical_opr = ' OR '
|
||||
elsif options[:ends_with]
|
||||
prefix, suffix = '%', nil
|
||||
logical_opr = ' OR '
|
||||
else
|
||||
prefix = suffix = '%'
|
||||
logical_opr = options[:all_words] == false ? ' OR ' : ' AND '
|
||||
end
|
||||
|
||||
sql, values = tokens.map do |token|
|
||||
[Redmine::Database.like(db_field, '?', options), "%#{sanitize_sql_like token}%"]
|
||||
[Redmine::Database.like(db_field, '?', options), "#{prefix}#{sanitize_sql_like token}#{suffix}"]
|
||||
end.transpose
|
||||
[sql.join(logical_opr), *values]
|
||||
end
|
||||
|
||||
@ -3086,6 +3086,34 @@ class QueryTest < ActiveSupport::TestCase
|
||||
assert_equal 1, query.issue_count
|
||||
end
|
||||
|
||||
def test_sql_contains_should_tokenize_for_starts_with
|
||||
query = IssueQuery.new(
|
||||
:project => nil, :name => '_',
|
||||
:filters => {
|
||||
'subject' => {:operator => '^', :values => ['issue closed']}
|
||||
}
|
||||
)
|
||||
|
||||
assert_equal 4, query.issue_count
|
||||
query.issues.each do |issue|
|
||||
assert_match /^(issue|closed)/i, issue.subject
|
||||
end
|
||||
end
|
||||
|
||||
def test_sql_contains_should_tokenize_for_ends_with
|
||||
query = IssueQuery.new(
|
||||
:project => nil, :name => '_',
|
||||
:filters => {
|
||||
'subject' => {:operator => '$', :values => ['version issue']}
|
||||
}
|
||||
)
|
||||
|
||||
assert_equal 4, query.issue_count
|
||||
query.issues.each do |issue|
|
||||
assert_match /(version|issue)$/i, issue.subject
|
||||
end
|
||||
end
|
||||
|
||||
def test_display_type_should_accept_known_types
|
||||
query = ProjectQuery.new(:name => '_')
|
||||
query.display_type = 'list'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user