square-arel 2.0.9.20110222133018
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +26 -0
- data/History.txt +105 -0
- data/MIT-LICENSE.txt +20 -0
- data/Manifest.txt +124 -0
- data/README.markdown +94 -0
- data/Rakefile +20 -0
- data/lib/arel.rb +39 -0
- data/lib/arel/attributes.rb +20 -0
- data/lib/arel/attributes/attribute.rb +18 -0
- data/lib/arel/compatibility/wheres.rb +33 -0
- data/lib/arel/crud.rb +37 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/deprecated.rb +4 -0
- data/lib/arel/expression.rb +4 -0
- data/lib/arel/expressions.rb +23 -0
- data/lib/arel/insert_manager.rb +34 -0
- data/lib/arel/nodes.rb +53 -0
- data/lib/arel/nodes/and.rb +6 -0
- data/lib/arel/nodes/as.rb +6 -0
- data/lib/arel/nodes/assignment.rb +6 -0
- data/lib/arel/nodes/avg.rb +6 -0
- data/lib/arel/nodes/between.rb +6 -0
- data/lib/arel/nodes/binary.rb +12 -0
- data/lib/arel/nodes/count.rb +13 -0
- data/lib/arel/nodes/delete_statement.rb +19 -0
- data/lib/arel/nodes/does_not_match.rb +6 -0
- data/lib/arel/nodes/equality.rb +9 -0
- data/lib/arel/nodes/except.rb +7 -0
- data/lib/arel/nodes/exists.rb +7 -0
- data/lib/arel/nodes/function.rb +18 -0
- data/lib/arel/nodes/greater_than.rb +6 -0
- data/lib/arel/nodes/greater_than_or_equal.rb +6 -0
- data/lib/arel/nodes/group.rb +6 -0
- data/lib/arel/nodes/grouping.rb +6 -0
- data/lib/arel/nodes/having.rb +6 -0
- data/lib/arel/nodes/in.rb +6 -0
- data/lib/arel/nodes/inner_join.rb +6 -0
- data/lib/arel/nodes/insert_statement.rb +19 -0
- data/lib/arel/nodes/intersect.rb +7 -0
- data/lib/arel/nodes/join.rb +13 -0
- data/lib/arel/nodes/less_than.rb +6 -0
- data/lib/arel/nodes/less_than_or_equal.rb +6 -0
- data/lib/arel/nodes/limit.rb +7 -0
- data/lib/arel/nodes/lock.rb +6 -0
- data/lib/arel/nodes/matches.rb +6 -0
- data/lib/arel/nodes/max.rb +6 -0
- data/lib/arel/nodes/min.rb +6 -0
- data/lib/arel/nodes/node.rb +44 -0
- data/lib/arel/nodes/not.rb +6 -0
- data/lib/arel/nodes/not_equal.rb +6 -0
- data/lib/arel/nodes/not_in.rb +6 -0
- data/lib/arel/nodes/offset.rb +7 -0
- data/lib/arel/nodes/on.rb +6 -0
- data/lib/arel/nodes/or.rb +6 -0
- data/lib/arel/nodes/ordering.rb +20 -0
- data/lib/arel/nodes/outer_join.rb +6 -0
- data/lib/arel/nodes/select_core.rb +26 -0
- data/lib/arel/nodes/select_statement.rb +22 -0
- data/lib/arel/nodes/sql_literal.rb +8 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/sum.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +13 -0
- data/lib/arel/nodes/top.rb +6 -0
- data/lib/arel/nodes/unary.rb +11 -0
- data/lib/arel/nodes/union.rb +7 -0
- data/lib/arel/nodes/union_all.rb +7 -0
- data/lib/arel/nodes/unqualified_column.rb +16 -0
- data/lib/arel/nodes/update_statement.rb +21 -0
- data/lib/arel/nodes/values.rb +14 -0
- data/lib/arel/predications.rb +183 -0
- data/lib/arel/relation.rb +6 -0
- data/lib/arel/select_manager.rb +237 -0
- data/lib/arel/sql/engine.rb +10 -0
- data/lib/arel/sql_literal.rb +4 -0
- data/lib/arel/table.rb +134 -0
- data/lib/arel/tree_manager.rb +36 -0
- data/lib/arel/update_manager.rb +49 -0
- data/lib/arel/visitors.rb +38 -0
- data/lib/arel/visitors/depth_first.rb +154 -0
- data/lib/arel/visitors/dot.rb +230 -0
- data/lib/arel/visitors/join_sql.rb +40 -0
- data/lib/arel/visitors/mssql.rb +16 -0
- data/lib/arel/visitors/mysql.rb +34 -0
- data/lib/arel/visitors/oracle.rb +116 -0
- data/lib/arel/visitors/order_clauses.rb +11 -0
- data/lib/arel/visitors/postgresql.rb +58 -0
- data/lib/arel/visitors/sqlite.rb +11 -0
- data/lib/arel/visitors/to_sql.rb +331 -0
- data/lib/arel/visitors/visitor.rb +27 -0
- data/lib/arel/visitors/where_sql.rb +9 -0
- data/square-arel.gemspec +36 -0
- data/test/attributes/test_attribute.rb +664 -0
- data/test/helper.rb +13 -0
- data/test/nodes/test_as.rb +16 -0
- data/test/nodes/test_count.rb +18 -0
- data/test/nodes/test_delete_statement.rb +14 -0
- data/test/nodes/test_equality.rb +74 -0
- data/test/nodes/test_insert_statement.rb +18 -0
- data/test/nodes/test_node.rb +33 -0
- data/test/nodes/test_not.rb +20 -0
- data/test/nodes/test_or.rb +22 -0
- data/test/nodes/test_select_core.rb +22 -0
- data/test/nodes/test_select_statement.rb +13 -0
- data/test/nodes/test_sql_literal.rb +52 -0
- data/test/nodes/test_sum.rb +12 -0
- data/test/nodes/test_update_statement.rb +18 -0
- data/test/support/fake_record.rb +91 -0
- data/test/test_activerecord_compat.rb +18 -0
- data/test/test_attributes.rb +46 -0
- data/test/test_crud.rb +69 -0
- data/test/test_delete_manager.rb +42 -0
- data/test/test_insert_manager.rb +125 -0
- data/test/test_select_manager.rb +659 -0
- data/test/test_table.rb +193 -0
- data/test/test_update_manager.rb +86 -0
- data/test/visitors/test_depth_first.rb +212 -0
- data/test/visitors/test_dot.rb +29 -0
- data/test/visitors/test_join_sql.rb +35 -0
- data/test/visitors/test_mssql.rb +18 -0
- data/test/visitors/test_mysql.rb +45 -0
- data/test/visitors/test_oracle.rb +147 -0
- data/test/visitors/test_postgres.rb +36 -0
- data/test/visitors/test_sqlite.rb +18 -0
- data/test/visitors/test_to_sql.rb +255 -0
- metadata +261 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
module Arel
|
2
|
+
module Nodes
|
3
|
+
###
|
4
|
+
# Abstract base class for all AST nodes
|
5
|
+
class Node
|
6
|
+
###
|
7
|
+
# Factory method to create a Nodes::Not node that has the recipient of
|
8
|
+
# the caller as a child.
|
9
|
+
def not
|
10
|
+
Nodes::Not.new Nodes::Grouping.new self
|
11
|
+
end
|
12
|
+
|
13
|
+
###
|
14
|
+
# Factory method to create a Nodes::Grouping node that has an Nodes::Or
|
15
|
+
# node as a child.
|
16
|
+
def or right
|
17
|
+
Nodes::Grouping.new Nodes::Or.new(self, right)
|
18
|
+
end
|
19
|
+
|
20
|
+
###
|
21
|
+
# Factory method to create an Nodes::And node.
|
22
|
+
def and right
|
23
|
+
Nodes::And.new self, right
|
24
|
+
end
|
25
|
+
|
26
|
+
# FIXME: this method should go away. I don't like people calling
|
27
|
+
# to_sql on non-head nodes. This forces us to walk the AST until we
|
28
|
+
# can find a node that has a "relation" member.
|
29
|
+
#
|
30
|
+
# Maybe we should just use `Table.engine`? :'(
|
31
|
+
def to_sql engine = Table.engine
|
32
|
+
viz = Visitors.for engine
|
33
|
+
viz.accept self
|
34
|
+
end
|
35
|
+
|
36
|
+
# Iterate through AST, nodes will be yielded depth-first
|
37
|
+
def each &block
|
38
|
+
return enum_for(:each) unless block_given?
|
39
|
+
|
40
|
+
Visitors::DepthFirst.new(block).accept self
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Arel
|
2
|
+
module Nodes
|
3
|
+
class Ordering < Arel::Nodes::Binary
|
4
|
+
alias :expr :left
|
5
|
+
alias :direction :right
|
6
|
+
|
7
|
+
def initialize expr, direction = :asc
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def ascending?
|
12
|
+
direction == :asc
|
13
|
+
end
|
14
|
+
|
15
|
+
def descending?
|
16
|
+
direction == :desc
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Arel
|
2
|
+
module Nodes
|
3
|
+
class SelectCore < Arel::Nodes::Node
|
4
|
+
attr_accessor :top, :froms, :projections, :wheres, :groups
|
5
|
+
attr_accessor :having
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@top = nil
|
9
|
+
@froms = nil
|
10
|
+
@projections = []
|
11
|
+
@wheres = []
|
12
|
+
@groups = []
|
13
|
+
@having = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize_copy other
|
17
|
+
super
|
18
|
+
@froms = @froms.clone if @froms
|
19
|
+
@projections = @projections.clone
|
20
|
+
@wheres = @wheres.clone
|
21
|
+
@group = @groups.clone
|
22
|
+
@having = @having.clone if @having
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Arel
|
2
|
+
module Nodes
|
3
|
+
class SelectStatement < Arel::Nodes::Node
|
4
|
+
attr_reader :cores
|
5
|
+
attr_accessor :limit, :orders, :lock, :offset
|
6
|
+
|
7
|
+
def initialize cores = [SelectCore.new]
|
8
|
+
@cores = cores
|
9
|
+
@orders = []
|
10
|
+
@limit = nil
|
11
|
+
@lock = nil
|
12
|
+
@offset = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize_copy other
|
16
|
+
super
|
17
|
+
@cores = @cores.map { |x| x.clone }
|
18
|
+
@orders = @orders.map { |x| x.clone }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Arel
|
2
|
+
module Nodes
|
3
|
+
class UpdateStatement < Arel::Nodes::Node
|
4
|
+
attr_accessor :relation, :wheres, :values, :orders, :limit
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@relation = nil
|
8
|
+
@wheres = []
|
9
|
+
@values = []
|
10
|
+
@orders = []
|
11
|
+
@limit = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize_copy other
|
15
|
+
super
|
16
|
+
@wheres = @wheres.clone
|
17
|
+
@values = @values.clone
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
module Arel
|
2
|
+
module Predications
|
3
|
+
def as other
|
4
|
+
Nodes::As.new self, other
|
5
|
+
end
|
6
|
+
|
7
|
+
def not_eq other
|
8
|
+
Nodes::NotEqual.new self, other
|
9
|
+
end
|
10
|
+
|
11
|
+
def not_eq_any others
|
12
|
+
grouping_any :not_eq, others
|
13
|
+
end
|
14
|
+
|
15
|
+
def not_eq_all others
|
16
|
+
grouping_all :not_eq, others
|
17
|
+
end
|
18
|
+
|
19
|
+
def eq other
|
20
|
+
Nodes::Equality.new self, other
|
21
|
+
end
|
22
|
+
|
23
|
+
def eq_any others
|
24
|
+
grouping_any :eq, others
|
25
|
+
end
|
26
|
+
|
27
|
+
def eq_all others
|
28
|
+
grouping_all :eq, others
|
29
|
+
end
|
30
|
+
|
31
|
+
def in other
|
32
|
+
case other
|
33
|
+
when Arel::SelectManager
|
34
|
+
Arel::Nodes::In.new(self, other.ast)
|
35
|
+
when Range
|
36
|
+
if other.exclude_end?
|
37
|
+
left = Nodes::GreaterThanOrEqual.new(self, other.begin)
|
38
|
+
right = Nodes::LessThan.new(self, other.end)
|
39
|
+
Nodes::And.new left, right
|
40
|
+
else
|
41
|
+
Nodes::Between.new(self, Nodes::And.new(other.begin, other.end))
|
42
|
+
end
|
43
|
+
else
|
44
|
+
Nodes::In.new self, other
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def in_any others
|
49
|
+
grouping_any :in, others
|
50
|
+
end
|
51
|
+
|
52
|
+
def in_all others
|
53
|
+
grouping_all :in, others
|
54
|
+
end
|
55
|
+
|
56
|
+
def not_in other
|
57
|
+
case other
|
58
|
+
when Arel::SelectManager
|
59
|
+
Arel::Nodes::NotIn.new(self, other.ast)
|
60
|
+
when Range
|
61
|
+
if other.exclude_end?
|
62
|
+
left = Nodes::LessThan.new(self, other.begin)
|
63
|
+
right = Nodes::GreaterThanOrEqual.new(self, other.end)
|
64
|
+
Nodes::Or.new left, right
|
65
|
+
else
|
66
|
+
left = Nodes::LessThan.new(self, other.begin)
|
67
|
+
right = Nodes::GreaterThan.new(self, other.end)
|
68
|
+
Nodes::Or.new left, right
|
69
|
+
end
|
70
|
+
else
|
71
|
+
Nodes::NotIn.new self, other
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def not_in_any others
|
76
|
+
grouping_any :not_in, others
|
77
|
+
end
|
78
|
+
|
79
|
+
def not_in_all others
|
80
|
+
grouping_all :not_in, others
|
81
|
+
end
|
82
|
+
|
83
|
+
def matches other
|
84
|
+
Nodes::Matches.new self, other
|
85
|
+
end
|
86
|
+
|
87
|
+
def matches_any others
|
88
|
+
grouping_any :matches, others
|
89
|
+
end
|
90
|
+
|
91
|
+
def matches_all others
|
92
|
+
grouping_all :matches, others
|
93
|
+
end
|
94
|
+
|
95
|
+
def does_not_match other
|
96
|
+
Nodes::DoesNotMatch.new self, other
|
97
|
+
end
|
98
|
+
|
99
|
+
def does_not_match_any others
|
100
|
+
grouping_any :does_not_match, others
|
101
|
+
end
|
102
|
+
|
103
|
+
def does_not_match_all others
|
104
|
+
grouping_all :does_not_match, others
|
105
|
+
end
|
106
|
+
|
107
|
+
def gteq right
|
108
|
+
Nodes::GreaterThanOrEqual.new self, right
|
109
|
+
end
|
110
|
+
|
111
|
+
def gteq_any others
|
112
|
+
grouping_any :gteq, others
|
113
|
+
end
|
114
|
+
|
115
|
+
def gteq_all others
|
116
|
+
grouping_all :gteq, others
|
117
|
+
end
|
118
|
+
|
119
|
+
def gt right
|
120
|
+
Nodes::GreaterThan.new self, right
|
121
|
+
end
|
122
|
+
|
123
|
+
def gt_any others
|
124
|
+
grouping_any :gt, others
|
125
|
+
end
|
126
|
+
|
127
|
+
def gt_all others
|
128
|
+
grouping_all :gt, others
|
129
|
+
end
|
130
|
+
|
131
|
+
def lt right
|
132
|
+
Nodes::LessThan.new self, right
|
133
|
+
end
|
134
|
+
|
135
|
+
def lt_any others
|
136
|
+
grouping_any :lt, others
|
137
|
+
end
|
138
|
+
|
139
|
+
def lt_all others
|
140
|
+
grouping_all :lt, others
|
141
|
+
end
|
142
|
+
|
143
|
+
def lteq right
|
144
|
+
Nodes::LessThanOrEqual.new self, right
|
145
|
+
end
|
146
|
+
|
147
|
+
def lteq_any others
|
148
|
+
grouping_any :lteq, others
|
149
|
+
end
|
150
|
+
|
151
|
+
def lteq_all others
|
152
|
+
grouping_all :lteq, others
|
153
|
+
end
|
154
|
+
|
155
|
+
def asc
|
156
|
+
Nodes::Ordering.new self, :asc
|
157
|
+
end
|
158
|
+
|
159
|
+
def desc
|
160
|
+
Nodes::Ordering.new self, :desc
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def grouping_any method_id, others
|
166
|
+
others = others.dup
|
167
|
+
first = send method_id, others.shift
|
168
|
+
|
169
|
+
Nodes::Grouping.new others.inject(first) { |memo,expr|
|
170
|
+
Nodes::Or.new(memo, send(method_id, expr))
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
174
|
+
def grouping_all method_id, others
|
175
|
+
others = others.dup
|
176
|
+
first = send method_id, others.shift
|
177
|
+
|
178
|
+
Nodes::Grouping.new others.inject(first) { |memo,expr|
|
179
|
+
Nodes::And.new(memo, send(method_id, expr))
|
180
|
+
}
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|