arel 1.0.1 → 2.0.0

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 (247) hide show
  1. data/MIT-LICENSE.txt +20 -0
  2. data/Manifest.txt +105 -0
  3. data/README.markdown +12 -32
  4. data/Rakefile +17 -0
  5. data/arel.gemspec +39 -0
  6. data/lib/arel.rb +30 -9
  7. data/lib/arel/attributes.rb +20 -0
  8. data/lib/arel/attributes/attribute.rb +190 -0
  9. data/lib/arel/compatibility/wheres.rb +33 -0
  10. data/lib/arel/crud.rb +37 -0
  11. data/lib/arel/delete_manager.rb +22 -0
  12. data/lib/arel/deprecated.rb +4 -0
  13. data/lib/arel/expression.rb +4 -0
  14. data/lib/arel/expressions.rb +23 -0
  15. data/lib/arel/insert_manager.rb +34 -0
  16. data/lib/arel/nodes.rb +44 -0
  17. data/lib/arel/nodes/and.rb +6 -0
  18. data/lib/arel/nodes/assignment.rb +6 -0
  19. data/lib/arel/nodes/avg.rb +6 -0
  20. data/lib/arel/nodes/between.rb +6 -0
  21. data/lib/arel/nodes/binary.rb +12 -0
  22. data/lib/arel/nodes/count.rb +13 -0
  23. data/lib/arel/nodes/delete_statement.rb +17 -0
  24. data/lib/arel/nodes/does_not_match.rb +6 -0
  25. data/lib/arel/nodes/equality.rb +9 -0
  26. data/lib/arel/nodes/exists.rb +11 -0
  27. data/lib/arel/nodes/function.rb +18 -0
  28. data/lib/arel/nodes/greater_than.rb +6 -0
  29. data/lib/arel/nodes/greater_than_or_equal.rb +6 -0
  30. data/lib/arel/nodes/group.rb +11 -0
  31. data/lib/arel/nodes/grouping.rb +11 -0
  32. data/lib/arel/nodes/having.rb +11 -0
  33. data/lib/arel/nodes/in.rb +6 -0
  34. data/lib/arel/nodes/inner_join.rb +6 -0
  35. data/lib/arel/nodes/insert_statement.rb +19 -0
  36. data/lib/arel/nodes/join.rb +13 -0
  37. data/lib/arel/nodes/less_than.rb +6 -0
  38. data/lib/arel/nodes/less_than_or_equal.rb +6 -0
  39. data/lib/arel/nodes/lock.rb +6 -0
  40. data/lib/arel/nodes/matches.rb +6 -0
  41. data/lib/arel/nodes/max.rb +6 -0
  42. data/lib/arel/nodes/min.rb +6 -0
  43. data/lib/arel/nodes/node.rb +30 -0
  44. data/lib/arel/nodes/not_equal.rb +6 -0
  45. data/lib/arel/nodes/not_in.rb +6 -0
  46. data/lib/arel/nodes/offset.rb +11 -0
  47. data/lib/arel/nodes/on.rb +11 -0
  48. data/lib/arel/nodes/or.rb +6 -0
  49. data/lib/arel/nodes/ordering.rb +19 -0
  50. data/lib/arel/nodes/outer_join.rb +6 -0
  51. data/lib/arel/nodes/select_core.rb +25 -0
  52. data/lib/arel/nodes/select_statement.rb +22 -0
  53. data/lib/arel/nodes/sql_literal.rb +7 -0
  54. data/lib/arel/nodes/string_join.rb +11 -0
  55. data/lib/arel/nodes/sum.rb +6 -0
  56. data/lib/arel/nodes/table_alias.rb +21 -0
  57. data/lib/arel/nodes/unqualified_column.rb +19 -0
  58. data/lib/arel/nodes/update_statement.rb +21 -0
  59. data/lib/arel/nodes/values.rb +12 -0
  60. data/lib/arel/relation.rb +6 -0
  61. data/lib/arel/select_manager.rb +203 -0
  62. data/lib/arel/sql/engine.rb +10 -0
  63. data/lib/arel/sql_literal.rb +1 -10
  64. data/lib/arel/table.rb +126 -0
  65. data/lib/arel/tree_manager.rb +26 -0
  66. data/lib/arel/update_manager.rb +48 -0
  67. data/lib/arel/visitors.rb +30 -0
  68. data/lib/arel/visitors/dot.rb +233 -0
  69. data/lib/arel/visitors/join_sql.rb +38 -0
  70. data/lib/arel/visitors/mysql.rb +16 -0
  71. data/lib/arel/visitors/oracle.rb +69 -0
  72. data/lib/arel/visitors/order_clauses.rb +9 -0
  73. data/lib/arel/visitors/postgresql.rb +54 -0
  74. data/lib/arel/visitors/to_sql.rb +301 -0
  75. data/lib/arel/visitors/where_sql.rb +9 -0
  76. data/spec/activerecord_compat_spec.rb +18 -0
  77. data/spec/attributes/attribute_spec.rb +648 -0
  78. data/spec/attributes_spec.rb +33 -6
  79. data/spec/crud_spec.rb +69 -0
  80. data/spec/delete_manager_spec.rb +53 -0
  81. data/spec/insert_manager_spec.rb +141 -0
  82. data/spec/nodes/count_spec.rb +18 -0
  83. data/spec/nodes/delete_statement_spec.rb +15 -0
  84. data/spec/nodes/equality_spec.rb +72 -0
  85. data/spec/nodes/insert_statement_spec.rb +18 -0
  86. data/spec/nodes/or_spec.rb +20 -0
  87. data/spec/nodes/select_core_spec.rb +21 -0
  88. data/spec/nodes/select_statement_spec.rb +14 -0
  89. data/spec/nodes/sql_literal_spec.rb +26 -0
  90. data/spec/nodes/sum_spec.rb +12 -0
  91. data/spec/nodes/update_statement_spec.rb +18 -0
  92. data/spec/select_manager_spec.rb +581 -0
  93. data/spec/spec.opts +3 -0
  94. data/spec/spec_helper.rb +6 -21
  95. data/spec/support/fake_record.rb +89 -0
  96. data/spec/support/shared/tree_manager_shared.rb +9 -0
  97. data/spec/table_spec.rb +176 -0
  98. data/spec/update_manager_spec.rb +89 -0
  99. data/spec/visitors/join_sql_spec.rb +35 -0
  100. data/spec/visitors/oracle_spec.rb +111 -0
  101. data/spec/visitors/to_sql_spec.rb +134 -0
  102. metadata +160 -260
  103. data/lib/arel/algebra.rb +0 -10
  104. data/lib/arel/algebra/attributes.rb +0 -7
  105. data/lib/arel/algebra/attributes/attribute.rb +0 -304
  106. data/lib/arel/algebra/attributes/boolean.rb +0 -21
  107. data/lib/arel/algebra/attributes/decimal.rb +0 -9
  108. data/lib/arel/algebra/attributes/float.rb +0 -9
  109. data/lib/arel/algebra/attributes/integer.rb +0 -10
  110. data/lib/arel/algebra/attributes/string.rb +0 -10
  111. data/lib/arel/algebra/attributes/time.rb +0 -6
  112. data/lib/arel/algebra/core_extensions.rb +0 -3
  113. data/lib/arel/algebra/core_extensions/hash.rb +0 -7
  114. data/lib/arel/algebra/core_extensions/object.rb +0 -13
  115. data/lib/arel/algebra/core_extensions/symbol.rb +0 -9
  116. data/lib/arel/algebra/expression.rb +0 -56
  117. data/lib/arel/algebra/header.rb +0 -66
  118. data/lib/arel/algebra/ordering.rb +0 -31
  119. data/lib/arel/algebra/predicates.rb +0 -306
  120. data/lib/arel/algebra/relations.rb +0 -16
  121. data/lib/arel/algebra/relations/operations/from.rb +0 -14
  122. data/lib/arel/algebra/relations/operations/group.rb +0 -14
  123. data/lib/arel/algebra/relations/operations/having.rb +0 -14
  124. data/lib/arel/algebra/relations/operations/join.rb +0 -103
  125. data/lib/arel/algebra/relations/operations/lock.rb +0 -10
  126. data/lib/arel/algebra/relations/operations/order.rb +0 -23
  127. data/lib/arel/algebra/relations/operations/project.rb +0 -20
  128. data/lib/arel/algebra/relations/operations/skip.rb +0 -14
  129. data/lib/arel/algebra/relations/operations/take.rb +0 -18
  130. data/lib/arel/algebra/relations/operations/where.rb +0 -24
  131. data/lib/arel/algebra/relations/relation.rb +0 -205
  132. data/lib/arel/algebra/relations/row.rb +0 -29
  133. data/lib/arel/algebra/relations/utilities/compound.rb +0 -55
  134. data/lib/arel/algebra/relations/utilities/externalization.rb +0 -26
  135. data/lib/arel/algebra/relations/utilities/nil.rb +0 -7
  136. data/lib/arel/algebra/relations/writes.rb +0 -47
  137. data/lib/arel/algebra/value.rb +0 -53
  138. data/lib/arel/engines.rb +0 -2
  139. data/lib/arel/engines/memory.rb +0 -2
  140. data/lib/arel/engines/memory/engine.rb +0 -10
  141. data/lib/arel/engines/memory/relations.rb +0 -2
  142. data/lib/arel/engines/memory/relations/array.rb +0 -37
  143. data/lib/arel/engines/memory/relations/operations.rb +0 -9
  144. data/lib/arel/engines/sql.rb +0 -6
  145. data/lib/arel/engines/sql/attributes.rb +0 -45
  146. data/lib/arel/engines/sql/christener.rb +0 -20
  147. data/lib/arel/engines/sql/compilers/ibm_db_compiler.rb +0 -48
  148. data/lib/arel/engines/sql/compilers/mysql_compiler.rb +0 -11
  149. data/lib/arel/engines/sql/compilers/oracle_compiler.rb +0 -106
  150. data/lib/arel/engines/sql/compilers/postgresql_compiler.rb +0 -50
  151. data/lib/arel/engines/sql/compilers/sqlite_compiler.rb +0 -9
  152. data/lib/arel/engines/sql/core_extensions.rb +0 -4
  153. data/lib/arel/engines/sql/core_extensions/array.rb +0 -24
  154. data/lib/arel/engines/sql/core_extensions/nil_class.rb +0 -15
  155. data/lib/arel/engines/sql/core_extensions/object.rb +0 -19
  156. data/lib/arel/engines/sql/core_extensions/range.rb +0 -19
  157. data/lib/arel/engines/sql/engine.rb +0 -47
  158. data/lib/arel/engines/sql/formatters.rb +0 -138
  159. data/lib/arel/engines/sql/relations.rb +0 -3
  160. data/lib/arel/engines/sql/relations/compiler.rb +0 -153
  161. data/lib/arel/engines/sql/relations/table.rb +0 -100
  162. data/lib/arel/engines/sql/relations/utilities/nil.rb +0 -6
  163. data/lib/arel/recursion/base_case.rb +0 -13
  164. data/lib/arel/session.rb +0 -35
  165. data/lib/arel/version.rb +0 -3
  166. data/spec/algebra/unit/predicates/binary_spec.rb +0 -35
  167. data/spec/algebra/unit/predicates/equality_spec.rb +0 -29
  168. data/spec/algebra/unit/predicates/in_spec.rb +0 -12
  169. data/spec/algebra/unit/predicates/inequality_spec.rb +0 -32
  170. data/spec/algebra/unit/predicates/predicate_spec.rb +0 -22
  171. data/spec/algebra/unit/primitives/attribute_spec.rb +0 -175
  172. data/spec/algebra/unit/primitives/expression_spec.rb +0 -39
  173. data/spec/algebra/unit/primitives/value_spec.rb +0 -15
  174. data/spec/algebra/unit/relations/alias_spec.rb +0 -16
  175. data/spec/algebra/unit/relations/delete_spec.rb +0 -9
  176. data/spec/algebra/unit/relations/group_spec.rb +0 -10
  177. data/spec/algebra/unit/relations/insert_spec.rb +0 -9
  178. data/spec/algebra/unit/relations/join_spec.rb +0 -18
  179. data/spec/algebra/unit/relations/order_spec.rb +0 -21
  180. data/spec/algebra/unit/relations/project_spec.rb +0 -34
  181. data/spec/algebra/unit/relations/relation_spec.rb +0 -241
  182. data/spec/algebra/unit/relations/skip_spec.rb +0 -10
  183. data/spec/algebra/unit/relations/table_spec.rb +0 -38
  184. data/spec/algebra/unit/relations/take_spec.rb +0 -10
  185. data/spec/algebra/unit/relations/update_spec.rb +0 -9
  186. data/spec/algebra/unit/relations/where_spec.rb +0 -19
  187. data/spec/algebra/unit/session/session_spec.rb +0 -84
  188. data/spec/attributes/boolean_spec.rb +0 -57
  189. data/spec/attributes/float_spec.rb +0 -119
  190. data/spec/attributes/header_spec.rb +0 -42
  191. data/spec/attributes/integer_spec.rb +0 -119
  192. data/spec/attributes/string_spec.rb +0 -43
  193. data/spec/attributes/time_spec.rb +0 -24
  194. data/spec/engines/memory/integration/joins/cross_engine_spec.rb +0 -61
  195. data/spec/engines/memory/unit/relations/array_spec.rb +0 -33
  196. data/spec/engines/memory/unit/relations/insert_spec.rb +0 -28
  197. data/spec/engines/memory/unit/relations/join_spec.rb +0 -32
  198. data/spec/engines/memory/unit/relations/order_spec.rb +0 -28
  199. data/spec/engines/memory/unit/relations/project_spec.rb +0 -27
  200. data/spec/engines/memory/unit/relations/skip_spec.rb +0 -31
  201. data/spec/engines/memory/unit/relations/take_spec.rb +0 -28
  202. data/spec/engines/memory/unit/relations/where_spec.rb +0 -43
  203. data/spec/engines/sql/integration/joins/with_adjacency_spec.rb +0 -258
  204. data/spec/engines/sql/integration/joins/with_aggregations_spec.rb +0 -221
  205. data/spec/engines/sql/integration/joins/with_compounds_spec.rb +0 -137
  206. data/spec/engines/sql/unit/engine_spec.rb +0 -65
  207. data/spec/engines/sql/unit/predicates/binary_spec.rb +0 -140
  208. data/spec/engines/sql/unit/predicates/equality_spec.rb +0 -75
  209. data/spec/engines/sql/unit/predicates/in_spec.rb +0 -179
  210. data/spec/engines/sql/unit/predicates/noteq_spec.rb +0 -75
  211. data/spec/engines/sql/unit/predicates/predicates_spec.rb +0 -79
  212. data/spec/engines/sql/unit/primitives/attribute_spec.rb +0 -36
  213. data/spec/engines/sql/unit/primitives/expression_spec.rb +0 -28
  214. data/spec/engines/sql/unit/primitives/literal_spec.rb +0 -43
  215. data/spec/engines/sql/unit/primitives/value_spec.rb +0 -29
  216. data/spec/engines/sql/unit/relations/alias_spec.rb +0 -53
  217. data/spec/engines/sql/unit/relations/delete_spec.rb +0 -83
  218. data/spec/engines/sql/unit/relations/from_spec.rb +0 -64
  219. data/spec/engines/sql/unit/relations/group_spec.rb +0 -72
  220. data/spec/engines/sql/unit/relations/having_spec.rb +0 -78
  221. data/spec/engines/sql/unit/relations/insert_spec.rb +0 -143
  222. data/spec/engines/sql/unit/relations/join_spec.rb +0 -180
  223. data/spec/engines/sql/unit/relations/lock_spec.rb +0 -86
  224. data/spec/engines/sql/unit/relations/order_spec.rb +0 -161
  225. data/spec/engines/sql/unit/relations/project_spec.rb +0 -143
  226. data/spec/engines/sql/unit/relations/skip_spec.rb +0 -41
  227. data/spec/engines/sql/unit/relations/table_spec.rb +0 -122
  228. data/spec/engines/sql/unit/relations/take_spec.rb +0 -75
  229. data/spec/engines/sql/unit/relations/update_spec.rb +0 -203
  230. data/spec/engines/sql/unit/relations/where_spec.rb +0 -72
  231. data/spec/relations/join_spec.rb +0 -42
  232. data/spec/relations/relation_spec.rb +0 -31
  233. data/spec/shared/relation_spec.rb +0 -255
  234. data/spec/sql/christener_spec.rb +0 -70
  235. data/spec/support/connections/mysql_connection.rb +0 -14
  236. data/spec/support/connections/oracle_connection.rb +0 -17
  237. data/spec/support/connections/postgresql_connection.rb +0 -13
  238. data/spec/support/connections/sqlite3_connection.rb +0 -24
  239. data/spec/support/guards.rb +0 -28
  240. data/spec/support/matchers/disambiguate_attributes.rb +0 -28
  241. data/spec/support/matchers/hash_the_same_as.rb +0 -26
  242. data/spec/support/matchers/have_rows.rb +0 -18
  243. data/spec/support/model.rb +0 -67
  244. data/spec/support/schemas/mysql_schema.rb +0 -26
  245. data/spec/support/schemas/oracle_schema.rb +0 -20
  246. data/spec/support/schemas/postgresql_schema.rb +0 -26
  247. data/spec/support/schemas/sqlite3_schema.rb +0 -26
