arel-compat 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. data/History.txt +25 -0
  2. data/README.markdown +182 -0
  3. data/lib/arel.rb +13 -0
  4. data/lib/arel/algebra.rb +10 -0
  5. data/lib/arel/algebra/attributes.rb +7 -0
  6. data/lib/arel/algebra/attributes/attribute.rb +270 -0
  7. data/lib/arel/algebra/attributes/boolean.rb +21 -0
  8. data/lib/arel/algebra/attributes/decimal.rb +9 -0
  9. data/lib/arel/algebra/attributes/float.rb +9 -0
  10. data/lib/arel/algebra/attributes/integer.rb +10 -0
  11. data/lib/arel/algebra/attributes/string.rb +10 -0
  12. data/lib/arel/algebra/attributes/time.rb +6 -0
  13. data/lib/arel/algebra/core_extensions.rb +4 -0
  14. data/lib/arel/algebra/core_extensions/class.rb +32 -0
  15. data/lib/arel/algebra/core_extensions/hash.rb +11 -0
  16. data/lib/arel/algebra/core_extensions/object.rb +30 -0
  17. data/lib/arel/algebra/core_extensions/symbol.rb +9 -0
  18. data/lib/arel/algebra/expression.rb +43 -0
  19. data/lib/arel/algebra/header.rb +67 -0
  20. data/lib/arel/algebra/ordering.rb +23 -0
  21. data/lib/arel/algebra/predicates.rb +190 -0
  22. data/lib/arel/algebra/relations.rb +17 -0
  23. data/lib/arel/algebra/relations/operations/alias.rb +7 -0
  24. data/lib/arel/algebra/relations/operations/from.rb +6 -0
  25. data/lib/arel/algebra/relations/operations/group.rb +12 -0
  26. data/lib/arel/algebra/relations/operations/having.rb +17 -0
  27. data/lib/arel/algebra/relations/operations/join.rb +69 -0
  28. data/lib/arel/algebra/relations/operations/lock.rb +12 -0
  29. data/lib/arel/algebra/relations/operations/order.rb +19 -0
  30. data/lib/arel/algebra/relations/operations/project.rb +20 -0
  31. data/lib/arel/algebra/relations/operations/skip.rb +7 -0
  32. data/lib/arel/algebra/relations/operations/take.rb +11 -0
  33. data/lib/arel/algebra/relations/operations/where.rb +17 -0
  34. data/lib/arel/algebra/relations/relation.rb +136 -0
  35. data/lib/arel/algebra/relations/row.rb +26 -0
  36. data/lib/arel/algebra/relations/utilities/compound.rb +54 -0
  37. data/lib/arel/algebra/relations/utilities/externalization.rb +24 -0
  38. data/lib/arel/algebra/relations/utilities/nil.rb +7 -0
  39. data/lib/arel/algebra/relations/writes.rb +36 -0
  40. data/lib/arel/algebra/value.rb +14 -0
  41. data/lib/arel/engines.rb +2 -0
  42. data/lib/arel/engines/memory.rb +4 -0
  43. data/lib/arel/engines/memory/engine.rb +16 -0
  44. data/lib/arel/engines/memory/predicates.rb +99 -0
  45. data/lib/arel/engines/memory/primitives.rb +27 -0
  46. data/lib/arel/engines/memory/relations.rb +5 -0
  47. data/lib/arel/engines/memory/relations/array.rb +35 -0
  48. data/lib/arel/engines/memory/relations/compound.rb +9 -0
  49. data/lib/arel/engines/memory/relations/operations.rb +67 -0
  50. data/lib/arel/engines/memory/relations/writes.rb +7 -0
  51. data/lib/arel/engines/sql.rb +8 -0
  52. data/lib/arel/engines/sql/attributes.rb +40 -0
  53. data/lib/arel/engines/sql/christener.rb +14 -0
  54. data/lib/arel/engines/sql/compilers/ibm_db_compiler.rb +48 -0
  55. data/lib/arel/engines/sql/compilers/mysql_compiler.rb +11 -0
  56. data/lib/arel/engines/sql/compilers/oracle_compiler.rb +95 -0
  57. data/lib/arel/engines/sql/compilers/postgresql_compiler.rb +42 -0
  58. data/lib/arel/engines/sql/compilers/sqlite_compiler.rb +9 -0
  59. data/lib/arel/engines/sql/core_extensions.rb +4 -0
  60. data/lib/arel/engines/sql/core_extensions/array.rb +24 -0
  61. data/lib/arel/engines/sql/core_extensions/nil_class.rb +15 -0
  62. data/lib/arel/engines/sql/core_extensions/object.rb +19 -0
  63. data/lib/arel/engines/sql/core_extensions/range.rb +19 -0
  64. data/lib/arel/engines/sql/engine.rb +55 -0
  65. data/lib/arel/engines/sql/formatters.rb +122 -0
  66. data/lib/arel/engines/sql/predicates.rb +103 -0
  67. data/lib/arel/engines/sql/primitives.rb +97 -0
  68. data/lib/arel/engines/sql/relations.rb +10 -0
  69. data/lib/arel/engines/sql/relations/compiler.rb +118 -0
  70. data/lib/arel/engines/sql/relations/operations/alias.rb +5 -0
  71. data/lib/arel/engines/sql/relations/operations/join.rb +33 -0
  72. data/lib/arel/engines/sql/relations/relation.rb +65 -0
  73. data/lib/arel/engines/sql/relations/table.rb +88 -0
  74. data/lib/arel/engines/sql/relations/utilities/compound.rb +10 -0
  75. data/lib/arel/engines/sql/relations/utilities/externalization.rb +14 -0
  76. data/lib/arel/engines/sql/relations/utilities/nil.rb +6 -0
  77. data/lib/arel/engines/sql/relations/utilities/recursion.rb +13 -0
  78. data/lib/arel/engines/sql/relations/writes.rb +19 -0
  79. data/lib/arel/session.rb +51 -0
  80. data/lib/arel/version.rb +3 -0
  81. data/spec/algebra/unit/predicates/binary_spec.rb +35 -0
  82. data/spec/algebra/unit/predicates/equality_spec.rb +29 -0
  83. data/spec/algebra/unit/predicates/in_spec.rb +12 -0
  84. data/spec/algebra/unit/primitives/attribute_spec.rb +181 -0
  85. data/spec/algebra/unit/primitives/expression_spec.rb +45 -0
  86. data/spec/algebra/unit/primitives/value_spec.rb +15 -0
  87. data/spec/algebra/unit/relations/alias_spec.rb +16 -0
  88. data/spec/algebra/unit/relations/delete_spec.rb +9 -0
  89. data/spec/algebra/unit/relations/group_spec.rb +10 -0
  90. data/spec/algebra/unit/relations/insert_spec.rb +9 -0
  91. data/spec/algebra/unit/relations/join_spec.rb +25 -0
  92. data/spec/algebra/unit/relations/order_spec.rb +21 -0
  93. data/spec/algebra/unit/relations/project_spec.rb +34 -0
  94. data/spec/algebra/unit/relations/relation_spec.rb +187 -0
  95. data/spec/algebra/unit/relations/skip_spec.rb +10 -0
  96. data/spec/algebra/unit/relations/table_spec.rb +38 -0
  97. data/spec/algebra/unit/relations/take_spec.rb +10 -0
  98. data/spec/algebra/unit/relations/update_spec.rb +9 -0
  99. data/spec/algebra/unit/relations/where_spec.rb +19 -0
  100. data/spec/algebra/unit/session/session_spec.rb +84 -0
  101. data/spec/attributes/boolean_spec.rb +57 -0
  102. data/spec/attributes/float_spec.rb +119 -0
  103. data/spec/attributes/header_spec.rb +42 -0
  104. data/spec/attributes/integer_spec.rb +119 -0
  105. data/spec/attributes/string_spec.rb +43 -0
  106. data/spec/attributes/time_spec.rb +24 -0
  107. data/spec/engines/memory/integration/joins/cross_engine_spec.rb +51 -0
  108. data/spec/engines/memory/unit/relations/array_spec.rb +32 -0
  109. data/spec/engines/memory/unit/relations/insert_spec.rb +28 -0
  110. data/spec/engines/memory/unit/relations/join_spec.rb +31 -0
  111. data/spec/engines/memory/unit/relations/order_spec.rb +27 -0
  112. data/spec/engines/memory/unit/relations/project_spec.rb +27 -0
  113. data/spec/engines/memory/unit/relations/skip_spec.rb +26 -0
  114. data/spec/engines/memory/unit/relations/take_spec.rb +26 -0
  115. data/spec/engines/memory/unit/relations/where_spec.rb +39 -0
  116. data/spec/engines/sql/integration/joins/with_adjacency_spec.rb +258 -0
  117. data/spec/engines/sql/integration/joins/with_aggregations_spec.rb +221 -0
  118. data/spec/engines/sql/integration/joins/with_compounds_spec.rb +137 -0
  119. data/spec/engines/sql/unit/engine_spec.rb +45 -0
  120. data/spec/engines/sql/unit/predicates/binary_spec.rb +140 -0
  121. data/spec/engines/sql/unit/predicates/equality_spec.rb +75 -0
  122. data/spec/engines/sql/unit/predicates/in_spec.rb +179 -0
  123. data/spec/engines/sql/unit/predicates/noteq_spec.rb +75 -0
  124. data/spec/engines/sql/unit/predicates/predicates_spec.rb +79 -0
  125. data/spec/engines/sql/unit/primitives/attribute_spec.rb +36 -0
  126. data/spec/engines/sql/unit/primitives/expression_spec.rb +28 -0
  127. data/spec/engines/sql/unit/primitives/literal_spec.rb +43 -0
  128. data/spec/engines/sql/unit/primitives/value_spec.rb +29 -0
  129. data/spec/engines/sql/unit/relations/alias_spec.rb +53 -0
  130. data/spec/engines/sql/unit/relations/delete_spec.rb +83 -0
  131. data/spec/engines/sql/unit/relations/from_spec.rb +64 -0
  132. data/spec/engines/sql/unit/relations/group_spec.rb +72 -0
  133. data/spec/engines/sql/unit/relations/having_spec.rb +78 -0
  134. data/spec/engines/sql/unit/relations/insert_spec.rb +143 -0
  135. data/spec/engines/sql/unit/relations/join_spec.rb +180 -0
  136. data/spec/engines/sql/unit/relations/lock_spec.rb +86 -0
  137. data/spec/engines/sql/unit/relations/order_spec.rb +161 -0
  138. data/spec/engines/sql/unit/relations/project_spec.rb +143 -0
  139. data/spec/engines/sql/unit/relations/skip_spec.rb +41 -0
  140. data/spec/engines/sql/unit/relations/table_spec.rb +129 -0
  141. data/spec/engines/sql/unit/relations/take_spec.rb +49 -0
  142. data/spec/engines/sql/unit/relations/update_spec.rb +203 -0
  143. data/spec/engines/sql/unit/relations/where_spec.rb +72 -0
  144. data/spec/relations/join_spec.rb +42 -0
  145. data/spec/relations/relation_spec.rb +31 -0
  146. data/spec/shared/relation_spec.rb +255 -0
  147. data/spec/spec_helper.rb +36 -0
  148. data/spec/support/check.rb +6 -0
  149. data/spec/support/connections/mysql_connection.rb +14 -0
  150. data/spec/support/connections/oracle_connection.rb +17 -0
  151. data/spec/support/connections/postgresql_connection.rb +13 -0
  152. data/spec/support/connections/sqlite3_connection.rb +24 -0
  153. data/spec/support/guards.rb +28 -0
  154. data/spec/support/matchers.rb +4 -0
  155. data/spec/support/matchers/be_like.rb +24 -0
  156. data/spec/support/matchers/disambiguate_attributes.rb +28 -0
  157. data/spec/support/matchers/hash_the_same_as.rb +26 -0
  158. data/spec/support/matchers/have_rows.rb +18 -0
  159. data/spec/support/model.rb +62 -0
  160. data/spec/support/schemas/mysql_schema.rb +26 -0
  161. data/spec/support/schemas/oracle_schema.rb +20 -0
  162. data/spec/support/schemas/postgresql_schema.rb +26 -0
  163. data/spec/support/schemas/sqlite3_schema.rb +26 -0
  164. metadata +258 -0
