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,38 @@
1
+ require 'arel/visitors/visitor'
2
+ require 'arel/visitors/depth_first'
3
+ require 'arel/visitors/to_sql'
4
+ require 'arel/visitors/sqlite'
5
+ require 'arel/visitors/postgresql'
6
+ require 'arel/visitors/mysql'
7
+ require 'arel/visitors/mssql'
8
+ require 'arel/visitors/oracle'
9
+ require 'arel/visitors/join_sql'
10
+ require 'arel/visitors/where_sql'
11
+ require 'arel/visitors/order_clauses'
12
+ require 'arel/visitors/dot'
13
+
14
+ module Arel
15
+ module Visitors
16
+ VISITORS = {
17
+ 'postgresql' => Arel::Visitors::PostgreSQL,
18
+ 'mysql' => Arel::Visitors::MySQL,
19
+ 'mysql2' => Arel::Visitors::MySQL,
20
+ 'mssql' => Arel::Visitors::MSSQL,
21
+ 'sqlserver' => Arel::Visitors::MSSQL,
22
+ 'oracle_enhanced' => Arel::Visitors::Oracle,
23
+ 'sqlite' => Arel::Visitors::SQLite,
24
+ 'sqlite3' => Arel::Visitors::SQLite,
25
+ }
26
+
27
+ ENGINE_VISITORS = Hash.new do |hash, engine|
28
+ pool = engine.connection_pool
29
+ adapter = pool.spec.config[:adapter]
30
+ hash[engine] = (VISITORS[adapter] || Visitors::ToSql).new(engine)
31
+ end
32
+
33
+ def self.visitor_for engine
34
+ ENGINE_VISITORS[engine]
35
+ end
36
+ class << self; alias :for :visitor_for; end
37
+ end
38
+ end
@@ -0,0 +1,154 @@
1
+ module Arel
2
+ module Visitors
3
+ class DepthFirst < Arel::Visitors::Visitor
4
+ def initialize block = nil
5
+ @block = block || Proc.new
6
+ end
7
+
8
+ private
9
+
10
+ def visit o
11
+ super
12
+ @block.call o
13
+ end
14
+
15
+ def unary o
16
+ visit o.expr
17
+ end
18
+ alias :visit_Arel_Nodes_Group :unary
19
+ alias :visit_Arel_Nodes_Grouping :unary
20
+ alias :visit_Arel_Nodes_Having :unary
21
+ alias :visit_Arel_Nodes_Limit :unary
22
+ alias :visit_Arel_Nodes_Not :unary
23
+ alias :visit_Arel_Nodes_Offset :unary
24
+ alias :visit_Arel_Nodes_On :unary
25
+ alias :visit_Arel_Nodes_Top :unary
26
+ alias :visit_Arel_Nodes_UnqualifiedColumn :unary
27
+
28
+ def function o
29
+ visit o.expressions
30
+ visit o.alias
31
+ end
32
+ alias :visit_Arel_Nodes_Avg :function
33
+ alias :visit_Arel_Nodes_Exists :function
34
+ alias :visit_Arel_Nodes_Max :function
35
+ alias :visit_Arel_Nodes_Min :function
36
+ alias :visit_Arel_Nodes_Sum :function
37
+
38
+ def visit_Arel_Nodes_Count o
39
+ visit o.expressions
40
+ visit o.alias
41
+ visit o.distinct
42
+ end
43
+
44
+ def join o
45
+ visit o.left
46
+ visit o.right
47
+ visit o.constraint
48
+ end
49
+ alias :visit_Arel_Nodes_InnerJoin :join
50
+ alias :visit_Arel_Nodes_OuterJoin :join
51
+
52
+ def binary o
53
+ visit o.left
54
+ visit o.right
55
+ end
56
+ alias :visit_Arel_Nodes_And :binary
57
+ alias :visit_Arel_Nodes_As :binary
58
+ alias :visit_Arel_Nodes_Assignment :binary
59
+ alias :visit_Arel_Nodes_Between :binary
60
+ alias :visit_Arel_Nodes_DeleteStatement :binary
61
+ alias :visit_Arel_Nodes_DoesNotMatch :binary
62
+ alias :visit_Arel_Nodes_Equality :binary
63
+ alias :visit_Arel_Nodes_GreaterThan :binary
64
+ alias :visit_Arel_Nodes_GreaterThanOrEqual :binary
65
+ alias :visit_Arel_Nodes_In :binary
66
+ alias :visit_Arel_Nodes_LessThan :binary
67
+ alias :visit_Arel_Nodes_LessThanOrEqual :binary
68
+ alias :visit_Arel_Nodes_Matches :binary
69
+ alias :visit_Arel_Nodes_NotEqual :binary
70
+ alias :visit_Arel_Nodes_NotIn :binary
71
+ alias :visit_Arel_Nodes_Or :binary
72
+ alias :visit_Arel_Nodes_Ordering :binary
73
+ alias :visit_Arel_Nodes_StringJoin :binary
74
+ alias :visit_Arel_Nodes_TableAlias :binary
75
+ alias :visit_Arel_Nodes_Values :binary
76
+
77
+ def visit_Arel_Attribute o
78
+ visit o.relation
79
+ visit o.name
80
+ end
81
+ alias :visit_Arel_Attributes_Integer :visit_Arel_Attribute
82
+ alias :visit_Arel_Attributes_Float :visit_Arel_Attribute
83
+ alias :visit_Arel_Attributes_String :visit_Arel_Attribute
84
+ alias :visit_Arel_Attributes_Time :visit_Arel_Attribute
85
+ alias :visit_Arel_Attributes_Boolean :visit_Arel_Attribute
86
+ alias :visit_Arel_Attributes_Attribute :visit_Arel_Attribute
87
+ alias :visit_Arel_Attributes_Decimal :visit_Arel_Attribute
88
+
89
+ def visit_Arel_Table o
90
+ visit o.name
91
+ end
92
+
93
+ def terminal o
94
+ end
95
+ alias :visit_ActiveSupport_Multibyte_Chars :terminal
96
+ alias :visit_ActiveSupport_StringInquirer :terminal
97
+ alias :visit_Arel_Nodes_Lock :terminal
98
+ alias :visit_Arel_Nodes_Node :terminal
99
+ alias :visit_Arel_Nodes_SqlLiteral :terminal
100
+ alias :visit_Arel_SqlLiteral :terminal
101
+ alias :visit_BigDecimal :terminal
102
+ alias :visit_Bignum :terminal
103
+ alias :visit_Class :terminal
104
+ alias :visit_Date :terminal
105
+ alias :visit_DateTime :terminal
106
+ alias :visit_FalseClass :terminal
107
+ alias :visit_Fixnum :terminal
108
+ alias :visit_Float :terminal
109
+ alias :visit_NilClass :terminal
110
+ alias :visit_String :terminal
111
+ alias :visit_Symbol :terminal
112
+ alias :visit_Time :terminal
113
+ alias :visit_TrueClass :terminal
114
+
115
+ def visit_Arel_Nodes_InsertStatement o
116
+ visit o.relation
117
+ visit o.columns
118
+ visit o.values
119
+ end
120
+
121
+ def visit_Arel_Nodes_SelectCore o
122
+ visit o.projections
123
+ visit o.froms
124
+ visit o.wheres
125
+ visit o.groups
126
+ visit o.having
127
+ end
128
+
129
+ def visit_Arel_Nodes_SelectStatement o
130
+ visit o.cores
131
+ visit o.orders
132
+ visit o.limit
133
+ visit o.lock
134
+ visit o.offset
135
+ end
136
+
137
+ def visit_Arel_Nodes_UpdateStatement o
138
+ visit o.relation
139
+ visit o.values
140
+ visit o.wheres
141
+ visit o.orders
142
+ visit o.limit
143
+ end
144
+
145
+ def visit_Array o
146
+ o.each { |i| visit i }
147
+ end
148
+
149
+ def visit_Hash o
150
+ o.each { |k,v| visit(k); visit(v) }
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,230 @@
1
+ module Arel
2
+ module Visitors
3
+ class Dot < Arel::Visitors::Visitor
4
+ class Node # :nodoc:
5
+ attr_accessor :name, :id, :fields
6
+
7
+ def initialize name, id, fields = []
8
+ @name = name
9
+ @id = id
10
+ @fields = fields
11
+ end
12
+ end
13
+
14
+ class Edge < Struct.new :name, :from, :to # :nodoc:
15
+ end
16
+
17
+ def initialize
18
+ @nodes = []
19
+ @edges = []
20
+ @node_stack = []
21
+ @edge_stack = []
22
+ @seen = {}
23
+ end
24
+
25
+ def accept object
26
+ super
27
+ to_dot
28
+ end
29
+
30
+ private
31
+ def visit_Arel_Nodes_Ordering o
32
+ visit_edge o, "expr"
33
+ visit_edge o, "direction"
34
+ end
35
+
36
+ def visit_Arel_Nodes_TableAlias o
37
+ visit_edge o, "name"
38
+ visit_edge o, "relation"
39
+ visit_edge o, "columns"
40
+ end
41
+
42
+ def visit_Arel_Nodes_Sum o
43
+ visit_edge o, "expressions"
44
+ visit_edge o, "alias"
45
+ end
46
+ alias :visit_Arel_Nodes_Max :visit_Arel_Nodes_Sum
47
+ alias :visit_Arel_Nodes_Avg :visit_Arel_Nodes_Sum
48
+
49
+ def visit_Arel_Nodes_Count o
50
+ visit_edge o, "expressions"
51
+ visit_edge o, "distinct"
52
+ end
53
+
54
+ def visit_Arel_Nodes_Values o
55
+ visit_edge o, "expressions"
56
+ end
57
+
58
+ def visit_Arel_Nodes_StringJoin o
59
+ visit_edge o, "left"
60
+ visit_edge o, "right"
61
+ end
62
+
63
+ def visit_Arel_Nodes_InnerJoin o
64
+ visit_edge o, "left"
65
+ visit_edge o, "right"
66
+ visit_edge o, "constraint"
67
+ end
68
+ alias :visit_Arel_Nodes_OuterJoin :visit_Arel_Nodes_InnerJoin
69
+
70
+ def visit_Arel_Nodes_DeleteStatement o
71
+ visit_edge o, "relation"
72
+ visit_edge o, "wheres"
73
+ end
74
+
75
+ def unary o
76
+ visit_edge o, "expr"
77
+ end
78
+ alias :visit_Arel_Nodes_Group :unary
79
+ alias :visit_Arel_Nodes_Grouping :unary
80
+ alias :visit_Arel_Nodes_Having :unary
81
+ alias :visit_Arel_Nodes_Limit :unary
82
+ alias :visit_Arel_Nodes_Not :unary
83
+ alias :visit_Arel_Nodes_Offset :unary
84
+ alias :visit_Arel_Nodes_On :unary
85
+ alias :visit_Arel_Nodes_Top :unary
86
+ alias :visit_Arel_Nodes_UnqualifiedColumn :unary
87
+
88
+ def visit_Arel_Nodes_InsertStatement o
89
+ visit_edge o, "relation"
90
+ visit_edge o, "columns"
91
+ visit_edge o, "values"
92
+ end
93
+
94
+ def visit_Arel_Nodes_SelectCore o
95
+ visit_edge o, "froms"
96
+ visit_edge o, "projections"
97
+ visit_edge o, "wheres"
98
+ end
99
+
100
+ def visit_Arel_Nodes_SelectStatement o
101
+ visit_edge o, "cores"
102
+ visit_edge o, "limit"
103
+ visit_edge o, "orders"
104
+ visit_edge o, "offset"
105
+ end
106
+
107
+ def visit_Arel_Nodes_UpdateStatement o
108
+ visit_edge o, "relation"
109
+ visit_edge o, "wheres"
110
+ visit_edge o, "values"
111
+ end
112
+
113
+ def visit_Arel_Table o
114
+ visit_edge o, "name"
115
+ end
116
+
117
+ def visit_Arel_Attribute o
118
+ visit_edge o, "relation"
119
+ visit_edge o, "name"
120
+ end
121
+ alias :visit_Arel_Attributes_Integer :visit_Arel_Attribute
122
+ alias :visit_Arel_Attributes_Float :visit_Arel_Attribute
123
+ alias :visit_Arel_Attributes_String :visit_Arel_Attribute
124
+ alias :visit_Arel_Attributes_Time :visit_Arel_Attribute
125
+ alias :visit_Arel_Attributes_Boolean :visit_Arel_Attribute
126
+ alias :visit_Arel_Attributes_Attribute :visit_Arel_Attribute
127
+
128
+ def visit_Arel_Nodes_Equality o
129
+ visit_edge o, "left"
130
+ visit_edge o, "right"
131
+ end
132
+ alias :visit_Arel_Nodes_And :visit_Arel_Nodes_Equality
133
+ alias :visit_Arel_Nodes_Or :visit_Arel_Nodes_Equality
134
+ alias :visit_Arel_Nodes_NotEqual :visit_Arel_Nodes_Equality
135
+ alias :visit_Arel_Nodes_GreaterThan :visit_Arel_Nodes_Equality
136
+ alias :visit_Arel_Nodes_GreaterThanOrEqual :visit_Arel_Nodes_Equality
137
+ alias :visit_Arel_Nodes_Assignment :visit_Arel_Nodes_Equality
138
+ alias :visit_Arel_Nodes_In :visit_Arel_Nodes_Equality
139
+ alias :visit_Arel_Nodes_LessThan :visit_Arel_Nodes_Equality
140
+ alias :visit_Arel_Nodes_LessThanOrEqual :visit_Arel_Nodes_Equality
141
+ alias :visit_Arel_Nodes_Between :visit_Arel_Nodes_Equality
142
+ alias :visit_Arel_Nodes_NotIn :visit_Arel_Nodes_Equality
143
+ alias :visit_Arel_Nodes_DoesNotMatch :visit_Arel_Nodes_Equality
144
+ alias :visit_Arel_Nodes_Matches :visit_Arel_Nodes_Equality
145
+
146
+ def visit_String o
147
+ @node_stack.last.fields << o
148
+ end
149
+ alias :visit_Time :visit_String
150
+ alias :visit_Date :visit_String
151
+ alias :visit_DateTime :visit_String
152
+ alias :visit_NilClass :visit_String
153
+ alias :visit_TrueClass :visit_String
154
+ alias :visit_FalseClass :visit_String
155
+ alias :visit_Arel_SqlLiteral :visit_String
156
+ alias :visit_Fixnum :visit_String
157
+ alias :visit_BigDecimal :visit_String
158
+ alias :visit_Float :visit_String
159
+ alias :visit_Symbol :visit_String
160
+ alias :visit_Arel_Nodes_SqlLiteral :visit_String
161
+
162
+ def visit_Hash o
163
+ o.each_with_index do |pair, i|
164
+ edge("pair_#{i}") { visit pair }
165
+ end
166
+ end
167
+
168
+ def visit_Array o
169
+ o.each_with_index do |x,i|
170
+ edge(i) { visit x }
171
+ end
172
+ end
173
+
174
+ def visit_edge o, method
175
+ edge(method) { visit o.send(method) }
176
+ end
177
+
178
+ def visit o
179
+ if node = @seen[o.object_id]
180
+ @edge_stack.last.to = node
181
+ return
182
+ end
183
+
184
+ node = Node.new(o.class.name, o.object_id)
185
+ @seen[node.id] = node
186
+ @nodes << node
187
+ with_node node do
188
+ super
189
+ end
190
+ end
191
+
192
+ def edge name
193
+ edge = Edge.new(name, @node_stack.last)
194
+ @edge_stack.push edge
195
+ @edges << edge
196
+ yield
197
+ @edge_stack.pop
198
+ end
199
+
200
+ def with_node node
201
+ if edge = @edge_stack.last
202
+ edge.to = node
203
+ end
204
+
205
+ @node_stack.push node
206
+ yield
207
+ @node_stack.pop
208
+ end
209
+
210
+ def quote string
211
+ string.to_s.gsub('"', '\"')
212
+ end
213
+
214
+ def to_dot
215
+ "digraph \"ARel\" {\nnode [width=0.375,height=0.25,shape=record];\n" +
216
+ @nodes.map { |node|
217
+ label = "<f0>#{node.name}"
218
+
219
+ node.fields.each_with_index do |field, i|
220
+ label << "|<f#{i + 1}>#{quote field}"
221
+ end
222
+
223
+ "#{node.id} [label=\"#{label}\"];"
224
+ }.join("\n") + "\n" + @edges.map { |edge|
225
+ "#{edge.from.id} -> #{edge.to.id} [label=\"#{edge.name}\"];"
226
+ }.join("\n") + "\n}"
227
+ end
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,40 @@
1
+ module Arel
2
+ module Visitors
3
+ ###
4
+ # This class produces SQL for JOIN clauses but omits the "single-source"
5
+ # part of the Join grammar:
6
+ #
7
+ # http://www.sqlite.org/syntaxdiagrams.html#join-source
8
+ #
9
+ # This visitor is used in SelectManager#join_sql and is for backwards
10
+ # compatibility with Arel V1.0
11
+ class JoinSql < Arel::Visitors::ToSql
12
+ private
13
+
14
+ def visit_Arel_Nodes_SelectCore o
15
+ [o.froms].grep(Nodes::Join).map { |x| visit x }.join ', '
16
+ end
17
+
18
+ def visit_Arel_Nodes_StringJoin o
19
+ [
20
+ (visit o.left if Nodes::Join === o.left),
21
+ visit(o.right)
22
+ ].compact.join ' '
23
+ end
24
+
25
+ def visit_Arel_Nodes_OuterJoin o
26
+ [
27
+ (visit o.left if Nodes::Join === o.left),
28
+ "LEFT OUTER JOIN #{visit o.right} #{visit o.constraint if o.constraint}"
29
+ ].compact.join ' '
30
+ end
31
+
32
+ def visit_Arel_Nodes_InnerJoin o
33
+ [
34
+ (visit o.left if Nodes::Join === o.left),
35
+ "INNER JOIN #{visit o.right} #{visit o.constraint if o.constraint}"
36
+ ].compact.join ' '
37
+ end
38
+ end
39
+ end
40
+ end