aboutsummaryrefslogtreecommitdiffstats
path: root/lib/active_relation/primitives/attribute.rb
blob: 4a10dffbe5ee6baf5643d92e57b73d83fed91995 (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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
module ActiveRelation
  class Attribute
    attr_reader :relation, :name, :alias, :ancestor

    def initialize(relation, name, aliaz = nil, ancestor = nil)
      @relation, @name, @alias, @ancestor = relation, name, aliaz, ancestor
    end
    
    def alias_or_name
      @alias || name
    end

    module Transformations
      def as(aliaz = nil)
        Attribute.new(relation, name, aliaz, self)
      end
    
      def bind(new_relation)
        relation == new_relation ? self : Attribute.new(new_relation, name, @alias, self)
      end

      def qualify
        self.as(qualified_name)
      end
      
      def to_attribute
        self
      end
    end
    include Transformations
    
    def qualified_name
      "#{prefix}.#{name}"
    end

    def ==(other)
      self.class  == other.class     and
      relation    == other.relation  and
      name        == other.name      and
      @alias      == other.alias     and
      ancestor    == other.ancestor
    end
    alias_method :eql?, :==
    
    def =~(other)
      !(history & other.send(:history)).empty?
    end
    
    module Predications
      def equals(other)
        Equality.new(self, other)
      end

      def less_than(other)
        LessThan.new(self, other)
      end

      def less_than_or_equal_to(other)
        LessThanOrEqualTo.new(self, other)
      end

      def greater_than(other)
        GreaterThan.new(self, other)
      end

      def greater_than_or_equal_to(other)
        GreaterThanOrEqualTo.new(self, other)
      end

      def matches(regexp)
        Match.new(self, regexp)
      end
    end
    include Predications
    
    module Expressions
      def count
        Expression.new(self, "COUNT")
      end
      
      def sum
        Expression.new(self, "SUM")
      end
      
      def maximum
        Expression.new(self, "MAX")
      end
      
      def minimum
        Expression.new(self, "MIN")
      end
      
      def average
        Expression.new(self, "AVG")
      end
    end
    include Expressions

    def to_sql(strategy = Sql::Predicate.new)
      strategy.attribute prefix, name, self.alias
    end
    
    def hash
      relation.hash + name.hash
    end
    
    private
    def prefix
      relation.prefix_for(self)
    end
    
    def history
      [self] + (ancestor ? [ancestor, ancestor.send(:history)].flatten : [])
    end
  end
end