square-arel 2.0.9.20110222133018

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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