From aa5c9a19826c84bbb9c9f75f8d1a4b04b874780c Mon Sep 17 00:00:00 2001 From: Nick Kallen Date: Sun, 16 Mar 2008 16:53:49 -0700 Subject: added support for `attribute IN ...` and `attribute BETWEEN ...` - IN and BETWEEN are chosen depending on the type of the second operand - ranges (1..2), arrays ([1,2,3]), and relations ("SELECT * ...") are all supported --- lib/active_relation/extensions.rb | 1 + lib/active_relation/extensions/array.rb | 4 ++++ lib/active_relation/extensions/range.rb | 9 +++++++++ lib/active_relation/predicates.rb | 14 +++----------- lib/active_relation/primitives/attribute.rb | 4 ++++ lib/active_relation/primitives/value.rb | 2 ++ lib/active_relation/relations/relation.rb | 21 ++++++++++++--------- lib/active_relation/sql.rb | 14 +++++++++----- 8 files changed, 44 insertions(+), 25 deletions(-) create mode 100644 lib/active_relation/extensions/range.rb (limited to 'lib') diff --git a/lib/active_relation/extensions.rb b/lib/active_relation/extensions.rb index 7268a5549b..21d6724004 100644 --- a/lib/active_relation/extensions.rb +++ b/lib/active_relation/extensions.rb @@ -2,3 +2,4 @@ require 'active_relation/extensions/object' require 'active_relation/extensions/class' require 'active_relation/extensions/array' require 'active_relation/extensions/hash' +require 'active_relation/extensions/range' \ No newline at end of file diff --git a/lib/active_relation/extensions/array.rb b/lib/active_relation/extensions/array.rb index c07819d35f..2af5832707 100644 --- a/lib/active_relation/extensions/array.rb +++ b/lib/active_relation/extensions/array.rb @@ -6,4 +6,8 @@ class Array def to_sql(formatter = nil) "(" + collect { |e| e.to_sql(formatter) }.join(', ') + ")" end + + def predicate_sql + "IN" + end end \ No newline at end of file diff --git a/lib/active_relation/extensions/range.rb b/lib/active_relation/extensions/range.rb new file mode 100644 index 0000000000..0218a0ab44 --- /dev/null +++ b/lib/active_relation/extensions/range.rb @@ -0,0 +1,9 @@ +class Range + def to_sql(formatter = nil) + formatter.range self.begin, self.end + end + + def predicate_sql + "BETWEEN" + end +end \ No newline at end of file diff --git a/lib/active_relation/predicates.rb b/lib/active_relation/predicates.rb index 98a966507f..f68ec991c3 100644 --- a/lib/active_relation/predicates.rb +++ b/lib/active_relation/predicates.rb @@ -76,18 +76,10 @@ module ActiveRelation class Match < Binary alias_method :regexp, :operand2 - - def initialize(operand1, regexp) - @operand1, @regexp = operand1, regexp - end end - - class RelationInclusion < Binary - alias_method :relation, :operand2 - + + class In < Binary protected - def predicate_sql - 'IN' - end + delegate :predicate_sql, :to => :operand2 end end \ No newline at end of file diff --git a/lib/active_relation/primitives/attribute.rb b/lib/active_relation/primitives/attribute.rb index 0ddbbb5cd4..ddf5ef5e07 100644 --- a/lib/active_relation/primitives/attribute.rb +++ b/lib/active_relation/primitives/attribute.rb @@ -85,6 +85,10 @@ module ActiveRelation def matches(regexp) Match.new(self, regexp) end + + def in(array) + In.new(self, array) + end end include Predications diff --git a/lib/active_relation/primitives/value.rb b/lib/active_relation/primitives/value.rb index 131610f2e9..aeee89dc3b 100644 --- a/lib/active_relation/primitives/value.rb +++ b/lib/active_relation/primitives/value.rb @@ -2,6 +2,8 @@ module ActiveRelation class Value attr_reader :value, :relation + delegate :predicate_sql, :to => :value + def initialize(value, relation) @value, @relation = value, relation end diff --git a/lib/active_relation/relations/relation.rb b/lib/active_relation/relations/relation.rb index 8c93f948f7..1364911f0c 100644 --- a/lib/active_relation/relations/relation.rb +++ b/lib/active_relation/relations/relation.rb @@ -37,10 +37,6 @@ module ActiveRelation end end - def include?(attribute) - RelationInclusion.new(attribute, self) - end - def select(*predicates) Selection.new(self, *predicates.collect {|p| p.bind(self)}) end @@ -94,13 +90,16 @@ module ActiveRelation end include Operations - def aggregation? - false - end + module Externalizable + def aggregation? + false + end - def alias? - false + def alias? + false + end end + include Externalizable def to_sql(formatter = Sql::SelectStatement.new(engine)) formatter.select [ @@ -116,6 +115,10 @@ module ActiveRelation end alias_method :to_s, :to_sql + def predicate_sql + "IN" + end + def call(connection = engine.connection) connection.select_all(to_sql) end diff --git a/lib/active_relation/sql.rb b/lib/active_relation/sql.rb index 85dd591860..027356d4d7 100644 --- a/lib/active_relation/sql.rb +++ b/lib/active_relation/sql.rb @@ -35,7 +35,11 @@ module ActiveRelation "#{quote_table_name(relation_name)}.#{quote_column_name(attribute_name)}" end - def value(value, column = nil) + def value(value) + value.to_sql(self) + end + + def scalar(value, column = nil) quote(value, column) end @@ -61,10 +65,6 @@ module ActiveRelation @attribute, @engine = attribute, attribute.engine end - def value(value) - value.to_sql(self) - end - def scalar(scalar) quote(scalar, @attribute.column) end @@ -72,6 +72,10 @@ module ActiveRelation def array(array) "(" + array.collect { |e| e.to_sql(self) }.join(', ') + ")" end + + def range(left, right) + "#{left} AND #{right}" + end end class Value < WhereCondition -- cgit v1.2.3