square-arel 2.0.9.20110222133018

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/.autotest +26 -0
  2. data/History.txt +105 -0
  3. data/MIT-LICENSE.txt +20 -0
  4. data/Manifest.txt +124 -0
  5. data/README.markdown +94 -0
  6. data/Rakefile +20 -0
  7. data/lib/arel.rb +39 -0
  8. data/lib/arel/attributes.rb +20 -0
  9. data/lib/arel/attributes/attribute.rb +18 -0
  10. data/lib/arel/compatibility/wheres.rb +33 -0
  11. data/lib/arel/crud.rb +37 -0
  12. data/lib/arel/delete_manager.rb +18 -0
  13. data/lib/arel/deprecated.rb +4 -0
  14. data/lib/arel/expression.rb +4 -0
  15. data/lib/arel/expressions.rb +23 -0
  16. data/lib/arel/insert_manager.rb +34 -0
  17. data/lib/arel/nodes.rb +53 -0
  18. data/lib/arel/nodes/and.rb +6 -0
  19. data/lib/arel/nodes/as.rb +6 -0
  20. data/lib/arel/nodes/assignment.rb +6 -0
  21. data/lib/arel/nodes/avg.rb +6 -0
  22. data/lib/arel/nodes/between.rb +6 -0
  23. data/lib/arel/nodes/binary.rb +12 -0
  24. data/lib/arel/nodes/count.rb +13 -0
  25. data/lib/arel/nodes/delete_statement.rb +19 -0
  26. data/lib/arel/nodes/does_not_match.rb +6 -0
  27. data/lib/arel/nodes/equality.rb +9 -0
  28. data/lib/arel/nodes/except.rb +7 -0
  29. data/lib/arel/nodes/exists.rb +7 -0
  30. data/lib/arel/nodes/function.rb +18 -0
  31. data/lib/arel/nodes/greater_than.rb +6 -0
  32. data/lib/arel/nodes/greater_than_or_equal.rb +6 -0
  33. data/lib/arel/nodes/group.rb +6 -0
  34. data/lib/arel/nodes/grouping.rb +6 -0
  35. data/lib/arel/nodes/having.rb +6 -0
  36. data/lib/arel/nodes/in.rb +6 -0
  37. data/lib/arel/nodes/inner_join.rb +6 -0
  38. data/lib/arel/nodes/insert_statement.rb +19 -0
  39. data/lib/arel/nodes/intersect.rb +7 -0
  40. data/lib/arel/nodes/join.rb +13 -0
  41. data/lib/arel/nodes/less_than.rb +6 -0
  42. data/lib/arel/nodes/less_than_or_equal.rb +6 -0
  43. data/lib/arel/nodes/limit.rb +7 -0
  44. data/lib/arel/nodes/lock.rb +6 -0
  45. data/lib/arel/nodes/matches.rb +6 -0
  46. data/lib/arel/nodes/max.rb +6 -0
  47. data/lib/arel/nodes/min.rb +6 -0
  48. data/lib/arel/nodes/node.rb +44 -0
  49. data/lib/arel/nodes/not.rb +6 -0
  50. data/lib/arel/nodes/not_equal.rb +6 -0
  51. data/lib/arel/nodes/not_in.rb +6 -0
  52. data/lib/arel/nodes/offset.rb +7 -0
  53. data/lib/arel/nodes/on.rb +6 -0
  54. data/lib/arel/nodes/or.rb +6 -0
  55. data/lib/arel/nodes/ordering.rb +20 -0
  56. data/lib/arel/nodes/outer_join.rb +6 -0
  57. data/lib/arel/nodes/select_core.rb +26 -0
  58. data/lib/arel/nodes/select_statement.rb +22 -0
  59. data/lib/arel/nodes/sql_literal.rb +8 -0
  60. data/lib/arel/nodes/string_join.rb +11 -0
  61. data/lib/arel/nodes/sum.rb +6 -0
  62. data/lib/arel/nodes/table_alias.rb +13 -0
  63. data/lib/arel/nodes/top.rb +6 -0
  64. data/lib/arel/nodes/unary.rb +11 -0
  65. data/lib/arel/nodes/union.rb +7 -0
  66. data/lib/arel/nodes/union_all.rb +7 -0
  67. data/lib/arel/nodes/unqualified_column.rb +16 -0
  68. data/lib/arel/nodes/update_statement.rb +21 -0
  69. data/lib/arel/nodes/values.rb +14 -0
  70. data/lib/arel/predications.rb +183 -0
  71. data/lib/arel/relation.rb +6 -0
  72. data/lib/arel/select_manager.rb +237 -0
  73. data/lib/arel/sql/engine.rb +10 -0
  74. data/lib/arel/sql_literal.rb +4 -0
  75. data/lib/arel/table.rb +134 -0
  76. data/lib/arel/tree_manager.rb +36 -0
  77. data/lib/arel/update_manager.rb +49 -0
  78. data/lib/arel/visitors.rb +38 -0
  79. data/lib/arel/visitors/depth_first.rb +154 -0
  80. data/lib/arel/visitors/dot.rb +230 -0
  81. data/lib/arel/visitors/join_sql.rb +40 -0
  82. data/lib/arel/visitors/mssql.rb +16 -0
  83. data/lib/arel/visitors/mysql.rb +34 -0
  84. data/lib/arel/visitors/oracle.rb +116 -0
  85. data/lib/arel/visitors/order_clauses.rb +11 -0
  86. data/lib/arel/visitors/postgresql.rb +58 -0
  87. data/lib/arel/visitors/sqlite.rb +11 -0
  88. data/lib/arel/visitors/to_sql.rb +331 -0
  89. data/lib/arel/visitors/visitor.rb +27 -0
  90. data/lib/arel/visitors/where_sql.rb +9 -0
  91. data/square-arel.gemspec +36 -0
  92. data/test/attributes/test_attribute.rb +664 -0
  93. data/test/helper.rb +13 -0
  94. data/test/nodes/test_as.rb +16 -0
  95. data/test/nodes/test_count.rb +18 -0
  96. data/test/nodes/test_delete_statement.rb +14 -0
  97. data/test/nodes/test_equality.rb +74 -0
  98. data/test/nodes/test_insert_statement.rb +18 -0
  99. data/test/nodes/test_node.rb +33 -0
  100. data/test/nodes/test_not.rb +20 -0
  101. data/test/nodes/test_or.rb +22 -0
  102. data/test/nodes/test_select_core.rb +22 -0
  103. data/test/nodes/test_select_statement.rb +13 -0
  104. data/test/nodes/test_sql_literal.rb +52 -0
  105. data/test/nodes/test_sum.rb +12 -0
  106. data/test/nodes/test_update_statement.rb +18 -0
  107. data/test/support/fake_record.rb +91 -0
  108. data/test/test_activerecord_compat.rb +18 -0
  109. data/test/test_attributes.rb +46 -0
  110. data/test/test_crud.rb +69 -0
  111. data/test/test_delete_manager.rb +42 -0
  112. data/test/test_insert_manager.rb +125 -0
  113. data/test/test_select_manager.rb +659 -0
  114. data/test/test_table.rb +193 -0
  115. data/test/test_update_manager.rb +86 -0
  116. data/test/visitors/test_depth_first.rb +212 -0
  117. data/test/visitors/test_dot.rb +29 -0
  118. data/test/visitors/test_join_sql.rb +35 -0
  119. data/test/visitors/test_mssql.rb +18 -0
  120. data/test/visitors/test_mysql.rb +45 -0
  121. data/test/visitors/test_oracle.rb +147 -0
  122. data/test/visitors/test_postgres.rb +36 -0
  123. data/test/visitors/test_sqlite.rb +18 -0
  124. data/test/visitors/test_to_sql.rb +255 -0
  125. metadata +261 -0
