From 508a6783c8f75742ac64e5073b3b211b0c15662a Mon Sep 17 00:00:00 2001 From: Keenan Brock Date: Sat, 5 Dec 2015 18:54:09 -0500 Subject: Add case sensitive match Explicitly declare if this is case sensitive or not most implementation assume case sensitive postgres assumes case insensitive --- lib/arel/nodes/matches.rb | 4 +++- lib/arel/predications.rb | 16 ++++++++-------- lib/arel/visitors/postgresql.rb | 6 ++++-- test/visitors/test_postgres.rb | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/lib/arel/nodes/matches.rb b/lib/arel/nodes/matches.rb index 583fb97c9b..0d9c1925dc 100644 --- a/lib/arel/nodes/matches.rb +++ b/lib/arel/nodes/matches.rb @@ -2,10 +2,12 @@ module Arel module Nodes class Matches < Binary attr_reader :escape + attr_accessor :case_sensitive - def initialize(left, right, escape = nil) + def initialize(left, right, escape = nil, case_sensitive = false) super(left, right) @escape = escape && Nodes.build_quoted(escape) + @case_sensitive = case_sensitive end end diff --git a/lib/arel/predications.rb b/lib/arel/predications.rb index b05fc6f99a..ed083f5402 100644 --- a/lib/arel/predications.rb +++ b/lib/arel/predications.rb @@ -118,20 +118,20 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead. grouping_all :not_in, others end - def matches other, escape = nil - Nodes::Matches.new self, quoted_node(other), escape + def matches other, escape = nil, case_sensitive = false + Nodes::Matches.new self, quoted_node(other), escape, case_sensitive end - def matches_any others, escape = nil - grouping_any :matches, others, escape + def matches_any others, escape = nil, case_sensitive = false + grouping_any :matches, others, escape, case_sensitive end - def matches_all others, escape = nil - grouping_all :matches, others, escape + def matches_all others, escape = nil, case_sensitive = false + grouping_all :matches, others, escape, case_sensitive end - def does_not_match other, escape = nil - Nodes::DoesNotMatch.new self, quoted_node(other), escape + def does_not_match other, escape = nil, case_sensitive = false + Nodes::DoesNotMatch.new self, quoted_node(other), escape, case_sensitive end def does_not_match_any others, escape = nil diff --git a/lib/arel/visitors/postgresql.rb b/lib/arel/visitors/postgresql.rb index bd23fc0a47..75d2ad9c93 100644 --- a/lib/arel/visitors/postgresql.rb +++ b/lib/arel/visitors/postgresql.rb @@ -4,7 +4,8 @@ module Arel private def visit_Arel_Nodes_Matches o, collector - collector = infix_value o, collector, ' ILIKE ' + op = o.case_sensitive ? ' LIKE ' : ' ILIKE ' + collector = infix_value o, collector, op if o.escape collector << ' ESCAPE ' visit o.escape, collector @@ -14,7 +15,8 @@ module Arel end def visit_Arel_Nodes_DoesNotMatch o, collector - collector = infix_value o, collector, ' NOT ILIKE ' + op = o.case_sensitive ? ' NOT LIKE ' : ' NOT ILIKE ' + collector = infix_value o, collector, op if o.escape collector << ' ESCAPE ' visit o.escape, collector diff --git a/test/visitors/test_postgres.rb b/test/visitors/test_postgres.rb index d6de216d91..d00aa1c100 100644 --- a/test/visitors/test_postgres.rb +++ b/test/visitors/test_postgres.rb @@ -58,6 +58,13 @@ module Arel } end + it "should know how to visit case sensitive" do + node = @table[:name].matches('foo%', nil, true) + compile(node).must_be_like %{ + "users"."name" LIKE 'foo%' + } + end + it "can handle ESCAPE" do node = @table[:name].matches('foo!%', '!') compile(node).must_be_like %{ @@ -82,6 +89,13 @@ module Arel } end + it "should know how to visit case sensitive" do + node = @table[:name].does_not_match('foo%', nil, true) + compile(node).must_be_like %{ + "users"."name" NOT LIKE 'foo%' + } + end + it "can handle ESCAPE" do node = @table[:name].does_not_match('foo!%', '!') compile(node).must_be_like %{ -- cgit v1.2.3