@@ -0,0 +1,221 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Join do
5
+ before do
6
+ @relation1 = Table(:users)
7
+ @relation2 = Table(:photos)
8
+ @predicate = @relation1[:id].eq(@relation2[:user_id])
9
+ end
10
+
11
+ describe 'when joining aggregated relations' do
12
+ before do
13
+ @aggregation = @relation2 \
14
+ .group(@relation2[:user_id]) \
15
+ .project(@relation2[:user_id], @relation2[:id].count.as(:cnt)) \
16
+ end
17
+
18
+ describe '#to_sql' do
19
+ # CLEANUP
20
+ it '' do
21
+ sql = @relation1.join(@relation2.take(3)).on(@predicate).to_sql
22
+
23
+ adapter_is :mysql do
24
+ sql.should be_like(%Q{
25
+ SELECT `users`.`id`, `users`.`name`, `photos_external`.`id`, `photos_external`.`user_id`, `photos_external`.`camera_id`
26
+ FROM `users`
27
+ INNER JOIN (SELECT `photos`.`id`, `photos`.`user_id`, `photos`.`camera_id` FROM `photos` LIMIT 3) `photos_external`
28
+ ON `users`.`id` = `photos_external`.`user_id`
29
+ })
30
+ end
31
+
32
+ adapter_is :oracle do
33
+ sql.should be_like(%Q{
34
+ SELECT "USERS"."ID", "USERS"."NAME", "PHOTOS_EXTERNAL"."ID", "PHOTOS_EXTERNAL"."USER_ID", "PHOTOS_EXTERNAL"."CAMERA_ID"
35
+ FROM "USERS"
36
+ INNER JOIN (SELECT "PHOTOS"."ID", "PHOTOS"."USER_ID", "PHOTOS"."CAMERA_ID" FROM "PHOTOS" WHERE ROWNUM <= 3) "PHOTOS_EXTERNAL"
37
+ ON "USERS"."ID" = "PHOTOS_EXTERNAL"."USER_ID"
38
+ })
39
+ end
40
+
41
+ adapter_is_not :mysql, :oracle do
42
+ sql.should be_like(%Q{
43
+ SELECT "users"."id", "users"."name", "photos_external"."id", "photos_external"."user_id", "photos_external"."camera_id"
44
+ FROM "users"
45
+ INNER JOIN (SELECT "photos"."id", "photos"."user_id", "photos"."camera_id" FROM "photos" LIMIT 3) "photos_external"
46
+ ON "users"."id" = "photos_external"."user_id"
47
+ })
48
+ end
49
+ end
50
+
51
+ describe 'with the aggregation on the right' do
52
+ it 'manufactures sql joining the left table to a derived table' do
53
+ sql = @relation1.join(@aggregation).on(@predicate).to_sql
54
+
55
+ adapter_is :mysql do
56
+ sql.should be_like(%Q{
57
+ SELECT `users`.`id`, `users`.`name`, `photos_external`.`user_id`, `photos_external`.`cnt`
58
+ FROM `users`
59
+ INNER JOIN (SELECT `photos`.`user_id`, COUNT(`photos`.`id`) AS `cnt` FROM `photos` GROUP BY `photos`.`user_id`) `photos_external`
60
+ ON `users`.`id` = `photos_external`.`user_id`
61
+ })
62
+ end
63
+
64
+ adapter_is :oracle do
65
+ sql.should be_like(%Q{
66
+ SELECT "USERS"."ID", "USERS"."NAME", "PHOTOS_EXTERNAL"."USER_ID", "PHOTOS_EXTERNAL"."CNT"
67
+ FROM "USERS"
68
+ INNER JOIN (SELECT "PHOTOS"."USER_ID", COUNT("PHOTOS"."ID") AS "CNT" FROM "PHOTOS" GROUP BY "PHOTOS"."USER_ID") "PHOTOS_EXTERNAL"
69
+ ON "USERS"."ID" = "PHOTOS_EXTERNAL"."USER_ID"
70
+ })
71
+ end
72
+
73
+ adapter_is_not :mysql, :oracle do
74
+ sql.should be_like(%Q{
75
+ SELECT "users"."id", "users"."name", "photos_external"."user_id", "photos_external"."cnt"
76
+ FROM "users"
77
+ INNER JOIN (SELECT "photos"."user_id", COUNT("photos"."id") AS "cnt" FROM "photos" GROUP BY "photos"."user_id") "photos_external"
78
+ ON "users"."id" = "photos_external"."user_id"
79
+ })
80
+ end
81
+ end
82
+ end
83
+
84
+ describe 'with the aggregation on the left' do
85
+ it 'manufactures sql joining the right table to a derived table' do
86
+ sql = @aggregation.join(@relation1).on(@predicate).to_sql
87
+
88
+ adapter_is :mysql do
89
+ sql.should be_like(%Q{
90
+ SELECT `photos_external`.`user_id`, `photos_external`.`cnt`, `users`.`id`, `users`.`name`
91
+ FROM (SELECT `photos`.`user_id`, COUNT(`photos`.`id`) AS `cnt` FROM `photos` GROUP BY `photos`.`user_id`) `photos_external`
92
+ INNER JOIN `users`
93
+ ON `users`.`id` = `photos_external`.`user_id`
94
+ })
95
+ end
96
+
97
+ adapter_is :oracle do
98
+ sql.should be_like(%Q{
99
+ SELECT "PHOTOS_EXTERNAL"."USER_ID", "PHOTOS_EXTERNAL"."CNT", "USERS"."ID", "USERS"."NAME"
100
+ FROM (SELECT "PHOTOS"."USER_ID", COUNT("PHOTOS"."ID") AS "CNT" FROM "PHOTOS" GROUP BY "PHOTOS"."USER_ID") "PHOTOS_EXTERNAL"
101
+ INNER JOIN "USERS"
102
+ ON "USERS"."ID" = "PHOTOS_EXTERNAL"."USER_ID"
103
+ })
104
+ end
105
+
106
+ adapter_is_not :mysql, :oracle do
107
+ sql.should be_like(%Q{
108
+ SELECT "photos_external"."user_id", "photos_external"."cnt", "users"."id", "users"."name"
109
+ FROM (SELECT "photos"."user_id", COUNT("photos"."id") AS "cnt" FROM "photos" GROUP BY "photos"."user_id") "photos_external"
110
+ INNER JOIN "users"
111
+ ON "users"."id" = "photos_external"."user_id"
112
+ })
113
+ end
114
+ end
115
+ end
116
+
117
+ describe 'with the aggregation on both sides' do
118
+ it 'it properly aliases the aggregations' do
119
+ aggregation2 = @aggregation.alias
120
+ sql = @aggregation.join(aggregation2).on(aggregation2[:user_id].eq(@aggregation[:user_id])).to_sql
121
+
122
+ adapter_is :mysql do
123
+ sql.should be_like(%Q{
124
+ SELECT `photos_external`.`user_id`, `photos_external`.`cnt`, `photos_external_2`.`user_id`, `photos_external_2`.`cnt`
125
+ FROM (SELECT `photos`.`user_id`, COUNT(`photos`.`id`) AS `cnt` FROM `photos` GROUP BY `photos`.`user_id`) `photos_external`
126
+ INNER JOIN (SELECT `photos`.`user_id`, COUNT(`photos`.`id`) AS `cnt` FROM `photos` GROUP BY `photos`.`user_id`) `photos_external_2`
127
+ ON `photos_external_2`.`user_id` = `photos_external`.`user_id`
128
+ })
129
+ end
130
+
131
+ adapter_is :oracle do
132
+ sql.should be_like(%Q{
133
+ SELECT "PHOTOS_EXTERNAL"."USER_ID", "PHOTOS_EXTERNAL"."CNT", "PHOTOS_EXTERNAL_2"."USER_ID", "PHOTOS_EXTERNAL_2"."CNT"
134
+ FROM (SELECT "PHOTOS"."USER_ID", COUNT("PHOTOS"."ID") AS "CNT" FROM "PHOTOS" GROUP BY "PHOTOS"."USER_ID") "PHOTOS_EXTERNAL"
135
+ INNER JOIN (SELECT "PHOTOS"."USER_ID", COUNT("PHOTOS"."ID") AS "CNT" FROM "PHOTOS" GROUP BY "PHOTOS"."USER_ID") "PHOTOS_EXTERNAL_2"
136
+ ON "PHOTOS_EXTERNAL_2"."USER_ID" = "PHOTOS_EXTERNAL"."USER_ID"
137
+ })
138
+ end
139
+
140
+ adapter_is_not :mysql, :oracle do
141
+ sql.should be_like(%Q{
142
+ SELECT "photos_external"."user_id", "photos_external"."cnt", "photos_external_2"."user_id", "photos_external_2"."cnt"
143
+ FROM (SELECT "photos"."user_id", COUNT("photos"."id") AS "cnt" FROM "photos" GROUP BY "photos"."user_id") "photos_external"
144
+ INNER JOIN (SELECT "photos"."user_id", COUNT("photos"."id") AS "cnt" FROM "photos" GROUP BY "photos"."user_id") "photos_external_2"
145
+ ON "photos_external_2"."user_id" = "photos_external"."user_id"
146
+ })
147
+ end
148
+ end
149
+ end
150
+
151
+ describe 'when the aggration has a where' do
152
+ describe 'with the aggregation on the left' do
153
+ it "manufactures sql keeping wheres on the aggregation within the derived table" do
154
+ sql = @relation1.join(@aggregation.where(@aggregation[:user_id].eq(1))).on(@predicate).to_sql
155
+
156
+ adapter_is :mysql do
157
+ sql.should be_like(%Q{
158
+ SELECT `users`.`id`, `users`.`name`, `photos_external`.`user_id`, `photos_external`.`cnt`
159
+ FROM `users`
160
+ INNER JOIN (SELECT `photos`.`user_id`, COUNT(`photos`.`id`) AS `cnt` FROM `photos` WHERE `photos`.`user_id` = 1 GROUP BY `photos`.`user_id`) `photos_external`
161
+ ON `users`.`id` = `photos_external`.`user_id`
162
+ })
163
+ end
164
+
165
+ adapter_is :oracle do
166
+ sql.should be_like(%Q{
167
+ SELECT "USERS"."ID", "USERS"."NAME", "PHOTOS_EXTERNAL"."USER_ID", "PHOTOS_EXTERNAL"."CNT"
168
+ FROM "USERS"
169
+ INNER JOIN (SELECT "PHOTOS"."USER_ID", COUNT("PHOTOS"."ID") AS "CNT" FROM "PHOTOS" WHERE "PHOTOS"."USER_ID" = 1 GROUP BY "PHOTOS"."USER_ID") "PHOTOS_EXTERNAL"
170
+ ON "USERS"."ID" = "PHOTOS_EXTERNAL"."USER_ID"
171
+ })
172
+ end
173
+
174
+ adapter_is_not :mysql, :oracle do
175
+ sql.should be_like(%Q{
176
+ SELECT "users"."id", "users"."name", "photos_external"."user_id", "photos_external"."cnt"
177
+ FROM "users"
178
+ INNER JOIN (SELECT "photos"."user_id", COUNT("photos"."id") AS "cnt" FROM "photos" WHERE "photos"."user_id" = 1 GROUP BY "photos"."user_id") "photos_external"
179
+ ON "users"."id" = "photos_external"."user_id"
180
+ })
181
+ end
182
+ end
183
+ end
184
+
185
+ describe 'with the aggregation on the right' do
186
+ it "manufactures sql keeping wheres on the aggregation within the derived table" do
187
+ sql = @aggregation.where(@aggregation[:user_id].eq(1)).join(@relation1).on(@predicate).to_sql
188
+
189
+ adapter_is :mysql do
190
+ sql.should be_like(%Q{
191
+ SELECT `photos_external`.`user_id`, `photos_external`.`cnt`, `users`.`id`, `users`.`name`
192
+ FROM (SELECT `photos`.`user_id`, COUNT(`photos`.`id`) AS `cnt` FROM `photos` WHERE `photos`.`user_id` = 1 GROUP BY `photos`.`user_id`) `photos_external`
193
+ INNER JOIN `users`
194
+ ON `users`.`id` = `photos_external`.`user_id`
195
+ })
196
+ end
197
+
198
+ adapter_is :oracle do
199
+ sql.should be_like(%Q{
200
+ SELECT "PHOTOS_EXTERNAL"."USER_ID", "PHOTOS_EXTERNAL"."CNT", "USERS"."ID", "USERS"."NAME"
201
+ FROM (SELECT "PHOTOS"."USER_ID", COUNT("PHOTOS"."ID") AS "CNT" FROM "PHOTOS" WHERE "PHOTOS"."USER_ID" = 1 GROUP BY "PHOTOS"."USER_ID") "PHOTOS_EXTERNAL"
202
+ INNER JOIN "USERS"
203
+ ON "USERS"."ID" = "PHOTOS_EXTERNAL"."USER_ID"
204
+ })
205
+ end
206
+
207
+ adapter_is_not :mysql, :oracle do
208
+ sql.should be_like(%Q{
209
+ SELECT "photos_external"."user_id", "photos_external"."cnt", "users"."id", "users"."name"
210
+ FROM (SELECT "photos"."user_id", COUNT("photos"."id") AS "cnt" FROM "photos" WHERE "photos"."user_id" = 1 GROUP BY "photos"."user_id") "photos_external"
211
+ INNER JOIN "users"
212
+ ON "users"."id" = "photos_external"."user_id"
213
+ })
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,137 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Join do
5
+ before do
6
+ @relation1 = Table(:users)
7
+ @relation2 = Table(:photos)
8
+ @predicate = @relation1[:id].eq(@relation2[:user_id])
9
+ end
10
+
11
+ describe '#to_sql' do
12
+ describe 'when the join contains a where' do
13
+ describe 'and the where is given a string' do
14
+ it 'does not escape the string' do
15
+ sql = @relation1 \
16
+ .join(@relation2.where("asdf")) \
17
+ .on(@predicate) \
18
+ .to_sql
19
+
20
+ adapter_is :mysql do
21
+ sql.should be_like(%Q{
22
+ SELECT `users`.`id`, `users`.`name`, `photos`.`id`, `photos`.`user_id`, `photos`.`camera_id`
23
+ FROM `users`
24
+ INNER JOIN `photos`
25
+ ON `users`.`id` = `photos`.`user_id` AND asdf
26
+ })
27
+ end
28
+
29
+ adapter_is :oracle do
30
+ sql.should be_like(%Q{
31
+ SELECT "USERS"."ID", "USERS"."NAME", "PHOTOS"."ID", "PHOTOS"."USER_ID", "PHOTOS"."CAMERA_ID"
32
+ FROM "USERS"
33
+ INNER JOIN "PHOTOS"
34
+ ON "USERS"."ID" = "PHOTOS"."USER_ID" AND asdf
35
+ })
36
+ end
37
+
38
+ adapter_is_not :mysql, :oracle do
39
+ sql.should be_like(%Q{
40
+ SELECT "users"."id", "users"."name", "photos"."id", "photos"."user_id", "photos"."camera_id"
41
+ FROM "users"
42
+ INNER JOIN "photos"
43
+ ON "users"."id" = "photos"."user_id" AND asdf
44
+ })
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ describe 'when a compound contains a join' do
51
+ describe 'and the compound is a where' do
52
+ it 'manufactures sql disambiguating the tables' do
53
+ sql = @relation1 \
54
+ .where(@relation1[:id].eq(1)) \
55
+ .join(@relation2) \
56
+ .on(@predicate) \
57
+ .where(@relation1[:id].eq(1)) \
58
+ .to_sql
59
+
60
+ adapter_is :mysql do
61
+ sql.should be_like(%Q{
62
+ SELECT `users`.`id`, `users`.`name`, `photos`.`id`, `photos`.`user_id`, `photos`.`camera_id`
63
+ FROM `users`
64
+ INNER JOIN `photos`
65
+ ON `users`.`id` = `photos`.`user_id`
66
+ WHERE `users`.`id` = 1
67
+ AND `users`.`id` = 1
68
+ })
69
+ end
70
+
71
+ adapter_is :oracle do
72
+ sql.should be_like(%Q{
73
+ SELECT "USERS"."ID", "USERS"."NAME", "PHOTOS"."ID", "PHOTOS"."USER_ID", "PHOTOS"."CAMERA_ID"
74
+ FROM "USERS"
75
+ INNER JOIN "PHOTOS"
76
+ ON "USERS"."ID" = "PHOTOS"."USER_ID"
77
+ WHERE "USERS"."ID" = 1
78
+ AND "USERS"."ID" = 1
79
+ })
80
+ end
81
+
82
+ adapter_is_not :mysql, :oracle do
83
+ sql.should be_like(%Q{
84
+ SELECT "users"."id", "users"."name", "photos"."id", "photos"."user_id", "photos"."camera_id"
85
+ FROM "users"
86
+ INNER JOIN "photos"
87
+ ON "users"."id" = "photos"."user_id"
88
+ WHERE "users"."id" = 1
89
+ AND "users"."id" = 1
90
+ })
91
+ end
92
+ end
93
+ end
94
+
95
+ describe 'and the compound is a group' do
96
+ it 'manufactures sql disambiguating the tables' do
97
+ sql = @relation1 \
98
+ .join(@relation2) \
99
+ .on(@predicate) \
100
+ .group(@relation1[:id]) \
101
+ .to_sql
102
+
103
+ adapter_is :mysql do
104
+ sql.should be_like(%Q{
105
+ SELECT `users`.`id`, `users`.`name`, `photos`.`id`, `photos`.`user_id`, `photos`.`camera_id`
106
+ FROM `users`
107
+ INNER JOIN `photos`
108
+ ON `users`.`id` = `photos`.`user_id`
109
+ GROUP BY `users`.`id`
110
+ })
111
+ end
112
+
113
+ adapter_is :oracle do
114
+ sql.should be_like(%Q{
115
+ SELECT "USERS"."ID", "USERS"."NAME", "PHOTOS"."ID", "PHOTOS"."USER_ID", "PHOTOS"."CAMERA_ID"
116
+ FROM "USERS"
117
+ INNER JOIN "PHOTOS"
118
+ ON "USERS"."ID" = "PHOTOS"."USER_ID"
119
+ GROUP BY "USERS"."ID"
120
+ })
121
+ end
122
+
123
+ adapter_is_not :mysql, :oracle do
124
+ sql.should be_like(%Q{
125
+ SELECT "users"."id", "users"."name", "photos"."id", "photos"."user_id", "photos"."camera_id"
126
+ FROM "users"
127
+ INNER JOIN "photos"
128
+ ON "users"."id" = "photos"."user_id"
129
+ GROUP BY "users"."id"
130
+ })
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Sql::Engine do
5
+ before do
6
+ @users = Table.new(:users)
7
+ @users.delete
8
+ end
9
+
10
+ describe "CRUD" do
11
+ describe "#create" do
12
+ it "inserts into the relation" do
13
+ @users.insert @users[:name] => "Bryan"
14
+ @users.first[@users[:name]].should == "Bryan"
15
+ end
16
+ end
17
+
18
+ describe "#read" do
19
+ it "reads from the relation" do
20
+ @users.insert @users[:name] => "Bryan"
21
+
22
+ @users.each do |row|
23
+ row[@users[:name]].should == "Bryan"
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "#update" do
29
+ it "updates the relation" do
30
+ @users.insert @users[:name] => "Nick"
31
+ @users.update @users[:name] => "Bryan"
32
+ @users.first[@users[:name]].should == "Bryan"
33
+ end
34
+ end
35
+
36
+ describe "#delete" do
37
+ it "deletes from the relation" do
38
+ @users.insert @users[:name] => "Bryan"
39
+ @users.delete
40
+ @users.first.should == nil
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,140 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ module Predicates
5
+ describe Binary do
6
+ class ConcreteBinary < Binary
7
+ def predicate_sql
8
+ "<=>"
9
+ end
10
+ end
11
+
12
+ before do
13
+ @relation = Arel::Table.new(:users)
14
+ @attribute1 = @relation[:id]
15
+ @attribute2 = @relation[:name]
16
+ end
17
+
18
+ describe "with compound predicates" do
19
+ before do
20
+ @operand1 = ConcreteBinary.new(@attribute1, 1)
21
+ @operand2 = ConcreteBinary.new(@attribute2, "name")
22
+ end
23
+
24
+ describe Or do
25
+ describe "#to_sql" do
26
+ it "manufactures sql with an OR operation" do
27
+ sql = Or.new(@operand1, @operand2).to_sql
28
+
29
+ adapter_is :mysql do
30
+ sql.should be_like(%Q{(`users`.`id` <=> 1 OR `users`.`name` <=> 'name')})
31
+ end
32
+
33
+ adapter_is :postgresql do
34
+ sql.should be_like(%Q{("users"."id" <=> 1 OR "users"."name" <=> E'name')})
35
+ end
36
+
37
+ adapter_is :sqlite3 do
38
+ sql.should be_like(%Q{("users"."id" <=> 1 OR "users"."name" <=> 'name')})
39
+ end
40
+
41
+ adapter_is :oracle do
42
+ sql.should be_like(%Q{("USERS"."ID" <=> 1 OR "USERS"."NAME" <=> 'name')})
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ describe And do
49
+ describe "#to_sql" do
50
+ it "manufactures sql with an AND operation" do
51
+ sql = And.new(@operand1, @operand2).to_sql
52
+
53
+ adapter_is :mysql do
54
+ sql.should be_like(%Q{(`users`.`id` <=> 1 AND `users`.`name` <=> 'name')})
55
+ end
56
+
57
+ adapter_is :sqlite3 do
58
+ sql.should be_like(%Q{("users"."id" <=> 1 AND "users"."name" <=> 'name')})
59
+ end
60
+
61
+ adapter_is :postgresql do
62
+ sql.should be_like(%Q{("users"."id" <=> 1 AND "users"."name" <=> E'name')})
63
+ end
64
+
65
+ adapter_is :oracle do
66
+ sql.should be_like(%Q{("USERS"."ID" <=> 1 AND "USERS"."NAME" <=> 'name')})
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ describe '#to_sql' do
74
+ describe 'when relating two attributes' do
75
+ it 'manufactures sql with a binary operation' do
76
+ sql = ConcreteBinary.new(@attribute1, @attribute2).to_sql
77
+
78
+ adapter_is :mysql do
79
+ sql.should be_like(%Q{`users`.`id` <=> `users`.`name`})
80
+ end
81
+
82
+ adapter_is :oracle do
83
+ sql.should be_like(%Q{"USERS"."ID" <=> "USERS"."NAME"})
84
+ end
85
+
86
+ adapter_is_not :mysql, :oracle do
87
+ sql.should be_like(%Q{"users"."id" <=> "users"."name"})
88
+ end
89
+ end
90
+ end
91
+
92
+ describe 'when relating an attribute and a value' do
93
+ before do
94
+ @value = "1-asdf"
95
+ end
96
+
97
+ describe 'when relating to an integer attribute' do
98
+ it 'formats values as integers' do
99
+ sql = ConcreteBinary.new(@attribute1, @value).to_sql
100
+
101
+ adapter_is :mysql do
102
+ sql.should be_like(%Q{`users`.`id` <=> 1})
103
+ end
104
+
105
+ adapter_is :oracle do
106
+ sql.should be_like(%Q{"USERS"."ID" <=> 1})
107
+ end
108
+
109
+ adapter_is_not :mysql, :oracle do
110
+ sql.should be_like(%Q{"users"."id" <=> 1})
111
+ end
112
+ end
113
+ end
114
+
115
+ describe 'when relating to a string attribute' do
116
+ it 'formats values as strings' do
117
+ sql = ConcreteBinary.new(@attribute2, @value).to_sql
118
+
119
+ adapter_is :mysql do
120
+ sql.should be_like(%Q{`users`.`name` <=> '1-asdf'})
121
+ end
122
+
123
+ adapter_is :sqlite3 do
124
+ sql.should be_like(%Q{"users"."name" <=> '1-asdf'})
125
+ end
126
+
127
+ adapter_is :postgresql do
128
+ sql.should be_like(%Q{"users"."name" <=> E'1-asdf'})
129
+ end
130
+
131
+ adapter_is :oracle do
132
+ sql.should be_like(%Q{"USERS"."NAME" <=> '1-asdf'})
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end