@@ -0,0 +1,9 @@
1
+ module Arel
2
+ module Visitors
3
+ class WhereSql < Arel::Visitors::ToSql
4
+ def visit_Arel_Nodes_SelectCore o
5
+ "WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe 'activerecord compatibility' do
5
+ describe 'select manager' do
6
+ it 'provides wheres' do
7
+ table = Table.new :users
8
+ manager = Arel::SelectManager.new Table.engine
9
+ manager.where table[:id].eq 1
10
+ manager.where table[:name].eq 'Aaron'
11
+
12
+ check manager.wheres.map { |x|
13
+ x.value
14
+ }.join(', ').should == "\"users\".\"id\" = 1, \"users\".\"name\" = 'Aaron'"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,648 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ module Attributes
5
+ describe 'attribute' do
6
+ describe '#not_eq' do
7
+ it 'should create a NotEqual node' do
8
+ relation = Table.new(:users)
9
+ relation[:id].not_eq(10).should be_kind_of Nodes::NotEqual
10
+ end
11
+
12
+ it 'should generate != in sql' do
13
+ relation = Table.new(:users)
14
+ mgr = relation.project relation[:id]
15
+ mgr.where relation[:id].not_eq(10)
16
+ mgr.to_sql.should be_like %{
17
+ SELECT "users"."id" FROM "users" WHERE "users"."id" != 10
18
+ }
19
+ end
20
+
21
+ it 'should handle nil' do
22
+ relation = Table.new(:users)
23
+ mgr = relation.project relation[:id]
24
+ mgr.where relation[:id].not_eq(nil)
25
+ mgr.to_sql.should be_like %{
26
+ SELECT "users"."id" FROM "users" WHERE "users"."id" IS NOT NULL
27
+ }
28
+ end
29
+ end
30
+
31
+ describe '#not_eq_any' do
32
+ it 'should create a Grouping node' do
33
+ relation = Table.new(:users)
34
+ relation[:id].not_eq_any([1,2]).should be_kind_of Nodes::Grouping
35
+ end
36
+
37
+ it 'should generate ORs in sql' do
38
+ relation = Table.new(:users)
39
+ mgr = relation.project relation[:id]
40
+ mgr.where relation[:id].not_eq_any([1,2])
41
+ mgr.to_sql.should be_like %{
42
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" != 1 OR "users"."id" != 2)
43
+ }
44
+ end
45
+ end
46
+
47
+ describe '#not_eq_all' do
48
+ it 'should create a Grouping node' do
49
+ relation = Table.new(:users)
50
+ relation[:id].not_eq_all([1,2]).should be_kind_of Nodes::Grouping
51
+ end
52
+
53
+ it 'should generate ANDs in sql' do
54
+ relation = Table.new(:users)
55
+ mgr = relation.project relation[:id]
56
+ mgr.where relation[:id].not_eq_all([1,2])
57
+ mgr.to_sql.should be_like %{
58
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" != 1 AND "users"."id" != 2)
59
+ }
60
+ end
61
+ end
62
+
63
+ describe '#gt' do
64
+ it 'should create a GreaterThan node' do
65
+ relation = Table.new(:users)
66
+ relation[:id].gt(10).should be_kind_of Nodes::GreaterThan
67
+ end
68
+
69
+ it 'should generate >= in sql' do
70
+ relation = Table.new(:users)
71
+ mgr = relation.project relation[:id]
72
+ mgr.where relation[:id].gt(10)
73
+ mgr.to_sql.should be_like %{
74
+ SELECT "users"."id" FROM "users" WHERE "users"."id" > 10
75
+ }
76
+ end
77
+ end
78
+
79
+ describe '#gt_any' do
80
+ it 'should create a Grouping node' do
81
+ relation = Table.new(:users)
82
+ relation[:id].gt_any([1,2]).should be_kind_of Nodes::Grouping
83
+ end
84
+
85
+ it 'should generate ORs in sql' do
86
+ relation = Table.new(:users)
87
+ mgr = relation.project relation[:id]
88
+ mgr.where relation[:id].gt_any([1,2])
89
+ mgr.to_sql.should be_like %{
90
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" > 1 OR "users"."id" > 2)
91
+ }
92
+ end
93
+ end
94
+
95
+ describe '#gt_all' do
96
+ it 'should create a Grouping node' do
97
+ relation = Table.new(:users)
98
+ relation[:id].gt_all([1,2]).should be_kind_of Nodes::Grouping
99
+ end
100
+
101
+ it 'should generate ANDs in sql' do
102
+ relation = Table.new(:users)
103
+ mgr = relation.project relation[:id]
104
+ mgr.where relation[:id].gt_all([1,2])
105
+ mgr.to_sql.should be_like %{
106
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" > 1 AND "users"."id" > 2)
107
+ }
108
+ end
109
+ end
110
+
111
+ describe '#gteq' do
112
+ it 'should create a GreaterThanOrEqual node' do
113
+ relation = Table.new(:users)
114
+ relation[:id].gteq(10).should be_kind_of Nodes::GreaterThanOrEqual
115
+ end
116
+
117
+ it 'should generate >= in sql' do
118
+ relation = Table.new(:users)
119
+ mgr = relation.project relation[:id]
120
+ mgr.where relation[:id].gteq(10)
121
+ mgr.to_sql.should be_like %{
122
+ SELECT "users"."id" FROM "users" WHERE "users"."id" >= 10
123
+ }
124
+ end
125
+ end
126
+
127
+ describe '#gteq_any' do
128
+ it 'should create a Grouping node' do
129
+ relation = Table.new(:users)
130
+ relation[:id].gteq_any([1,2]).should be_kind_of Nodes::Grouping
131
+ end
132
+
133
+ it 'should generate ORs in sql' do
134
+ relation = Table.new(:users)
135
+ mgr = relation.project relation[:id]
136
+ mgr.where relation[:id].gteq_any([1,2])
137
+ mgr.to_sql.should be_like %{
138
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" >= 1 OR "users"."id" >= 2)
139
+ }
140
+ end
141
+ end
142
+
143
+ describe '#gteq_all' do
144
+ it 'should create a Grouping node' do
145
+ relation = Table.new(:users)
146
+ relation[:id].gteq_all([1,2]).should be_kind_of Nodes::Grouping
147
+ end
148
+
149
+ it 'should generate ANDs in sql' do
150
+ relation = Table.new(:users)
151
+ mgr = relation.project relation[:id]
152
+ mgr.where relation[:id].gteq_all([1,2])
153
+ mgr.to_sql.should be_like %{
154
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" >= 1 AND "users"."id" >= 2)
155
+ }
156
+ end
157
+ end
158
+
159
+ describe '#lt' do
160
+ it 'should create a LessThan node' do
161
+ relation = Table.new(:users)
162
+ relation[:id].lt(10).should be_kind_of Nodes::LessThan
163
+ end
164
+
165
+ it 'should generate < in sql' do
166
+ relation = Table.new(:users)
167
+ mgr = relation.project relation[:id]
168
+ mgr.where relation[:id].lt(10)
169
+ mgr.to_sql.should be_like %{
170
+ SELECT "users"."id" FROM "users" WHERE "users"."id" < 10
171
+ }
172
+ end
173
+ end
174
+
175
+ describe '#lt_any' do
176
+ it 'should create a Grouping node' do
177
+ relation = Table.new(:users)
178
+ relation[:id].lt_any([1,2]).should be_kind_of Nodes::Grouping
179
+ end
180
+
181
+ it 'should generate ORs in sql' do
182
+ relation = Table.new(:users)
183
+ mgr = relation.project relation[:id]
184
+ mgr.where relation[:id].lt_any([1,2])
185
+ mgr.to_sql.should be_like %{
186
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" < 1 OR "users"."id" < 2)
187
+ }
188
+ end
189
+ end
190
+
191
+ describe '#lt_all' do
192
+ it 'should create a Grouping node' do
193
+ relation = Table.new(:users)
194
+ relation[:id].lt_all([1,2]).should be_kind_of Nodes::Grouping
195
+ end
196
+
197
+ it 'should generate ANDs in sql' do
198
+ relation = Table.new(:users)
199
+ mgr = relation.project relation[:id]
200
+ mgr.where relation[:id].lt_all([1,2])
201
+ mgr.to_sql.should be_like %{
202
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" < 1 AND "users"."id" < 2)
203
+ }
204
+ end
205
+ end
206
+
207
+ describe '#lteq' do
208
+ it 'should create a LessThanOrEqual node' do
209
+ relation = Table.new(:users)
210
+ relation[:id].lteq(10).should be_kind_of Nodes::LessThanOrEqual
211
+ end
212
+
213
+ it 'should generate <= in sql' do
214
+ relation = Table.new(:users)
215
+ mgr = relation.project relation[:id]
216
+ mgr.where relation[:id].lteq(10)
217
+ mgr.to_sql.should be_like %{
218
+ SELECT "users"."id" FROM "users" WHERE "users"."id" <= 10
219
+ }
220
+ end
221
+ end
222
+
223
+ describe '#lteq_any' do
224
+ it 'should create a Grouping node' do
225
+ relation = Table.new(:users)
226
+ relation[:id].lteq_any([1,2]).should be_kind_of Nodes::Grouping
227
+ end
228
+
229
+ it 'should generate ORs in sql' do
230
+ relation = Table.new(:users)
231
+ mgr = relation.project relation[:id]
232
+ mgr.where relation[:id].lteq_any([1,2])
233
+ mgr.to_sql.should be_like %{
234
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" <= 1 OR "users"."id" <= 2)
235
+ }
236
+ end
237
+ end
238
+
239
+ describe '#lteq_all' do
240
+ it 'should create a Grouping node' do
241
+ relation = Table.new(:users)
242
+ relation[:id].lteq_all([1,2]).should be_kind_of Nodes::Grouping
243
+ end
244
+
245
+ it 'should generate ANDs in sql' do
246
+ relation = Table.new(:users)
247
+ mgr = relation.project relation[:id]
248
+ mgr.where relation[:id].lteq_all([1,2])
249
+ mgr.to_sql.should be_like %{
250
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" <= 1 AND "users"."id" <= 2)
251
+ }
252
+ end
253
+ end
254
+
255
+ describe '#average' do
256
+ it 'should create a AVG node' do
257
+ relation = Table.new(:users)
258
+ relation[:id].average.should be_kind_of Nodes::Avg
259
+ end
260
+
261
+ # FIXME: backwards compat. Is this really necessary?
262
+ it 'should set the alias to "avg_id"' do
263
+ relation = Table.new(:users)
264
+ mgr = relation.project relation[:id].average
265
+ mgr.to_sql.should be_like %{
266
+ SELECT AVG("users"."id") AS avg_id
267
+ FROM "users"
268
+ }
269
+ end
270
+ end
271
+
272
+ describe '#maximum' do
273
+ it 'should create a MAX node' do
274
+ relation = Table.new(:users)
275
+ relation[:id].maximum.should be_kind_of Nodes::Max
276
+ end
277
+
278
+ # FIXME: backwards compat. Is this really necessary?
279
+ it 'should set the alias to "max_id"' do
280
+ relation = Table.new(:users)
281
+ mgr = relation.project relation[:id].maximum
282
+ mgr.to_sql.should be_like %{
283
+ SELECT MAX("users"."id") AS max_id
284
+ FROM "users"
285
+ }
286
+ end
287
+ end
288
+
289
+ describe '#minimum' do
290
+ it 'should create a Min node' do
291
+ relation = Table.new(:users)
292
+ relation[:id].minimum.should be_kind_of Nodes::Min
293
+ end
294
+ end
295
+
296
+ describe '#sum' do
297
+ it 'should create a SUM node' do
298
+ relation = Table.new(:users)
299
+ relation[:id].sum.should be_kind_of Nodes::Sum
300
+ end
301
+
302
+ # FIXME: backwards compat. Is this really necessary?
303
+ it 'should set the alias to "sum_id"' do
304
+ relation = Table.new(:users)
305
+ mgr = relation.project relation[:id].sum
306
+ mgr.to_sql.should be_like %{
307
+ SELECT SUM("users"."id") AS sum_id
308
+ FROM "users"
309
+ }
310
+ end
311
+ end
312
+
313
+ describe '#count' do
314
+ it 'should return a count node' do
315
+ relation = Table.new(:users)
316
+ relation[:id].count.should be_kind_of Nodes::Count
317
+ end
318
+
319
+ it 'should take a distinct param' do
320
+ relation = Table.new(:users)
321
+ count = relation[:id].count(nil)
322
+ count.should be_kind_of Nodes::Count
323
+ count.distinct.should be_nil
324
+ end
325
+ end
326
+
327
+ describe '#eq' do
328
+ it 'should return an equality node' do
329
+ attribute = Attribute.new nil, nil, nil
330
+ equality = attribute.eq 1
331
+ check equality.left.should == attribute
332
+ check equality.right.should == 1
333
+ equality.should be_kind_of Nodes::Equality
334
+ end
335
+
336
+ it 'should generate = in sql' do
337
+ relation = Table.new(:users)
338
+ mgr = relation.project relation[:id]
339
+ mgr.where relation[:id].eq(10)
340
+ mgr.to_sql.should be_like %{
341
+ SELECT "users"."id" FROM "users" WHERE "users"."id" = 10
342
+ }
343
+ end
344
+
345
+ it 'should handle nil' do
346
+ relation = Table.new(:users)
347
+ mgr = relation.project relation[:id]
348
+ mgr.where relation[:id].eq(nil)
349
+ mgr.to_sql.should be_like %{
350
+ SELECT "users"."id" FROM "users" WHERE "users"."id" IS NULL
351
+ }
352
+ end
353
+ end
354
+
355
+ describe '#eq_any' do
356
+ it 'should create a Grouping node' do
357
+ relation = Table.new(:users)
358
+ relation[:id].eq_any([1,2]).should be_kind_of Nodes::Grouping
359
+ end
360
+
361
+ it 'should generate ORs in sql' do
362
+ relation = Table.new(:users)
363
+ mgr = relation.project relation[:id]
364
+ mgr.where relation[:id].eq_any([1,2])
365
+ mgr.to_sql.should be_like %{
366
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 OR "users"."id" = 2)
367
+ }
368
+ end
369
+ end
370
+
371
+ describe '#eq_all' do
372
+ it 'should create a Grouping node' do
373
+ relation = Table.new(:users)
374
+ relation[:id].eq_all([1,2]).should be_kind_of Nodes::Grouping
375
+ end
376
+
377
+ it 'should generate ANDs in sql' do
378
+ relation = Table.new(:users)
379
+ mgr = relation.project relation[:id]
380
+ mgr.where relation[:id].eq_all([1,2])
381
+ mgr.to_sql.should be_like %{
382
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 AND "users"."id" = 2)
383
+ }
384
+ end
385
+ end
386
+
387
+ describe '#matches' do
388
+ it 'should create a Matches node' do
389
+ relation = Table.new(:users)
390
+ relation[:name].matches('%bacon%').should be_kind_of Nodes::Matches
391
+ end
392
+
393
+ it 'should generate LIKE in sql' do
394
+ relation = Table.new(:users)
395
+ mgr = relation.project relation[:id]
396
+ mgr.where relation[:name].matches('%bacon%')
397
+ mgr.to_sql.should be_like %{
398
+ SELECT "users"."id" FROM "users" WHERE "users"."name" LIKE '%bacon%'
399
+ }
400
+ end
401
+ end
402
+
403
+ describe '#matches_any' do
404
+ it 'should create a Grouping node' do
405
+ relation = Table.new(:users)
406
+ relation[:name].matches_any(['%chunky%','%bacon%']).should be_kind_of Nodes::Grouping
407
+ end
408
+
409
+ it 'should generate ORs in sql' do
410
+ relation = Table.new(:users)
411
+ mgr = relation.project relation[:id]
412
+ mgr.where relation[:name].matches_any(['%chunky%','%bacon%'])
413
+ mgr.to_sql.should be_like %{
414
+ SELECT "users"."id" FROM "users" WHERE ("users"."name" LIKE '%chunky%' OR "users"."name" LIKE '%bacon%')
415
+ }
416
+ end
417
+ end
418
+
419
+ describe '#matches_all' do
420
+ it 'should create a Grouping node' do
421
+ relation = Table.new(:users)
422
+ relation[:name].matches_all(['%chunky%','%bacon%']).should be_kind_of Nodes::Grouping
423
+ end
424
+
425
+ it 'should generate ANDs in sql' do
426
+ relation = Table.new(:users)
427
+ mgr = relation.project relation[:id]
428
+ mgr.where relation[:name].matches_all(['%chunky%','%bacon%'])
429
+ mgr.to_sql.should be_like %{
430
+ SELECT "users"."id" FROM "users" WHERE ("users"."name" LIKE '%chunky%' AND "users"."name" LIKE '%bacon%')
431
+ }
432
+ end
433
+ end
434
+
435
+ describe '#does_not_match' do
436
+ it 'should create a DoesNotMatch node' do
437
+ relation = Table.new(:users)
438
+ relation[:name].does_not_match('%bacon%').should be_kind_of Nodes::DoesNotMatch
439
+ end
440
+
441
+ it 'should generate NOT LIKE in sql' do
442
+ relation = Table.new(:users)
443
+ mgr = relation.project relation[:id]
444
+ mgr.where relation[:name].does_not_match('%bacon%')
445
+ mgr.to_sql.should be_like %{
446
+ SELECT "users"."id" FROM "users" WHERE "users"."name" NOT LIKE '%bacon%'
447
+ }
448
+ end
449
+ end
450
+
451
+ describe '#does_not_match_any' do
452
+ it 'should create a Grouping node' do
453
+ relation = Table.new(:users)
454
+ relation[:name].does_not_match_any(['%chunky%','%bacon%']).should be_kind_of Nodes::Grouping
455
+ end
456
+
457
+ it 'should generate ORs in sql' do
458
+ relation = Table.new(:users)
459
+ mgr = relation.project relation[:id]
460
+ mgr.where relation[:name].does_not_match_any(['%chunky%','%bacon%'])
461
+ mgr.to_sql.should be_like %{
462
+ SELECT "users"."id" FROM "users" WHERE ("users"."name" NOT LIKE '%chunky%' OR "users"."name" NOT LIKE '%bacon%')
463
+ }
464
+ end
465
+ end
466
+
467
+ describe '#does_not_match_all' do
468
+ it 'should create a Grouping node' do
469
+ relation = Table.new(:users)
470
+ relation[:name].does_not_match_all(['%chunky%','%bacon%']).should be_kind_of Nodes::Grouping
471
+ end
472
+
473
+ it 'should generate ANDs in sql' do
474
+ relation = Table.new(:users)
475
+ mgr = relation.project relation[:id]
476
+ mgr.where relation[:name].does_not_match_all(['%chunky%','%bacon%'])
477
+ mgr.to_sql.should be_like %{
478
+ SELECT "users"."id" FROM "users" WHERE ("users"."name" NOT LIKE '%chunky%' AND "users"."name" NOT LIKE '%bacon%')
479
+ }
480
+ end
481
+ end
482
+
483
+ describe '#in' do
484
+ it 'can be constructed with a list' do
485
+ end
486
+
487
+ it 'should return an in node' do
488
+ attribute = Attribute.new nil, nil, nil
489
+ node = Nodes::In.new attribute, [1,2,3]
490
+ check node.left.should == attribute
491
+ check node.right.should == [1, 2, 3]
492
+ end
493
+
494
+ it 'should generate IN in sql' do
495
+ relation = Table.new(:users)
496
+ mgr = relation.project relation[:id]
497
+ mgr.where relation[:id].in([1,2,3])
498
+ mgr.to_sql.should be_like %{
499
+ SELECT "users"."id" FROM "users" WHERE "users"."id" IN (1, 2, 3)
500
+ }
501
+ end
502
+ end
503
+
504
+ describe '#in_any' do
505
+ it 'should create a Grouping node' do
506
+ relation = Table.new(:users)
507
+ relation[:id].in_any([1,2]).should be_kind_of Nodes::Grouping
508
+ end
509
+
510
+ it 'should generate ORs in sql' do
511
+ relation = Table.new(:users)
512
+ mgr = relation.project relation[:id]
513
+ mgr.where relation[:id].in_any([[1,2], [3,4]])
514
+ mgr.to_sql.should be_like %{
515
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" IN (1, 2) OR "users"."id" IN (3, 4))
516
+ }
517
+ end
518
+ end
519
+
520
+ describe '#in_all' do
521
+ it 'should create a Grouping node' do
522
+ relation = Table.new(:users)
523
+ relation[:id].in_all([1,2]).should be_kind_of Nodes::Grouping
524
+ end
525
+
526
+ it 'should generate ANDs in sql' do
527
+ relation = Table.new(:users)
528
+ mgr = relation.project relation[:id]
529
+ mgr.where relation[:id].in_all([[1,2], [3,4]])
530
+ mgr.to_sql.should be_like %{
531
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" IN (1, 2) AND "users"."id" IN (3, 4))
532
+ }
533
+ end
534
+ end
535
+
536
+ describe '#not_in' do
537
+ it 'can be constructed with a list' do
538
+ end
539
+
540
+ it 'should return a NotIn node' do
541
+ attribute = Attribute.new nil, nil, nil
542
+ node = Nodes::NotIn.new attribute, [1,2,3]
543
+ check node.left.should == attribute
544
+ check node.right.should == [1, 2, 3]
545
+ end
546
+
547
+ it 'should generate NOT IN in sql' do
548
+ relation = Table.new(:users)
549
+ mgr = relation.project relation[:id]
550
+ mgr.where relation[:id].not_in([1,2,3])
551
+ mgr.to_sql.should be_like %{
552
+ SELECT "users"."id" FROM "users" WHERE "users"."id" NOT IN (1, 2, 3)
553
+ }
554
+ end
555
+ end
556
+
557
+ describe '#not_in_any' do
558
+ it 'should create a Grouping node' do
559
+ relation = Table.new(:users)
560
+ relation[:id].not_in_any([1,2]).should be_kind_of Nodes::Grouping
561
+ end
562
+
563
+ it 'should generate ORs in sql' do
564
+ relation = Table.new(:users)
565
+ mgr = relation.project relation[:id]
566
+ mgr.where relation[:id].not_in_any([[1,2], [3,4]])
567
+ mgr.to_sql.should be_like %{
568
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" NOT IN (1, 2) OR "users"."id" NOT IN (3, 4))
569
+ }
570
+ end
571
+ end
572
+
573
+ describe '#not_in_all' do
574
+ it 'should create a Grouping node' do
575
+ relation = Table.new(:users)
576
+ relation[:id].not_in_all([1,2]).should be_kind_of Nodes::Grouping
577
+ end
578
+
579
+ it 'should generate ANDs in sql' do
580
+ relation = Table.new(:users)
581
+ mgr = relation.project relation[:id]
582
+ mgr.where relation[:id].not_in_all([[1,2], [3,4]])
583
+ mgr.to_sql.should be_like %{
584
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" NOT IN (1, 2) AND "users"."id" NOT IN (3, 4))
585
+ }
586
+ end
587
+ end
588
+
589
+ describe '#eq_all' do
590
+ it 'should create a Grouping node' do
591
+ relation = Table.new(:users)
592
+ relation[:id].eq_all([1,2]).should be_kind_of Nodes::Grouping
593
+ end
594
+
595
+ it 'should generate ANDs in sql' do
596
+ relation = Table.new(:users)
597
+ mgr = relation.project relation[:id]
598
+ mgr.where relation[:id].eq_all([1,2])
599
+ mgr.to_sql.should be_like %{
600
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 AND "users"."id" = 2)
601
+ }
602
+ end
603
+ end
604
+
605
+ describe '#asc' do
606
+ it 'should create an Ordering node' do
607
+ relation = Table.new(:users)
608
+ relation[:id].asc.should be_kind_of Nodes::Ordering
609
+ end
610
+
611
+ it 'should generate ASC in sql' do
612
+ relation = Table.new(:users)
613
+ mgr = relation.project relation[:id]
614
+ mgr.order relation[:id].asc
615
+ mgr.to_sql.should be_like %{
616
+ SELECT "users"."id" FROM "users" ORDER BY "users"."id" ASC
617
+ }
618
+ end
619
+ end
620
+
621
+ describe '#desc' do
622
+ it 'should create an Ordering node' do
623
+ relation = Table.new(:users)
624
+ relation[:id].desc.should be_kind_of Nodes::Ordering
625
+ end
626
+
627
+ it 'should generate DESC in sql' do
628
+ relation = Table.new(:users)
629
+ mgr = relation.project relation[:id]
630
+ mgr.order relation[:id].desc
631
+ mgr.to_sql.should be_like %{
632
+ SELECT "users"."id" FROM "users" ORDER BY "users"."id" DESC
633
+ }
634
+ end
635
+ end
636
+ end
637
+
638
+ describe 'equality' do
639
+ describe '#to_sql' do
640
+ it 'should produce sql' do
641
+ table = Table.new :users
642
+ condition = table['id'].eq 1
643
+ condition.to_sql.should == '"users"."id" = 1'
644
+ end
645
+ end
646
+ end
647
+ end
648
+ end