@@ -0,0 +1,7 @@
1
+ module Arel
2
+ module Nodes
3
+ class Intersect < Arel::Nodes::Binary
4
+ end
5
+ end
6
+ end
7
+
@@ -0,0 +1,13 @@
1
+ module Arel
2
+ module Nodes
3
+ class Join < Arel::Nodes::Node
4
+ attr_accessor :left, :right, :constraint
5
+
6
+ def initialize left, right, constraint
7
+ @left = left
8
+ @right = right
9
+ @constraint = constraint
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class LessThan < Arel::Nodes::Binary
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class LessThanOrEqual < Arel::Nodes::Binary
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ module Arel
2
+ module Nodes
3
+ class Limit < Arel::Nodes::Unary
4
+ end
5
+ end
6
+ end
7
+
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class Lock < Arel::Nodes::Unary
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class Matches < Arel::Nodes::Binary
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class Max < Arel::Nodes::Function
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class Min < Arel::Nodes::Function
4
+ end
5
+ end
6
+ end
@@ -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,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class Not < Arel::Nodes::Unary
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class NotEqual < Arel::Nodes::Binary
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class NotIn < Arel::Nodes::Binary
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ module Arel
2
+ module Nodes
3
+ class Offset < Arel::Nodes::Unary
4
+ alias :value :expr
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class On < Arel::Nodes::Unary
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class Or < Arel::Nodes::Binary
4
+ end
5
+ end
6
+ 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,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class OuterJoin < Arel::Nodes::Join
4
+ end
5
+ end
6
+ 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,8 @@
1
+ module Arel
2
+ module Nodes
3
+ class SqlLiteral < String
4
+ include Arel::Expressions
5
+ include Arel::Predications
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ module Arel
2
+ module Nodes
3
+ class StringJoin < Arel::Nodes::Join
4
+ undef :constraint
5
+
6
+ def initialize left, right
7
+ super(left, right, nil)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class Sum < Arel::Nodes::Function
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ module Arel
2
+ module Nodes
3
+ class TableAlias < Arel::Nodes::Binary
4
+ alias :name :left
5
+ alias :relation :right
6
+ alias :table_alias :name
7
+
8
+ def [] name
9
+ Attribute.new self, name
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class Top < Arel::Nodes::Unary
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ module Arel
2
+ module Nodes
3
+ class Unary < Arel::Nodes::Node
4
+ attr_accessor :expr
5
+
6
+ def initialize expr
7
+ @expr = expr
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Arel
2
+ module Nodes
3
+ class Union < Arel::Nodes::Binary
4
+ end
5
+ end
6
+ end
7
+
@@ -0,0 +1,7 @@
1
+ module Arel
2
+ module Nodes
3
+ class UnionAll < Arel::Nodes::Binary
4
+ end
5
+ end
6
+ end
7
+
@@ -0,0 +1,16 @@
1
+ module Arel
2
+ module Nodes
3
+ class UnqualifiedColumn < Arel::Nodes::Unary
4
+ alias :attribute :expr
5
+ alias :attribute= :expr=
6
+
7
+ def column
8
+ @expr.column
9
+ end
10
+
11
+ def name
12
+ @expr.name
13
+ end
14
+ end
15
+ end
16
+ 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,14 @@
1
+ module Arel
2
+ module Nodes
3
+ class Values < Arel::Nodes::Binary
4
+ alias :expressions :left
5
+ alias :expressions= :left=
6
+ alias :columns :right
7
+ alias :columns= :right=
8
+
9
+ def initialize exprs, columns = []
10
+ super
11
+ end
12
+ end
13
+ end
14
+ 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