aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--History.txt1
-rw-r--r--Manifest.txt2
-rw-r--r--lib/arel/nodes.rb1
-rw-r--r--lib/arel/nodes/node.rb7
-rw-r--r--lib/arel/nodes/not.rb11
-rw-r--r--lib/arel/visitors/to_sql.rb4
-rw-r--r--test/nodes/test_not.rb20
-rw-r--r--test/visitors/test_to_sql.rb5
8 files changed, 51 insertions, 0 deletions
diff --git a/History.txt b/History.txt
index af20f9d635..328fe6ba8b 100644
--- a/History.txt
+++ b/History.txt
@@ -3,6 +3,7 @@
* Bug fixes
* #lock will lock SELECT statements "FOR UPDATE" on mysql
+ * Nodes::Node#not factory method added for creating Nodes::Not nodes
== 2.0.4
diff --git a/Manifest.txt b/Manifest.txt
index 89b6d37c0b..c9cd045b75 100644
--- a/Manifest.txt
+++ b/Manifest.txt
@@ -43,6 +43,7 @@ lib/arel/nodes/matches.rb
lib/arel/nodes/max.rb
lib/arel/nodes/min.rb
lib/arel/nodes/node.rb
+lib/arel/nodes/not.rb
lib/arel/nodes/not_equal.rb
lib/arel/nodes/not_in.rb
lib/arel/nodes/offset.rb
@@ -84,6 +85,7 @@ test/nodes/test_count.rb
test/nodes/test_delete_statement.rb
test/nodes/test_equality.rb
test/nodes/test_insert_statement.rb
+test/nodes/test_not.rb
test/nodes/test_or.rb
test/nodes/test_select_core.rb
test/nodes/test_select_statement.rb
diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb
index 47cbd64eb5..2affd01fa8 100644
--- a/lib/arel/nodes.rb
+++ b/lib/arel/nodes.rb
@@ -6,6 +6,7 @@ require 'arel/nodes/not_equal'
require 'arel/nodes/assignment'
require 'arel/nodes/or'
require 'arel/nodes/and'
+require 'arel/nodes/not'
require 'arel/nodes/greater_than'
require 'arel/nodes/greater_than_or_equal'
require 'arel/nodes/less_than'
diff --git a/lib/arel/nodes/node.rb b/lib/arel/nodes/node.rb
index 43bad19488..841b954db9 100644
--- a/lib/arel/nodes/node.rb
+++ b/lib/arel/nodes/node.rb
@@ -4,6 +4,13 @@ module Arel
# Abstract base class for all AST nodes
class Node
###
+ # Factory method to create a Nodes::Not node that has the recipient of
+ # the caller as a child.
+ def not
+ Nodes::Not.new self
+ end
+
+ ###
# Factory method to create a Nodes::Grouping node that has an Nodes::Or
# node as a child.
def or right
diff --git a/lib/arel/nodes/not.rb b/lib/arel/nodes/not.rb
new file mode 100644
index 0000000000..d463ae9d08
--- /dev/null
+++ b/lib/arel/nodes/not.rb
@@ -0,0 +1,11 @@
+module Arel
+ module Nodes
+ class Not < Arel::Nodes::Node
+ attr_reader :expr
+
+ def initialize expr
+ @expr = expr
+ end
+ end
+ end
+end
diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb
index 528c5f6ced..bbc1eb3105 100644
--- a/lib/arel/visitors/to_sql.rb
+++ b/lib/arel/visitors/to_sql.rb
@@ -191,6 +191,10 @@ module Arel
"ON #{visit o.expr}"
end
+ def visit_Arel_Nodes_Not o
+ "NOT #{visit o.expr}"
+ end
+
def visit_Arel_Table o
if o.table_alias
"#{quote_table_name o.name} #{quote_table_name o.table_alias}"
diff --git a/test/nodes/test_not.rb b/test/nodes/test_not.rb
new file mode 100644
index 0000000000..7dffdea0c8
--- /dev/null
+++ b/test/nodes/test_not.rb
@@ -0,0 +1,20 @@
+require 'helper'
+
+module Arel
+ module Nodes
+ describe 'not' do
+ describe '#not' do
+ it 'makes a NOT node' do
+ attr = Table.new(:users)[:id]
+ left = attr.eq(10)
+ right = attr.eq(11)
+ node = left.or right
+ node.expr.left.must_equal left
+ node.expr.right.must_equal right
+
+ knot = node.or(right).not
+ end
+ end
+ end
+ end
+end
diff --git a/test/visitors/test_to_sql.rb b/test/visitors/test_to_sql.rb
index b84730eeb4..89f3f60de2 100644
--- a/test/visitors/test_to_sql.rb
+++ b/test/visitors/test_to_sql.rb
@@ -33,6 +33,11 @@ module Arel
@visitor.accept 2.14
end
+ it "should visit_Not" do
+ sql = @visitor.accept Nodes::Not.new(Arel.sql("foo"))
+ sql.must_be_like "NOT foo"
+ end
+
it "should visit_Bignum" do
@visitor.accept 8787878092
end