git-svn-id: http://svn.redmine.org/redmine/trunk@14476 e93f8b46-1217-0410-a6f0-8f06a7374b81tags/3.2.0
@@ -779,9 +779,9 @@ class Query < ActiveRecord::Base | |||
date = Date.today | |||
sql = date_clause(db_table, db_field, date.beginning_of_year, date.end_of_year, is_custom_filter) | |||
when "~" | |||
sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{self.class.connection.quote_string(value.first.to_s.downcase)}%'" | |||
sql = sql_contains("#{db_table}.#{db_field}", value.first) | |||
when "!~" | |||
sql = "LOWER(#{db_table}.#{db_field}) NOT LIKE '%#{self.class.connection.quote_string(value.first.to_s.downcase)}%'" | |||
sql = sql_contains("#{db_table}.#{db_field}", value.first, false) | |||
else | |||
raise "Unknown query operator #{operator}" | |||
end | |||
@@ -789,6 +789,12 @@ class Query < ActiveRecord::Base | |||
return sql | |||
end | |||
# Returns a SQL LIKE statement with wildcards | |||
def sql_contains(db_field, value, match=true) | |||
value = "'%#{self.class.connection.quote_string(value.to_s)}%'" | |||
Redmine::Database.like(db_field, value, :match => match) | |||
end | |||
# Adds a filter for the given custom field | |||
def add_custom_field_filter(field, assoc=nil) | |||
options = field.format.query_filter_options(field, self) |
@@ -159,15 +159,7 @@ module Redmine | |||
private :search_tokens_condition | |||
def search_token_match_statement(column, value='?') | |||
if Redmine::Database.postgresql? | |||
if Redmine::Database.postgresql_unaccent? | |||
"unaccent(#{column}) ILIKE unaccent(#{value})" | |||
else | |||
"#{column} ILIKE #{value}" | |||
end | |||
else | |||
"#{column} LIKE #{value}" | |||
end | |||
Redmine::Database.like(column, value) | |||
end | |||
private :search_token_match_statement | |||
@@ -44,6 +44,21 @@ module Redmine | |||
end | |||
end | |||
# Returns a SQL statement for case/accent (if possible) insensitive match | |||
def like(left, right, options={}) | |||
neg = (options[:match] == false ? 'NOT ' : '') | |||
if postgresql? | |||
if postgresql_unaccent? | |||
"unaccent(#{left}) #{neg}ILIKE unaccent(#{right})" | |||
else | |||
"#{left} #{neg}ILIKE #{right}" | |||
end | |||
else | |||
"#{left} #{neg}LIKE #{right}" | |||
end | |||
end | |||
# Resets database information | |||
def reset | |||
@postgresql_unaccent = nil |
@@ -592,12 +592,22 @@ class QueryTest < ActiveSupport::TestCase | |||
end | |||
def test_operator_contains | |||
query = IssueQuery.new(:project => Project.find(1), :name => '_') | |||
query.add_filter('subject', '~', ['uNable']) | |||
assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'") | |||
issue = Issue.generate!(:subject => 'AbCdEfG') | |||
query = IssueQuery.new(:name => '_') | |||
query.add_filter('subject', '~', ['cdeF']) | |||
result = find_issues_with_query(query) | |||
assert_include issue, result | |||
result.each {|issue| assert issue.subject.downcase.include?('cdef') } | |||
end | |||
def test_operator_does_not_contain | |||
issue = Issue.generate!(:subject => 'AbCdEfG') | |||
query = IssueQuery.new(:name => '_') | |||
query.add_filter('subject', '!~', ['cdeF']) | |||
result = find_issues_with_query(query) | |||
assert result.empty? | |||
result.each {|issue| assert issue.subject.downcase.include?('unable') } | |||
assert_not_include issue, result | |||
end | |||
def test_range_for_this_week_with_week_starting_on_monday | |||
@@ -625,13 +635,6 @@ class QueryTest < ActiveSupport::TestCase | |||
query.statement | |||
end | |||
def test_operator_does_not_contains | |||
query = IssueQuery.new(:project => Project.find(1), :name => '_') | |||
query.add_filter('subject', '!~', ['uNable']) | |||
assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'") | |||
find_issues_with_query(query) | |||
end | |||
def test_filter_assigned_to_me | |||
user = User.find(2) | |||
group = Group.find(10) |