summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2014-12-14 13:55:52 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2014-12-14 13:55:52 +0000
commit24ea9538225cca7504808883031b37564720b82f (patch)
tree052d06337e59c2e84036ee00d9a8a16c750da3f0 /lib
parent9c685f503430410203b5aadf301e7d710443c299 (diff)
downloadredmine-24ea9538225cca7504808883031b37564720b82f.tar.gz
redmine-24ea9538225cca7504808883031b37564720b82f.zip
Use custom SQL for MySQL to behave like others DBMS: case-insensitive search without ignoring accentuation (#18537).
git-svn-id: http://svn.redmine.org/redmine/trunk@13759 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'lib')
-rw-r--r--lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb40
1 files changed, 27 insertions, 13 deletions
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 37c8b400d..ad1ef122c 100644
--- a/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb
+++ b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb
@@ -86,7 +86,7 @@ module Redmine
columns = searchable_options[:columns]
columns = columns[0..0] if options[:titles_only]
- token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE LOWER(?))"}
+ token_clauses = columns.collect {|column| "(#{search_token_match_statement(column)})"}
if !options[:titles_only] && searchable_options[:search_custom_fields]
searchable_custom_fields = CustomField.where(:type => "#{self.name}CustomField", :searchable => true)
@@ -97,8 +97,9 @@ module Redmine
fields_by_visibility.each do |visibility, fields|
ids = fields.map(&:id).join(',')
sql = "#{table_name}.id IN (SELECT cfs.customized_id FROM #{CustomValue.table_name} cfs" +
- " WHERE cfs.customized_type='#{self.name}' AND cfs.customized_id=#{table_name}.id AND LOWER(cfs.value) LIKE LOWER(?)" +
+ " WHERE cfs.customized_type='#{self.name}' AND cfs.customized_id=#{table_name}.id" +
" AND cfs.custom_field_id IN (#{ids})" +
+ " AND #{search_token_match_statement('cfs.value')}" +
" AND #{visibility})"
token_clauses << sql
end
@@ -108,6 +109,28 @@ module Redmine
tokens_conditions = [sql, * (tokens.collect {|w| "%#{w}%"} * token_clauses.size).sort]
+ search_scope(user, projects).
+ reorder(searchable_options[:date_column] => :desc, :id => :desc).
+ where(tokens_conditions).
+ limit(options[:limit]).
+ uniq.
+ pluck(searchable_options[:date_column], :id)
+ end
+
+ def search_token_match_statement(column, value='?')
+ case connection.adapter_name
+ when /postgresql/i
+ "#{column} ILIKE #{value}"
+ when /mysql/i
+ "LOWER(#{column}) COLLATE utf8_bin LIKE LOWER(#{value})"
+ else
+ "#{column} LIKE #{value}"
+ end
+ end
+ private :search_token_match_statement
+
+ # Returns the search scope for user and projects
+ def search_scope(user, projects)
scope = (searchable_options[:scope] || self)
if scope.is_a? Proc
scope = scope.call
@@ -120,21 +143,12 @@ module Redmine
scope = scope.where(Project.allowed_to_condition(user, permission))
end
- # TODO: use visible scope options instead
if projects
scope = scope.where("#{searchable_options[:project_key]} IN (?)", projects.map(&:id))
end
-
- results = []
- results_count = 0
-
- scope.
- reorder(searchable_options[:date_column] => :desc, :id => :desc).
- where(tokens_conditions).
- limit(options[:limit]).
- uniq.
- pluck(searchable_options[:date_column], :id)
+ scope
end
+ private :search_scope
# Returns search results of given ids
def search_results_from_ids(ids)