diff --git a/lib/additionals/entity_methods_global.rb b/lib/additionals/entity_methods_global.rb index c512aa13..b1629175 100644 --- a/lib/additionals/entity_methods_global.rb +++ b/lib/additionals/entity_methods_global.rb @@ -60,6 +60,32 @@ module Additionals "JOIN #{::EnabledModule.table_name} ON #{::EnabledModule.table_name}.project_id=#{table_name}.project_id" \ " AND #{::EnabledModule.table_name}.name='#{module_name}'" end + + def like_pattern(value, wildcard = nil) + cleaned_value = sanitize_sql_like value.to_s.strip + return cleaned_value if wildcard.nil? || wildcard == :none + + case wildcard + when :both + "%#{cleaned_value}%" + when :left + "%#{cleaned_value}" + when :right + "#{cleaned_value}%" + else + raise 'unsupported wildcard rule' + end + end + + def like_with_wildcard(columns:, value:, wildcard: :none) + sql = [] + Array(columns).each do |column| + sql << "LOWER(#{column}) LIKE LOWER(:p) ESCAPE :s" + end + + sql_string = sql.join ' OR ' + where sql_string, p: like_pattern(value, wildcard), s: '\\' + end end module InstanceMethods diff --git a/test/unit/entity_method_test.rb b/test/unit/entity_method_test.rb index 580c29d4..5e851618 100644 --- a/test/unit/entity_method_test.rb +++ b/test/unit/entity_method_test.rb @@ -49,4 +49,20 @@ class EntityMethodTest < Additionals::TestCase assert_sorted_equal [1, 2, 3], projects.ids end + + def test_like_pattern + assert_equal 'ss', Wiki.like_pattern(' ss ') + assert_equal 'ss%', Wiki.like_pattern('ss', :right) + assert_equal '%ss', Wiki.like_pattern('ss', :left) + assert_equal '%ss%', Wiki.like_pattern('ss', :both) + assert_equal 'ss', Wiki.like_pattern('ss', :none) + end + + def test_like_with_wildcard + assert_empty Wiki.like_with_wildcard(columns: :start_page, value: 'nothing') + end + + def test_like_with_wildcard_with_empty_value + assert_empty Wiki.like_with_wildcard(columns: :start_page, value: '') + end end