aboutsummaryrefslogtreecommitdiffstats
path: root/lib/arel/algebra/header.rb
blob: 3b8aea3422a3fad34e8f0fff8edf3a5bab2f4298 (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
63
64
65
66
67
module Arel
  class Header
    include Enumerable

    def initialize(attrs = [])
      @attributes = attrs.to_ary
      @names = Hash.new do |h,k|
        h[k] = @attributes.detect { |a| a.named?(k) }
      end
    end

    def each
      to_ary.each { |e| yield e }
      self
    end

    def [](key)
      case key
      when String, Symbol then find_by_name(key)
      when Attribute      then find_by_attribute(key)
      end
    end

    def ==(other)
      to_set == other.to_set
    end

    def union(other)
      new(to_ary | other)
    end

    alias | union

    def to_ary
      @attributes
    end

    def bind(relation)
      Header.new(map { |a| a.bind(relation) })
    end

    # TMP
    def index(i)
      to_ary.index(i)
    end

  private

    def new(attrs)
      self.class.new(attrs)
    end

    def matching(attribute)
      select { |a| !a.is_a?(Value) && a.root == attribute.root }
    end

    def find_by_name(name)
      @names[name.to_sym]
    end

    def find_by_attribute(attr)
      matching(attr).max do |a, b|
        (a.original_attribute / attr) <=> (b.original_attribute / attr)
      end
    end
  end
end