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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
module ActiveRelation
class Relation
def session
Session.new
end
module Enumerable
include ::Enumerable
def each(&block)
session.read(self).each(&block)
end
def first
session.read(self).first
end
end
include Enumerable
module Operations
def join(other = nil)
case other
when String
Join.new(other, self)
when Relation
JoinOperation.new("INNER JOIN", self, other)
else
self
end
end
def outer_join(other)
JoinOperation.new("LEFT OUTER JOIN", self, other)
end
def [](index)
case index
when Symbol, String
attribute_for_name(index)
when Attribute, Expression
attribute_for_attribute(index)
end
end
def select(*predicates)
predicates.all?(&:blank?) ? self : Selection.new(self, *predicates)
end
def project(*attributes)
attributes.all?(&:blank?) ? self : Projection.new(self, *attributes)
end
def as(aliaz = nil)
aliaz.blank?? self : Alias.new(self, aliaz)
end
def order(*attributes)
attributes.all?(&:blank?) ? self : Order.new(self, *attributes)
end
def take(taken = nil)
taken.blank?? self : Take.new(self, taken)
end
def skip(skipped = nil)
skipped.blank?? self : Skip.new(self, skipped)
end
def group(*groupings)
groupings.all?(&:blank?) ? self : Grouping.new(self, *groupings)
end
module Writes
def insert(record)
session.create Insertion.new(self, record); self
end
def update(assignments)
session.update Update.new(self, assignments); self
end
def delete
session.delete Deletion.new(self); self
end
end
include Writes
JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do
def on(*predicates)
Join.new(join_sql, relation1, relation2, *predicates)
end
end
end
include Operations
module Externalizable
def aggregation?
false
end
def alias?
false
end
end
include Externalizable
def to_sql(formatter = Sql::SelectStatement.new(engine))
formatter.select [
"SELECT #{attributes.collect { |a| a.to_sql(Sql::SelectClause.new(engine)) }.join(', ')}",
"FROM #{table_sql}",
(joins unless joins.blank? ),
("WHERE #{selects.collect { |s| s.to_sql(Sql::WhereClause.new(engine)) }.join("\n\tAND ")}" unless selects.blank? ),
("ORDER BY #{orders.collect { |o| o.to_sql(Sql::OrderClause.new(engine)) }.join(', ')}" unless orders.blank? ),
("GROUP BY #{groupings.collect(&:to_sql)}" unless groupings.blank? ),
("LIMIT #{taken}" unless taken.blank? ),
("OFFSET #{skipped}" unless skipped.blank? )
].compact.join("\n"), self.alias
end
alias_method :to_s, :to_sql
def inclusion_predicate_sql
"IN"
end
def call(connection = engine.connection)
connection.select_all(to_sql)
end
module AttributeAccessors
def attribute_for_name(name)
attributes.detect { |a| a.alias_or_name.to_s == name.to_s }
end
def attribute_for_attribute(attribute)
attributes.detect { |a| a =~ attribute }
end
end
include AttributeAccessors
def bind(relation)
self
end
def format(object)
object.to_sql(Sql::WhereCondition.new(engine))
end
def attributes; [] end
def selects; [] end
def orders; [] end
def inserts; [] end
def groupings; [] end
def joins; nil end
def taken; nil end
def skipped; nil end
def alias; nil end
end
end
|