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
|
module ActiveRelation
class Relation
include Sql::Quoting
module Iteration
include Enumerable
def each(&block)
connection.select_all(to_s).each(&block)
end
def first
connection.select_one(to_s)
end
end
include Iteration
module Operations
def join(other)
JoinOperation.new("INNER JOIN", self, other)
end
def outer_join(other)
JoinOperation.new("LEFT OUTER JOIN", self, other)
end
def [](index)
case index
when Symbol
attribute(index)
when ::Range
Range.new(self, index)
end
end
def include?(attribute)
RelationInclusion.new(attribute, self)
end
def select(*predicates)
Selection.new(self, *predicates)
end
def project(*attributes)
Projection.new(self, *attributes)
end
def as(aliaz)
Alias.new(self, aliaz)
end
def order(*attributes)
Order.new(self, *attributes)
end
def rename(attribute, aliaz)
Rename.new(self, attribute => aliaz)
end
def insert(record)
Insertion.new(self, record)
end
def delete
Deletion.new(self)
end
def group(*attributes)
Group.new(self, *attributes)
end
JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do
def on(*predicates)
Join.new(join_sql, relation1, relation2, *predicates)
end
end
end
include Operations
def to_sql(strategy = Sql::Select.new)
strategy.select [
"SELECT #{attributes.collect{ |a| a.to_sql(Sql::Projection.new) }.join(', ')}",
"FROM #{table_sql}",
(joins unless joins.blank?),
("WHERE #{selects.collect{|s| s.to_sql(Sql::Predicate.new)}.join("\n\tAND ")}" unless selects.blank?),
("ORDER BY #{orders.collect(&:to_sql)}" unless orders.blank?),
("GROUP BY #{groupings.collect(&:to_sql)}" unless groupings.blank?),
("LIMIT #{limit.to_sql}" unless limit.blank?),
("OFFSET #{offset.to_sql}" unless offset.blank?)
].compact.join("\n")
end
alias_method :to_s, :to_sql
protected
def connection
ActiveRecord::Base.connection
end
def attributes; [] end
def selects; [] end
def orders; [] end
def inserts; [] end
def groupings; [] end
def joins; nil end
def limit; nil end
def offset; nil end
def alias; nil end
end
end
|