summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/models/query.rb10
-rw-r--r--lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb10
-rw-r--r--lib/redmine/database.rb15
-rw-r--r--test/unit/query_test.rb27
4 files changed, 39 insertions, 23 deletions
diff --git a/app/models/query.rb b/app/models/query.rb
index b77f76c2e..a232258e0 100644
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -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)
diff --git a/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb
index 96d1c2588..06d5db7de 100644
--- a/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb
+++ b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb
@@ -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
diff --git a/lib/redmine/database.rb b/lib/redmine/database.rb
index 290c78ea4..d8b4b7ccb 100644
--- a/lib/redmine/database.rb
+++ b/lib/redmine/database.rb
@@ -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
diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb
index 1907cd9b3..aa45b5beb 100644
--- a/test/unit/query_test.rb
+++ b/test/unit/query_test.rb
@@ -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)