Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/sql/pattern.rb')
-rw-r--r--lib/gitlab/sql/pattern.rb28
1 files changed, 16 insertions, 12 deletions
diff --git a/lib/gitlab/sql/pattern.rb b/lib/gitlab/sql/pattern.rb
index ca7ae429986..d13ccde8576 100644
--- a/lib/gitlab/sql/pattern.rb
+++ b/lib/gitlab/sql/pattern.rb
@@ -6,7 +6,7 @@ module Gitlab
extend ActiveSupport::Concern
MIN_CHARS_FOR_PARTIAL_MATCHING = 3
- REGEX_QUOTED_WORD = /(?<=\A| )"[^"]+"(?= |\z)/.freeze
+ REGEX_QUOTED_TERM = /(?<=\A| )"[^"]+"(?= |\z)/.freeze
class_methods do
def fuzzy_search(query, columns, use_minimum_char_limit: true)
@@ -40,12 +40,14 @@ module Gitlab
# lower_exact_match - When set to `true` we'll fall back to using
# `LOWER(column) = query` instead of using `ILIKE`.
def fuzzy_arel_match(column, query, lower_exact_match: false, use_minimum_char_limit: true)
+ return unless query.is_a?(String)
+
query = query.squish
return unless query.present?
arel_column = column.is_a?(Arel::Attributes::Attribute) ? column : arel_table[column]
- words = select_fuzzy_words(query, use_minimum_char_limit: use_minimum_char_limit)
+ words = select_fuzzy_terms(query, use_minimum_char_limit: use_minimum_char_limit)
if words.any?
words.map { |word| arel_column.matches(to_pattern(word, use_minimum_char_limit: use_minimum_char_limit)) }.reduce(:and)
@@ -62,19 +64,21 @@ module Gitlab
end
end
- def select_fuzzy_words(query, use_minimum_char_limit: true)
- quoted_words = query.scan(REGEX_QUOTED_WORD)
-
- query = quoted_words.reduce(query) { |q, quoted_word| q.sub(quoted_word, '') }
-
- words = query.split
-
- quoted_words.map! { |quoted_word| quoted_word[1..-2] }
+ def select_fuzzy_terms(query, use_minimum_char_limit: true)
+ terms = Gitlab::SQL::Pattern.split_query_to_search_terms(query)
+ terms.select { |term| partial_matching?(term, use_minimum_char_limit: use_minimum_char_limit) }
+ end
+ end
- words.concat(quoted_words)
+ def self.split_query_to_search_terms(query)
+ quoted_terms = []
- words.select { |word| partial_matching?(word, use_minimum_char_limit: use_minimum_char_limit) }
+ query = query.gsub(REGEX_QUOTED_TERM) do |quoted_term|
+ quoted_terms << quoted_term
+ ""
end
+
+ query.split + quoted_terms.map { |quoted_term| quoted_term[1..-2] }
end
end
end