diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/arel/attributes/attribute.rb | 133 | ||||
-rw-r--r-- | lib/arel/nodes.rb | 3 | ||||
-rw-r--r-- | lib/arel/nodes/does_not_match.rb | 6 | ||||
-rw-r--r-- | lib/arel/nodes/matches.rb | 6 | ||||
-rw-r--r-- | lib/arel/nodes/not_in.rb | 6 | ||||
-rw-r--r-- | lib/arel/visitors/postgresql.rb | 8 | ||||
-rw-r--r-- | lib/arel/visitors/to_sql.rb | 14 |
7 files changed, 176 insertions, 0 deletions
diff --git a/lib/arel/attributes/attribute.rb b/lib/arel/attributes/attribute.rb index e1f7fd81d2..25ffe717b2 100644 --- a/lib/arel/attributes/attribute.rb +++ b/lib/arel/attributes/attribute.rb @@ -7,10 +7,26 @@ module Arel Nodes::NotEqual.new self, other end + def not_eq_any others + grouping_any :not_eq, others + end + + def not_eq_all others + grouping_all :not_eq, others + end + def eq other Nodes::Equality.new self, other end + def eq_any others + grouping_any :eq, others + end + + def eq_all others + grouping_all :eq, others + end + def in other case other when Arel::SelectManager @@ -28,13 +44,130 @@ module Arel end end + def in_any others + grouping_any :in, others + end + + def in_all others + grouping_all :in, others + end + + def not_in other + case other + when Arel::SelectManager + Nodes::NotIn.new self, other.to_a.map { |x| x.id } + when Range + if other.exclude_end? + left = Nodes::LessThan.new(self, other.min) + right = Nodes::GreaterThanOrEqual.new(self, other.max) + Nodes::Or.new left, right + else + left = Nodes::LessThan.new(self, other.min) + right = Nodes::GreaterThan.new(self, other.max) + Nodes::Or.new left, right + end + else + Nodes::NotIn.new self, other + end + end + + def not_in_any others + grouping_any :not_in, others + end + + def not_in_all others + grouping_all :not_in, others + end + + def matches other + Nodes::Matches.new self, other + end + + def matches_any others + grouping_any :matches, others + end + + def matches_all others + grouping_all :matches, others + end + + def does_not_match other + Nodes::DoesNotMatch.new self, other + end + + def does_not_match_any others + grouping_any :does_not_match, others + end + + def does_not_match_all others + grouping_all :does_not_match, others + end + def gteq right Nodes::GreaterThanOrEqual.new self, right end + def gteq_any others + grouping_any :gteq, others + end + + def gteq_all others + grouping_all :gteq, others + end + def gt right Nodes::GreaterThan.new self, right end + + def gt_any others + grouping_any :gt, others + end + + def gt_all others + grouping_all :gt, others + end + + def lt right + Nodes::LessThan.new self, right + end + + def lt_any others + grouping_any :lt, others + end + + def lt_all others + grouping_all :lt, others + end + + def lteq right + Nodes::LessThanOrEqual.new self, right + end + + def lteq_any others + grouping_any :lteq, others + end + + def lteq_all others + grouping_all :lteq, others + end + + private + + def grouping_any method_id, others + first = send method_id, others.shift + + Nodes::Grouping.new others.inject(first) { |memo,expr| + Nodes::Or.new(memo, send(method_id, expr)) + } + end + + def grouping_all method_id, others + first = send method_id, others.shift + + Nodes::Grouping.new others.inject(first) { |memo,expr| + Nodes::And.new(memo, send(method_id, expr)) + } + end end class String < Attribute; end diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb index 6ed05fb31b..0063ed1cd5 100644 --- a/lib/arel/nodes.rb +++ b/lib/arel/nodes.rb @@ -10,8 +10,11 @@ require 'arel/nodes/greater_than' require 'arel/nodes/greater_than_or_equal' require 'arel/nodes/less_than' require 'arel/nodes/less_than_or_equal' +require 'arel/nodes/matches' +require 'arel/nodes/does_not_match' require 'arel/nodes/in' +require 'arel/nodes/not_in' require 'arel/nodes/lock' require 'arel/nodes/function' require 'arel/nodes/count' diff --git a/lib/arel/nodes/does_not_match.rb b/lib/arel/nodes/does_not_match.rb new file mode 100644 index 0000000000..b5693df711 --- /dev/null +++ b/lib/arel/nodes/does_not_match.rb @@ -0,0 +1,6 @@ +module Arel + module Nodes + class DoesNotMatch < Binary + end + end +end diff --git a/lib/arel/nodes/matches.rb b/lib/arel/nodes/matches.rb new file mode 100644 index 0000000000..4b9fd34ad1 --- /dev/null +++ b/lib/arel/nodes/matches.rb @@ -0,0 +1,6 @@ +module Arel + module Nodes + class Matches < Binary + end + end +end diff --git a/lib/arel/nodes/not_in.rb b/lib/arel/nodes/not_in.rb new file mode 100644 index 0000000000..6cb2c6f832 --- /dev/null +++ b/lib/arel/nodes/not_in.rb @@ -0,0 +1,6 @@ +module Arel + module Nodes + class NotIn < Binary + end + end +end diff --git a/lib/arel/visitors/postgresql.rb b/lib/arel/visitors/postgresql.rb index 87fc3bd60d..5e03f40984 100644 --- a/lib/arel/visitors/postgresql.rb +++ b/lib/arel/visitors/postgresql.rb @@ -21,6 +21,14 @@ module Arel end end + def visit_Arel_Nodes_Matches o + "#{visit o.left} ILIKE #{visit o.right}" + end + + def visit_Arel_Nodes_DoesNotMatch o + "#{visit o.left} NOT ILIKE #{visit o.right}" + end + def using_distinct_on?(o) o.cores.any? do |core| core.projections.any? do |projection| diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index fc821a0ddb..7f9186d28c 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -161,6 +161,14 @@ module Arel "#{visit o.left} < #{visit o.right}" end + def visit_Arel_Nodes_Matches o + "#{visit o.left} LIKE #{visit o.right}" + end + + def visit_Arel_Nodes_DoesNotMatch o + "#{visit o.left} NOT LIKE #{visit o.right}" + end + def visit_Arel_Nodes_StringJoin o "#{visit o.left} #{visit o.right}" end @@ -191,6 +199,12 @@ module Arel "#{visit o.left} IN (#{right})" end + def visit_Arel_Nodes_NotIn o + right = o.right + right = right.empty? ? 'NULL' : right.map { |x| visit x }.join(', ') + "#{visit o.left} NOT IN (#{right})" + end + def visit_Arel_Nodes_And o "#{visit o.left} AND #{visit o.right}" end |