Skip to content

Commit

Permalink
Grouped predicates.
Browse files Browse the repository at this point in the history
Attributes get _any- and _all-suffixed methods to compare an attribute against multiple criteria at once, joining by OR and AND, respectively
  • Loading branch information
Ernie Miller committed Mar 26, 2010
1 parent 66824e5 commit 8387f6f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 37 deletions.
74 changes: 37 additions & 37 deletions lib/arel/algebra/attributes/attribute.rb
Expand Up @@ -22,6 +22,29 @@ def aggregation?
def inspect
"<Attribute #{name}>"
end

def self.predication(name, klass)
methods = {
:operator => "
def #{name}(other)
Predicates::#{klass}.new(self, other)
end
",
:any => "
def #{name}_any(*others)
Predicates::Any.new(Predicates::#{klass}, self, *others)
end
",
:all => "
def #{name}_all(*others)
Predicates::All.new(Predicates::#{klass}, self, *others)
end
"
}
[:operator, :any, :all].each do |method_name|
class_eval methods[method_name], __FILE__, __LINE__
end
end

module Transformations
def self.included(klass)
Expand Down Expand Up @@ -82,44 +105,21 @@ def /(other)
include Congruence

module Predications
def eq(other)
Predicates::Equality.new(self, other)
end

def not(other)
Predicates::Not.new(self, other)
end

def lt(other)
Predicates::LessThan.new(self, other)
end

def lteq(other)
Predicates::LessThanOrEqualTo.new(self, other)
end

def gt(other)
Predicates::GreaterThan.new(self, other)
end

def gteq(other)
Predicates::GreaterThanOrEqualTo.new(self, other)
end

def matches(regexp)
Predicates::Match.new(self, regexp)
end

def notmatches(regexp)
Predicates::NotMatch.new(self, regexp)
end

def in(array)
Predicates::In.new(self, array)
end
methods = {
:eq => "Equality",
:not => "Not",
:lt => "LessThan",
:lteq => "LessThanOrEqualTo",
:gt => "GreaterThan",
:gteq => "GreaterThanOrEqualTo",
:matches => "Match",
:notmatches => "NotMatch",
:in => "In",
:notin => "NotIn"
}

def notin(array)
Predicates::NotIn.new(self, array)
methods.each_pair do |method_name, class_name|
Attribute.predication(method_name, class_name)
end
end
include Predications
Expand Down
10 changes: 10 additions & 0 deletions lib/arel/algebra/predicates.rb
Expand Up @@ -9,6 +9,16 @@ def and(other_predicate)
And.new(self, other_predicate)
end
end

class Grouped < Predicate
attr_reader :operator, :operand1, :operands2

def initialize(operator, operand1, *operands2)
@operator = operator
@operand1 = operand1
@operands2 = operands2
end
end

class Binary < Predicate
attributes :operand1, :operand2
Expand Down
16 changes: 16 additions & 0 deletions lib/arel/engines/sql/predicates.rb
Expand Up @@ -19,6 +19,22 @@ def predicate_sql; "OR" end
class And < CompoundPredicate
def predicate_sql; "AND" end
end

class GroupedPredicate < Grouped
def to_sql(formatter = nil)
"(" + operands2.inject([]) do |predicates, operand|
predicates << operator.new(operand1, operand).to_sql
end.join(" #{predicate_sql} ") + ")"
end
end

class Any < GroupedPredicate
def predicate_sql; "OR" end
end

class All < GroupedPredicate
def predicate_sql; "AND" end
end

class Equality < Binary
def predicate_sql
Expand Down

0 comments on commit 8387f6f

Please sign in to comment.