diff options
author | Bryan Helmkamp <bryan@brynary.com> | 2009-05-17 14:49:56 -0400 |
---|---|---|
committer | Bryan Helmkamp <bryan@brynary.com> | 2009-05-17 14:49:56 -0400 |
commit | 3a6e8e5a3f99841691b70b89b0a10f836e6ec071 (patch) | |
tree | 89e59775b729616ca9cb4a4f1f70415af35ce3d7 | |
parent | 892337509b2bd269920dc567bc48c6a28c7222d2 (diff) | |
download | rails-3a6e8e5a3f99841691b70b89b0a10f836e6ec071.tar.gz rails-3a6e8e5a3f99841691b70b89b0a10f836e6ec071.tar.bz2 rails-3a6e8e5a3f99841691b70b89b0a10f836e6ec071.zip |
join sql stuff moved into sql adapter
Conflicts:
lib/arel/algebra/primitives/value.rb
lib/arel/algebra/relations/operations/join.rb
lib/arel/algebra/relations/relation.rb
spec/arel/unit/relations/join_spec.rb
-rw-r--r-- | lib/arel/algebra/primitives/value.rb | 1 | ||||
-rw-r--r-- | lib/arel/algebra/relations/operations/join.rb | 14 | ||||
-rw-r--r-- | lib/arel/algebra/relations/relation.rb | 15 | ||||
-rw-r--r-- | lib/arel/algebra/relations/utilities/compound.rb | 3 | ||||
-rw-r--r-- | lib/arel/engines/sql/primitives.rb | 18 | ||||
-rw-r--r-- | lib/arel/engines/sql/relations/operations/join.rb | 14 | ||||
-rw-r--r-- | spec/arel/unit/relations/join_spec.rb | 12 | ||||
-rw-r--r-- | spec/arel/unit/relations/relation_spec.rb | 4 |
8 files changed, 51 insertions, 30 deletions
diff --git a/lib/arel/algebra/primitives/value.rb b/lib/arel/algebra/primitives/value.rb index 91c4045507..76c82890d0 100644 --- a/lib/arel/algebra/primitives/value.rb +++ b/lib/arel/algebra/primitives/value.rb @@ -2,7 +2,6 @@ module Arel class Value attributes :value, :relation deriving :initialize, :== - delegate :inclusion_predicate_sql, :equality_predicate_sql, :to => :value def bind(relation) Value.new(value, relation) diff --git a/lib/arel/algebra/relations/operations/join.rb b/lib/arel/algebra/relations/operations/join.rb index 8e19254378..695f360b51 100644 --- a/lib/arel/algebra/relations/operations/join.rb +++ b/lib/arel/algebra/relations/operations/join.rb @@ -1,12 +1,12 @@ module Arel class Join < Relation - attributes :join_sql, :relation1, :relation2, :predicates + attributes :relation1, :relation2, :predicates deriving :== delegate :engine, :name, :to => :relation1 hash_on :relation1 - def initialize(join_sql, relation1, relation2 = Nil.instance, *predicates) - @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates + def initialize(relation1, relation2 = Nil.instance, *predicates) + @relation1, @relation2, @predicates = relation1, relation2, predicates end def attributes @@ -33,6 +33,14 @@ module Arel end end + class InnerJoin < Join; end + class OuterJoin < Join; end + class StringJoin < Join + def attributes + relation1.externalize.attributes + end + end + class Relation def join? false diff --git a/lib/arel/algebra/relations/relation.rb b/lib/arel/algebra/relations/relation.rb index 20badaf165..6d76e66638 100644 --- a/lib/arel/algebra/relations/relation.rb +++ b/lib/arel/algebra/relations/relation.rb @@ -32,28 +32,27 @@ module Arel include Enumerable module Operable - def join(other_relation = nil, join_type = "INNER JOIN") + def join(other_relation = nil, join_class = InnerJoin) case other_relation when String - Join.new(other_relation, self) + StringJoin.new(other_relation, self) when Relation - JoinOperation.new(join_type, self, other_relation) + JoinOperation.new(join_class, self, other_relation) else self end end def outer_join(other_relation = nil) - join(other_relation, "LEFT OUTER JOIN") + join(other_relation, OuterJoin) end [:where, :project, :order, :take, :skip, :group].each do |operation_name| - operation = <<-OPERATION + class_eval <<-OPERATION, __FILE__, __LINE__ def #{operation_name}(*arguments, &block) arguments.all?(&:blank?) && !block_given?? self : #{operation_name.to_s.classify}.new(self, *arguments, &block) end OPERATION - class_eval operation, __FILE__, __LINE__ end def alias @@ -75,9 +74,9 @@ module Arel end include Writable - JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do + JoinOperation = Struct.new(:join_class, :relation1, :relation2) do def on(*predicates) - Join.new(join_sql, relation1, relation2, *predicates) + join_class.new(relation1, relation2, *predicates) end end end diff --git a/lib/arel/algebra/relations/utilities/compound.rb b/lib/arel/algebra/relations/utilities/compound.rb index e33b8dbf14..fbff36a868 100644 --- a/lib/arel/algebra/relations/utilities/compound.rb +++ b/lib/arel/algebra/relations/utilities/compound.rb @@ -7,12 +7,11 @@ module Arel :to => :relation [:attributes, :wheres, :groupings, :orders].each do |operation_name| - operation = <<-OPERATION + class_eval <<-OPERATION, __FILE__, __LINE__ def #{operation_name} @#{operation_name} ||= relation.#{operation_name}.collect { |o| o.bind(self) } end OPERATION - class_eval operation, __FILE__, __LINE__ end end end diff --git a/lib/arel/engines/sql/primitives.rb b/lib/arel/engines/sql/primitives.rb index c4968558a2..6f89723afe 100644 --- a/lib/arel/engines/sql/primitives.rb +++ b/lib/arel/engines/sql/primitives.rb @@ -3,7 +3,7 @@ module Arel def column original_relation.column_for(self) end - + def format(object) object.to_sql(Sql::Attribute.new(self)) end @@ -14,6 +14,8 @@ module Arel end class Value + delegate :inclusion_predicate_sql, :equality_predicate_sql, :to => :value + def to_sql(formatter = Sql::WhereCondition.new(relation)) formatter.value value end @@ -22,33 +24,33 @@ module Arel object.to_sql(Sql::Value.new(relation)) end end - + class Expression < Attribute def to_sql(formatter = Sql::SelectClause.new(relation)) formatter.expression self end end - + class Count < Expression def function_sql; 'COUNT' end end - + class Distinct < Expression def function_sql; 'DISTINCT' end end - + class Sum < Expression def function_sql; 'SUM' end end - + class Maximum < Expression def function_sql; 'MAX' end end - + class Minimum < Expression def function_sql; 'MIN' end end - + class Average < Expression def function_sql; 'AVG' end end diff --git a/lib/arel/engines/sql/relations/operations/join.rb b/lib/arel/engines/sql/relations/operations/join.rb index be21119bc9..2f5e23644e 100644 --- a/lib/arel/engines/sql/relations/operations/join.rb +++ b/lib/arel/engines/sql/relations/operations/join.rb @@ -16,4 +16,18 @@ module Arel end end end + + class InnerJoin < Join + def join_sql; "INNER JOIN" end + end + + class OuterJoin < Join + def join_sql; "OUTER JOIN" end + end + + class StringJoin < Join + def joins(_, __ = nil) + relation2 + end + end end
\ No newline at end of file diff --git a/spec/arel/unit/relations/join_spec.rb b/spec/arel/unit/relations/join_spec.rb index fa6bbbe216..0e3e6ef16b 100644 --- a/spec/arel/unit/relations/join_spec.rb +++ b/spec/arel/unit/relations/join_spec.rb @@ -10,20 +10,20 @@ module Arel describe 'hashing' do it 'implements hash equality' do - Join.new("INNER JOIN", @relation1, @relation2, @predicate) \ - .should hash_the_same_as(Join.new("INNER JOIN", @relation1, @relation2, @predicate)) + InnerJoin.new(@relation1, @relation2, @predicate) \ + .should hash_the_same_as(InnerJoin.new(@relation1, @relation2, @predicate)) end end describe '#engine' do it "delegates to a relation's engine" do - Join.new("INNER JOIN", @relation1, @relation2, @predicate).engine.should == @relation1.engine + InnerJoin.new(@relation1, @relation2, @predicate).engine.should == @relation1.engine end end describe '#attributes' do it 'combines the attributes of the two relations' do - join = Join.new("INNER JOIN", @relation1, @relation2, @predicate) + join = InnerJoin.new(@relation1, @relation2, @predicate) join.attributes.should == (@relation1.attributes + @relation2.attributes).collect { |a| a.bind(join) } end @@ -32,7 +32,7 @@ module Arel describe '#to_sql' do describe 'when joining with another relation' do it 'manufactures sql joining the two tables on the predicate' do - sql = Join.new("INNER JOIN", @relation1, @relation2, @predicate).to_sql + sql = InnerJoin.new(@relation1, @relation2, @predicate).to_sql adapter_is :mysql do sql.should be_like(%Q{ @@ -54,7 +54,7 @@ module Arel describe 'when joining with a string' do it "passes the string through to the where clause" do - sql = Join.new("INNER JOIN asdf ON fdsa", @relation1).to_sql + sql = StringJoin.new(@relation1, "INNER JOIN asdf ON fdsa").to_sql adapter_is :mysql do sql.should be_like(%Q{ diff --git a/spec/arel/unit/relations/relation_spec.rb b/spec/arel/unit/relations/relation_spec.rb index 7df10be59c..6a61f39966 100644 --- a/spec/arel/unit/relations/relation_spec.rb +++ b/spec/arel/unit/relations/relation_spec.rb @@ -34,7 +34,7 @@ module Arel describe 'when given a relation' do it "manufactures an inner join operation between those two relations" do @relation.join(@relation).on(@predicate). \ - should == Join.new("INNER JOIN", @relation, @relation, @predicate) + should == InnerJoin.new(@relation, @relation, @predicate) end end @@ -54,7 +54,7 @@ module Arel describe '#outer_join' do it "manufactures a left outer join operation between those two relations" do @relation.outer_join(@relation).on(@predicate). \ - should == Join.new("LEFT OUTER JOIN", @relation, @relation, @predicate) + should == OuterJoin.new(@relation, @relation, @predicate) end end end |