aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorErnie Miller <ernie@metautonomo.us>2010-03-30 15:32:39 -0400
committerErnie Miller <ernie@metautonomo.us>2010-05-07 13:07:21 -0400
commit0433b054eebd5a53ff6c5f35383a6c0aed0015b2 (patch)
treeed07230cd0f1e033138f89e103bb2ce4cb6d6f7a /lib
parent0afcfa27c9f386ca7c190cd1f66db1cdd9971f3b (diff)
downloadrails-0433b054eebd5a53ff6c5f35383a6c0aed0015b2.tar.gz
rails-0433b054eebd5a53ff6c5f35383a6c0aed0015b2.tar.bz2
rails-0433b054eebd5a53ff6c5f35383a6c0aed0015b2.zip
Tests for notmatches and notin, and fixes for issues found in tests
Diffstat (limited to 'lib')
-rw-r--r--lib/arel/algebra/predicates.rb23
-rw-r--r--lib/arel/engines/memory/predicates.rb53
-rw-r--r--lib/arel/engines/sql/predicates.rb6
3 files changed, 71 insertions, 11 deletions
diff --git a/lib/arel/algebra/predicates.rb b/lib/arel/algebra/predicates.rb
index 43606139b0..be80f2a987 100644
--- a/lib/arel/algebra/predicates.rb
+++ b/lib/arel/algebra/predicates.rb
@@ -14,19 +14,28 @@ module Arel
end
end
- class Grouped < Predicate
- attributes :operator, :operand1, :operands2
+ class Polyadic < Predicate
+ attributes :operator, :operand1, :additional_operands
- def initialize(operator, operand1, *operands2)
+ def initialize(operator, operand1, *additional_operands)
@operator = operator
@operand1 = operand1
- @operands2 = operands2.uniq
+ @additional_operands = additional_operands.uniq
end
def ==(other)
self.class === other and
+ @operator == operator and
@operand1 == other.operand1 and
- same_elements?(@operands2, other.operands2)
+ same_elements?(@additional_operands, other.additional_operands)
+ end
+
+ def bind(relation)
+ self.class.new(
+ operator,
+ operand1.find_correlate_in(relation),
+ *additional_operands.map {|o| o.find_correlate_in(relation)}
+ )
end
private
@@ -43,6 +52,10 @@ module Arel
class Unary < Predicate
attributes :operand
deriving :initialize, :==
+
+ def bind(relation)
+ self.class.new(operand.find_correlate_in(relation))
+ end
end
class Binary < Predicate
diff --git a/lib/arel/engines/memory/predicates.rb b/lib/arel/engines/memory/predicates.rb
index d0963e2f74..c0ee862626 100644
--- a/lib/arel/engines/memory/predicates.rb
+++ b/lib/arel/engines/memory/predicates.rb
@@ -5,6 +5,49 @@ module Arel
operand1.eval(row).send(operator, operand2.eval(row))
end
end
+
+ class Unary < Predicate
+ def eval(row)
+ operand.eval(row).send(operator)
+ end
+ end
+
+ class Not < Unary
+ def operator; '!' end
+ end
+
+ class CompoundPredicate < Binary
+ def eval(row)
+ eval "operand1.eval(row) #{operator} operand2.eval(row)"
+ end
+ end
+
+ class Or < CompoundPredicate
+ def operator; :or end
+ end
+
+ class And < CompoundPredicate
+ def operator; :and end
+ end
+
+ class GroupedPredicate < Polyadic
+ def eval(row)
+ group = additional_operands.inject([]) do |results, operand|
+ results << operator.new(operand1, operand)
+ end
+ group.send(compounder) do |operation|
+ operation.eval(row)
+ end
+ end
+ end
+
+ class Any < GroupedPredicate
+ def compounder; :any? end
+ end
+
+ class All < GroupedPredicate
+ def compounder; :all? end
+ end
class Equality < Binary
def operator; :== end
@@ -37,16 +80,20 @@ module Arel
end
class NotMatch < Binary
- def operator; :!~ end
+ def eval(row)
+ operand1.eval(row) !~ operand2.eval(row)
+ end
end
class In < Binary
- def operator; :include? end
+ def eval(row)
+ operand2.eval(row).include?(operand1.eval(row))
+ end
end
class NotIn < Binary
def eval(row)
- !(operand1.eval(row).include?(operand2.eval(row)))
+ !(operand2.eval(row).include?(operand1.eval(row)))
end
end
end
diff --git a/lib/arel/engines/sql/predicates.rb b/lib/arel/engines/sql/predicates.rb
index 29bc74c605..b459168620 100644
--- a/lib/arel/engines/sql/predicates.rb
+++ b/lib/arel/engines/sql/predicates.rb
@@ -30,11 +30,11 @@ module Arel
def predicate_sql; "AND" end
end
- class GroupedPredicate < Grouped
+ class GroupedPredicate < Polyadic
def to_sql(formatter = nil)
"(" +
- operands2.inject([]) { |predicates, operand|
- predicates << operator.new(operand1, operand).to_sql
+ additional_operands.inject([]) { |predicates, operand|
+ predicates << operator.new(operand1, operand).to_sql(formatter)
}.join(" #{predicate_sql} ") +
")"
end