aboutsummaryrefslogtreecommitdiffstats
path: root/lib/arel/relations/operations/join.rb
blob: acad75c81754d368bbccd74abd9f7fe614944893 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
module Arel
  class Join < Relation
    attr_reader :join_sql, :relation1, :relation2, :predicates
    delegate :engine, :name, :to => :relation1
    hash_on :relation1

    def initialize(join_sql, relation1, relation2 = Nil.new, *predicates)
      @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates
    end
    
    def table_sql(formatter = Sql::TableReference.new(self))
      relation1.externalize.table_sql(formatter)
    end
    
    def joins(environment, formatter = Sql::TableReference.new(environment))
      @joins ||= begin
        this_join = [
          join_sql,
          relation2.externalize.table_sql(formatter),
          ("ON" unless predicates.blank?),
          (ons + relation2.externalize.wheres).collect { |p| p.bind(environment).to_sql(Sql::WhereClause.new(environment)) }.join(' AND ')
        ].compact.join(" ")
        [relation1.joins(environment), this_join, relation2.joins(environment)].compact.join(" ")
      end
    end

    def attributes
      @attributes ||= (relation1.externalize.attributes +
        relation2.externalize.attributes).collect { |a| a.bind(self) }
    end
    
    def wheres
      relation1.externalize.wheres
    end
    
    def ons
      @ons ||= @predicates.collect { |p| p.bind(self) }
    end
    
    # TESTME
    def aggregation?
      relation1.aggregation? or relation2.aggregation?
    end
    
    def join?
      true
    end
    
    def ==(other)
      Join       === other             and
      predicates ==  other.predicates  and
      relation1  ==  other.relation1   and
      relation2  ==  other.relation2
    end
  end
  
  class Relation
    def join?
      false
    end
  end
end