diff options
-rw-r--r-- | lib/arel/algebra/attributes/attribute.rb | 8 | ||||
-rw-r--r-- | lib/arel/algebra/predicates.rb | 16 | ||||
-rw-r--r-- | lib/arel/engines/memory/predicates.rb | 12 | ||||
-rw-r--r-- | lib/arel/engines/sql/core_extensions/array.rb | 4 | ||||
-rw-r--r-- | lib/arel/engines/sql/core_extensions/range.rb | 4 | ||||
-rw-r--r-- | lib/arel/engines/sql/predicates.rb | 8 | ||||
-rw-r--r-- | lib/arel/engines/sql/relations/relation.rb | 4 | ||||
-rw-r--r-- | spec/shared/relation_spec.rb | 4 |
8 files changed, 52 insertions, 8 deletions
diff --git a/lib/arel/algebra/attributes/attribute.rb b/lib/arel/algebra/attributes/attribute.rb index afcbdd8301..d9ea588128 100644 --- a/lib/arel/algebra/attributes/attribute.rb +++ b/lib/arel/algebra/attributes/attribute.rb @@ -110,6 +110,10 @@ module Arel Predicates::Match.new(self, regexp) end + def notmatches(regexp) + Predicates::NotMatch.new(self, regexp) + end + def in(array) if array.is_a?(Range) && array.exclude_end? [Predicates::GreaterThanOrEqualTo.new(self, array.begin), Predicates::LessThan.new(self, array.end)] @@ -117,6 +121,10 @@ module Arel Predicates::In.new(self, array) end end + + def notin(array) + Predicates::NotIn.new(self, array) + end end include Predications diff --git a/lib/arel/algebra/predicates.rb b/lib/arel/algebra/predicates.rb index 700cd6afaa..05a1de983d 100644 --- a/lib/arel/algebra/predicates.rb +++ b/lib/arel/algebra/predicates.rb @@ -33,12 +33,14 @@ module Arel end end - class Not < Binary; end - class GreaterThanOrEqualTo < Binary; end - class GreaterThan < Binary; end - class LessThanOrEqualTo < Binary; end - class LessThan < Binary; end - class Match < Binary; end - class In < Binary; end + class Not < Equality; end + class GreaterThanOrEqualTo < Binary; end + class GreaterThan < Binary; end + class LessThanOrEqualTo < Binary; end + class LessThan < Binary; end + class Match < Binary; end + class NotMatch < Binary; end + class In < Binary; end + class NotIn < Binary; end end end diff --git a/lib/arel/engines/memory/predicates.rb b/lib/arel/engines/memory/predicates.rb index f87bf68357..b8642136d8 100644 --- a/lib/arel/engines/memory/predicates.rb +++ b/lib/arel/engines/memory/predicates.rb @@ -10,7 +10,7 @@ module Arel def operator; :== end end - class Not < Binary + class Not < Equality def eval(row) operand1.eval(row) != operand2.eval(row) end @@ -35,9 +35,19 @@ module Arel class Match < Binary def operator; :=~ end end + + class NotMatch < Binary + def operator; :!~ end + end class In < Binary def operator; :include? end end + + class NotIn < Binary + def eval(row) + !(operand1.eval(row).include?(operand2.eval(row))) + end + end end end diff --git a/lib/arel/engines/sql/core_extensions/array.rb b/lib/arel/engines/sql/core_extensions/array.rb index 72f579b7eb..412479dc83 100644 --- a/lib/arel/engines/sql/core_extensions/array.rb +++ b/lib/arel/engines/sql/core_extensions/array.rb @@ -12,6 +12,10 @@ module Arel def inclusion_predicate_sql "IN" end + + def exclusion_predicate_sql + "NOT IN" + end Array.send(:include, self) end diff --git a/lib/arel/engines/sql/core_extensions/range.rb b/lib/arel/engines/sql/core_extensions/range.rb index 46124f8865..b5b1534e48 100644 --- a/lib/arel/engines/sql/core_extensions/range.rb +++ b/lib/arel/engines/sql/core_extensions/range.rb @@ -8,6 +8,10 @@ module Arel def inclusion_predicate_sql "BETWEEN" end + + def exclusion_predicate_sql + "NOT BETWEEN" + end Range.send(:include, self) end diff --git a/lib/arel/engines/sql/predicates.rb b/lib/arel/engines/sql/predicates.rb index e40240eec5..e9a068fb13 100644 --- a/lib/arel/engines/sql/predicates.rb +++ b/lib/arel/engines/sql/predicates.rb @@ -51,9 +51,17 @@ module Arel class Match < Binary def predicate_sql; 'LIKE' end end + + class NotMatch < Binary + def predicate_sql; 'NOT LIKE' end + end class In < Binary def predicate_sql; operand2.inclusion_predicate_sql end end + + class NotIn < Binary + def predicate_sql; operand2.exclusion_predicate_sql end + end end end diff --git a/lib/arel/engines/sql/relations/relation.rb b/lib/arel/engines/sql/relations/relation.rb index f372589af1..fc353fe0c8 100644 --- a/lib/arel/engines/sql/relations/relation.rb +++ b/lib/arel/engines/sql/relations/relation.rb @@ -21,6 +21,10 @@ module Arel def inclusion_predicate_sql "IN" end + + def exclusion_predicate_sql + "NOT IN" + end def primary_key connection_id = engine.connection.object_id diff --git a/spec/shared/relation_spec.rb b/spec/shared/relation_spec.rb index 5f0ae4b46e..06e8fd2027 100644 --- a/spec/shared/relation_spec.rb +++ b/spec/shared/relation_spec.rb @@ -61,12 +61,16 @@ share_examples_for 'A Relation' do end it "finds rows with a matches predicate" + + it "finds rows with a not matches predicate" it "finds rows with an in predicate" do pending set = @expected[1..(@expected.length/2+1)] @relation.all(:id.in => set.map { |r| r.id }).should have_resources(set) end + + it "finds rows with a not in predicate" end describe "#order" do |