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,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Arel::Nodes::SelectCore do
4
+ describe "#clone" do
5
+ it "clones froms, projections and wheres" do
6
+ core = Arel::Nodes::SelectCore.new
7
+ core.instance_variable_set "@froms", %w[a b c]
8
+ core.instance_variable_set "@projections", %w[d e f]
9
+ core.instance_variable_set "@wheres", %w[g h i]
10
+
11
+ [:froms, :projections, :wheres].each do |array_attr|
12
+ core.send(array_attr).should_receive(:clone).and_return([array_attr])
13
+ end
14
+
15
+ dolly = core.clone
16
+ check dolly.froms.should == [:froms]
17
+ check dolly.projections.should == [:projections]
18
+ check dolly.wheres.should == [:wheres]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Arel::Nodes::SelectStatement do
4
+ describe "#clone" do
5
+ it "clones cores" do
6
+ statement = Arel::Nodes::SelectStatement.new %w[a b c]
7
+
8
+ statement.cores.map { |x| x.should_receive(:clone).and_return(:f) }
9
+
10
+ dolly = statement.clone
11
+ dolly.cores.should == [:f, :f, :f]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ module Arel
2
+ module Nodes
3
+ describe 'sql literal' do
4
+ describe 'sql' do
5
+ it 'makes a sql literal node' do
6
+ sql = Arel.sql 'foo'
7
+ sql.should be_kind_of Arel::Nodes::SqlLiteral
8
+ end
9
+ end
10
+
11
+ describe 'count' do
12
+ it 'makes a count node' do
13
+ node = SqlLiteral.new('*').count
14
+ viz = Visitors::ToSql.new Table.engine
15
+ viz.accept(node).should be_like %{ COUNT(*) }
16
+ end
17
+
18
+ it 'makes a distinct node' do
19
+ node = SqlLiteral.new('*').count true
20
+ viz = Visitors::ToSql.new Table.engine
21
+ viz.accept(node).should be_like %{ COUNT(DISTINCT *) }
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Arel::Nodes::Sum do
4
+ describe "as" do
5
+ it 'should alias the sum' do
6
+ table = Arel::Table.new :users
7
+ table[:id].sum.as('foo').to_sql.should be_like %{
8
+ SUM("users"."id") AS foo
9
+ }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Arel::Nodes::UpdateStatement do
4
+ describe "#clone" do
5
+ it "clones wheres and values" do
6
+ statement = Arel::Nodes::UpdateStatement.new
7
+ statement.wheres = %w[a b c]
8
+ statement.values = %w[x y z]
9
+
10
+ statement.wheres.should_receive(:clone).and_return([:wheres])
11
+ statement.values.should_receive(:clone).and_return([:values])
12
+
13
+ dolly = statement.clone
14
+ check dolly.wheres.should == [:wheres]
15
+ check dolly.values.should == [:values]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,581 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ class EngineProxy
5
+ attr_reader :executed
6
+ attr_reader :connection_pool
7
+ attr_reader :spec
8
+ attr_reader :config
9
+
10
+ def initialize engine
11
+ @engine = engine
12
+ @executed = []
13
+ @connection_pool = self
14
+ @spec = self
15
+ @config = { :adapter => 'sqlite3' }
16
+ end
17
+
18
+ def with_connection
19
+ yield self
20
+ end
21
+
22
+ def connection
23
+ self
24
+ end
25
+
26
+ def quote_table_name thing; @engine.connection.quote_table_name thing end
27
+ def quote_column_name thing; @engine.connection.quote_column_name thing end
28
+ def quote thing, column; @engine.connection.quote thing, column end
29
+
30
+ def execute sql, name = nil, *args
31
+ @executed << sql
32
+ end
33
+ alias :update :execute
34
+ alias :delete :execute
35
+ alias :insert :execute
36
+ end
37
+
38
+ describe 'select manager' do
39
+ describe 'backwards compatibility' do
40
+ describe 'order' do
41
+ it 'accepts symbols' do
42
+ table = Table.new :users
43
+ manager = Arel::SelectManager.new Table.engine
44
+ manager.project SqlLiteral.new '*'
45
+ manager.from table
46
+ manager.order :foo
47
+ manager.to_sql.should be_like %{
48
+ SELECT * FROM "users" ORDER BY foo
49
+ }
50
+ end
51
+ end
52
+
53
+ describe 'group' do
54
+ it 'takes a symbol' do
55
+ table = Table.new :users
56
+ manager = Arel::SelectManager.new Table.engine
57
+ manager.from table
58
+ manager.group :foo
59
+ manager.to_sql.should be_like %{
60
+ SELECT FROM "users" GROUP BY foo
61
+ }
62
+ end
63
+ end
64
+
65
+ describe 'from' do
66
+ it 'ignores strings when table of same name exists' do
67
+ table = Table.new :users
68
+ manager = Arel::SelectManager.new Table.engine
69
+
70
+ manager.from table
71
+ manager.from 'users'
72
+ manager.project table['id']
73
+ manager.to_sql.should be_like 'SELECT "users"."id" FROM users'
74
+ end
75
+ end
76
+
77
+ describe '#having' do
78
+ it 'converts strings to SQLLiterals' do
79
+ table = Table.new :users
80
+ mgr = table.from table
81
+ mgr.having 'foo'
82
+ mgr.to_sql.should be_like %{ SELECT FROM "users" HAVING foo }
83
+ end
84
+ end
85
+ end
86
+
87
+ describe 'clone' do
88
+ it 'creates new cores' do
89
+ table = Table.new :users, :engine => Table.engine, :as => 'foo'
90
+ mgr = table.from table
91
+ m2 = mgr.clone
92
+ m2.project "foo"
93
+
94
+ check mgr.to_sql.should_not == m2.to_sql
95
+ end
96
+ end
97
+
98
+ describe 'initialize' do
99
+ it 'uses alias in sql' do
100
+ table = Table.new :users, :engine => Table.engine, :as => 'foo'
101
+ mgr = table.from table
102
+ mgr.skip 10
103
+ mgr.to_sql.should be_like %{ SELECT FROM "users" "foo" OFFSET 10 }
104
+ end
105
+ end
106
+
107
+ describe 'skip' do
108
+ it 'should add an offset' do
109
+ table = Table.new :users
110
+ mgr = table.from table
111
+ mgr.skip 10
112
+ mgr.to_sql.should be_like %{ SELECT FROM "users" OFFSET 10 }
113
+ end
114
+
115
+ it 'should chain' do
116
+ table = Table.new :users
117
+ mgr = table.from table
118
+ mgr.skip(10).to_sql.should be_like %{ SELECT FROM "users" OFFSET 10 }
119
+ end
120
+ end
121
+
122
+ describe 'taken' do
123
+ it 'should return limit' do
124
+ table = Table.new :users
125
+ manager = Arel::SelectManager.new Table.engine
126
+ manager.take 10
127
+ check manager.taken.should == 10
128
+ end
129
+ end
130
+
131
+ describe 'insert' do
132
+ it 'uses the select FROM' do
133
+ engine = EngineProxy.new Table.engine
134
+ table = Table.new :users
135
+ manager = Arel::SelectManager.new engine
136
+ manager.from table
137
+ manager.insert 'VALUES(NULL)'
138
+
139
+ engine.executed.last.should be_like %{
140
+ INSERT INTO "users" VALUES(NULL)
141
+ }
142
+ end
143
+ end
144
+
145
+ describe 'lock' do
146
+ # This should fail on other databases
147
+ it 'adds a lock node' do
148
+ table = Table.new :users
149
+ mgr = table.from table
150
+ mgr.lock.to_sql.should be_like %{ SELECT FROM "users" }
151
+ end
152
+ end
153
+
154
+ describe 'orders' do
155
+ it 'returns order clauses' do
156
+ table = Table.new :users
157
+ manager = Arel::SelectManager.new Table.engine
158
+ order = table[:id]
159
+ manager.order table[:id]
160
+ check manager.orders.should == [order]
161
+ end
162
+ end
163
+
164
+ describe 'order' do
165
+ it 'generates order clauses' do
166
+ table = Table.new :users
167
+ manager = Arel::SelectManager.new Table.engine
168
+ manager.project SqlLiteral.new '*'
169
+ manager.from table
170
+ manager.order table[:id]
171
+ manager.to_sql.should be_like %{
172
+ SELECT * FROM "users" ORDER BY "users"."id"
173
+ }
174
+ end
175
+
176
+ # FIXME: I would like to deprecate this
177
+ it 'takes *args' do
178
+ table = Table.new :users
179
+ manager = Arel::SelectManager.new Table.engine
180
+ manager.project SqlLiteral.new '*'
181
+ manager.from table
182
+ manager.order table[:id], table[:name]
183
+ manager.to_sql.should be_like %{
184
+ SELECT * FROM "users" ORDER BY "users"."id", "users"."name"
185
+ }
186
+ end
187
+
188
+ it 'chains' do
189
+ table = Table.new :users
190
+ manager = Arel::SelectManager.new Table.engine
191
+ check manager.order(table[:id]).should == manager
192
+ end
193
+ end
194
+
195
+ describe 'on' do
196
+ it 'takes two params' do
197
+ left = Table.new :users
198
+ right = left.alias
199
+ predicate = left[:id].eq(right[:id])
200
+ manager = Arel::SelectManager.new Table.engine
201
+
202
+ manager.from left
203
+ manager.join(right).on(predicate, predicate)
204
+ manager.to_sql.should be_like %{
205
+ SELECT FROM "users"
206
+ INNER JOIN "users" "users_2"
207
+ ON "users"."id" = "users_2"."id" AND
208
+ "users"."id" = "users_2"."id"
209
+ }
210
+ end
211
+
212
+ it 'takes three params' do
213
+ left = Table.new :users
214
+ right = left.alias
215
+ predicate = left[:id].eq(right[:id])
216
+ manager = Arel::SelectManager.new Table.engine
217
+
218
+ manager.from left
219
+ manager.join(right).on(
220
+ predicate,
221
+ predicate,
222
+ left[:name].eq(right[:name])
223
+ )
224
+ manager.to_sql.should be_like %{
225
+ SELECT FROM "users"
226
+ INNER JOIN "users" "users_2"
227
+ ON "users"."id" = "users_2"."id" AND
228
+ "users"."id" = "users_2"."id" AND
229
+ "users"."name" = "users_2"."name"
230
+ }
231
+ end
232
+ end
233
+
234
+ describe 'join' do
235
+ it 'responds to join' do
236
+ left = Table.new :users
237
+ right = left.alias
238
+ predicate = left[:id].eq(right[:id])
239
+ manager = Arel::SelectManager.new Table.engine
240
+
241
+ manager.from left
242
+ manager.join(right).on(predicate)
243
+ manager.to_sql.should be_like %{
244
+ SELECT FROM "users"
245
+ INNER JOIN "users" "users_2"
246
+ ON "users"."id" = "users_2"."id"
247
+ }
248
+ end
249
+
250
+ it 'takes a class' do
251
+ left = Table.new :users
252
+ right = left.alias
253
+ predicate = left[:id].eq(right[:id])
254
+ manager = Arel::SelectManager.new Table.engine
255
+
256
+ manager.from left
257
+ manager.join(right, Nodes::OuterJoin).on(predicate)
258
+ manager.to_sql.should be_like %{
259
+ SELECT FROM "users"
260
+ LEFT OUTER JOIN "users" "users_2"
261
+ ON "users"."id" = "users_2"."id"
262
+ }
263
+ end
264
+
265
+ it 'noops on nil' do
266
+ manager = Arel::SelectManager.new Table.engine
267
+ check manager.join(nil).should == manager
268
+ end
269
+ end
270
+
271
+ describe 'joins' do
272
+ it 'returns join sql' do
273
+ table = Table.new :users
274
+ aliaz = table.alias
275
+ manager = Arel::SelectManager.new Table.engine
276
+ manager.from Nodes::InnerJoin.new(table, aliaz, table[:id].eq(aliaz[:id]))
277
+ manager.join_sql.should be_like %{
278
+ INNER JOIN "users" "users_2" "users"."id" = "users_2"."id"
279
+ }
280
+ check manager.joins(manager).should == manager.join_sql
281
+ end
282
+
283
+ it 'returns outer join sql' do
284
+ table = Table.new :users
285
+ aliaz = table.alias
286
+ manager = Arel::SelectManager.new Table.engine
287
+ manager.from Nodes::OuterJoin.new(table, aliaz, table[:id].eq(aliaz[:id]))
288
+ manager.join_sql.should be_like %{
289
+ LEFT OUTER JOIN "users" "users_2" "users"."id" = "users_2"."id"
290
+ }
291
+ check manager.joins(manager).should == manager.join_sql
292
+ end
293
+
294
+ it 'returns string join sql' do
295
+ table = Table.new :users
296
+ aliaz = table.alias
297
+ manager = Arel::SelectManager.new Table.engine
298
+ manager.from Nodes::StringJoin.new(table, 'hello')
299
+ manager.join_sql.should be_like %{ 'hello' }
300
+ check manager.joins(manager).should == manager.join_sql
301
+ end
302
+
303
+ it 'returns nil join sql' do
304
+ manager = Arel::SelectManager.new Table.engine
305
+ manager.join_sql.should be_nil
306
+ end
307
+ end
308
+
309
+ describe 'order_clauses' do
310
+ it 'returns order clauses as a list' do
311
+ table = Table.new :users
312
+ aliaz = table.alias
313
+ manager = Arel::SelectManager.new Table.engine
314
+ manager.from table
315
+ manager.order table[:id]
316
+ manager.order_clauses.first.should be_like %{ "users"."id" }
317
+ end
318
+ end
319
+
320
+ describe 'group' do
321
+ it 'takes an attribute' do
322
+ table = Table.new :users
323
+ manager = Arel::SelectManager.new Table.engine
324
+ manager.from table
325
+ manager.group table[:id]
326
+ manager.to_sql.should be_like %{
327
+ SELECT FROM "users" GROUP BY "users"."id"
328
+ }
329
+ end
330
+
331
+ it 'chains' do
332
+ table = Table.new :users
333
+ manager = Arel::SelectManager.new Table.engine
334
+ check manager.group(table[:id]).should == manager
335
+ end
336
+
337
+ it 'takes multiple args' do
338
+ table = Table.new :users
339
+ manager = Arel::SelectManager.new Table.engine
340
+ manager.from table
341
+ manager.group table[:id], table[:name]
342
+ manager.to_sql.should be_like %{
343
+ SELECT FROM "users" GROUP BY "users"."id", "users"."name"
344
+ }
345
+ end
346
+
347
+ # FIXME: backwards compat
348
+ it 'makes strings literals' do
349
+ table = Table.new :users
350
+ manager = Arel::SelectManager.new Table.engine
351
+ manager.from table
352
+ manager.group 'foo'
353
+ manager.to_sql.should be_like %{ SELECT FROM "users" GROUP BY foo }
354
+ end
355
+ end
356
+
357
+ describe 'delete' do
358
+ it "copies from" do
359
+ engine = EngineProxy.new Table.engine
360
+ table = Table.new :users
361
+ manager = Arel::SelectManager.new engine
362
+ manager.from table
363
+ manager.delete
364
+
365
+ engine.executed.last.should be_like %{ DELETE FROM "users" }
366
+ end
367
+
368
+ it "copies where" do
369
+ engine = EngineProxy.new Table.engine
370
+ table = Table.new :users
371
+ manager = Arel::SelectManager.new engine
372
+ manager.from table
373
+ manager.where table[:id].eq 10
374
+ manager.delete
375
+
376
+ engine.executed.last.should be_like %{
377
+ DELETE FROM "users" WHERE "users"."id" = 10
378
+ }
379
+ end
380
+ end
381
+
382
+ describe 'where_sql' do
383
+ it 'gives me back the where sql' do
384
+ table = Table.new :users
385
+ manager = Arel::SelectManager.new Table.engine
386
+ manager.from table
387
+ manager.where table[:id].eq 10
388
+ manager.where_sql.should be_like %{ WHERE "users"."id" = 10 }
389
+ end
390
+
391
+ it 'returns nil when there are no wheres' do
392
+ table = Table.new :users
393
+ manager = Arel::SelectManager.new Table.engine
394
+ manager.from table
395
+ manager.where_sql.should be_nil
396
+ end
397
+ end
398
+
399
+ describe 'update' do
400
+ it 'copies limits' do
401
+ engine = EngineProxy.new Table.engine
402
+ table = Table.new :users
403
+ manager = Arel::SelectManager.new engine
404
+ manager.from table
405
+ manager.take 1
406
+ manager.update(SqlLiteral.new('foo = bar'))
407
+
408
+ engine.executed.last.should be_like %{
409
+ UPDATE "users" SET foo = bar
410
+ WHERE "users"."id" IN (SELECT "users"."id" FROM "users" LIMIT 1)
411
+ }
412
+ end
413
+
414
+ it 'copies order' do
415
+ engine = EngineProxy.new Table.engine
416
+ table = Table.new :users
417
+ manager = Arel::SelectManager.new engine
418
+ manager.from table
419
+ manager.order :foo
420
+ manager.update(SqlLiteral.new('foo = bar'))
421
+
422
+ engine.executed.last.should be_like %{
423
+ UPDATE "users" SET foo = bar
424
+ WHERE "users"."id" IN (SELECT "users"."id" FROM "users" ORDER BY foo)
425
+ }
426
+ end
427
+
428
+ it 'takes a string' do
429
+ engine = EngineProxy.new Table.engine
430
+ table = Table.new :users
431
+ manager = Arel::SelectManager.new engine
432
+ manager.from table
433
+ manager.update(SqlLiteral.new('foo = bar'))
434
+
435
+ engine.executed.last.should be_like %{ UPDATE "users" SET foo = bar }
436
+ end
437
+
438
+ it 'copies where clauses' do
439
+ engine = EngineProxy.new Table.engine
440
+ table = Table.new :users
441
+ manager = Arel::SelectManager.new engine
442
+ manager.where table[:id].eq 10
443
+ manager.from table
444
+ manager.update(table[:id] => 1)
445
+
446
+ engine.executed.last.should be_like %{
447
+ UPDATE "users" SET "id" = 1 WHERE "users"."id" = 10
448
+ }
449
+ end
450
+
451
+ it 'executes an update statement' do
452
+ engine = EngineProxy.new Table.engine
453
+ table = Table.new :users
454
+ manager = Arel::SelectManager.new engine
455
+ manager.from table
456
+ manager.update(table[:id] => 1)
457
+
458
+ engine.executed.last.should be_like %{
459
+ UPDATE "users" SET "id" = 1
460
+ }
461
+ end
462
+ end
463
+
464
+ describe 'project' do
465
+ it 'takes multiple args' do
466
+ table = Table.new :users
467
+ manager = Arel::SelectManager.new Table.engine
468
+ manager.project Nodes::SqlLiteral.new('foo'),
469
+ Nodes::SqlLiteral.new('bar')
470
+ manager.to_sql.should be_like %{ SELECT foo, bar }
471
+ end
472
+
473
+ it 'takes strings' do
474
+ table = Table.new :users
475
+ manager = Arel::SelectManager.new Table.engine
476
+ manager.project Nodes::SqlLiteral.new('*')
477
+ manager.to_sql.should be_like %{ SELECT * }
478
+ end
479
+
480
+ it "takes sql literals" do
481
+ table = Table.new :users
482
+ manager = Arel::SelectManager.new Table.engine
483
+ manager.project Nodes::SqlLiteral.new '*'
484
+ manager.to_sql.should be_like %{
485
+ SELECT *
486
+ }
487
+ end
488
+ end
489
+
490
+ describe 'take' do
491
+ it "knows take" do
492
+ table = Table.new :users
493
+ manager = Arel::SelectManager.new Table.engine
494
+ manager.from(table).project(table['id'])
495
+ manager.where(table['id'].eq(1))
496
+ manager.take 1
497
+
498
+ manager.to_sql.should be_like %{
499
+ SELECT "users"."id"
500
+ FROM "users"
501
+ WHERE "users"."id" = 1
502
+ LIMIT 1
503
+ }
504
+ end
505
+
506
+ it "chains" do
507
+ table = Table.new :users
508
+ manager = Arel::SelectManager.new Table.engine
509
+ manager.take(1).should == manager
510
+ end
511
+ end
512
+
513
+ describe 'where' do
514
+ it "knows where" do
515
+ table = Table.new :users
516
+ manager = Arel::SelectManager.new Table.engine
517
+ manager.from(table).project(table['id'])
518
+ manager.where(table['id'].eq(1))
519
+ manager.to_sql.should be_like %{
520
+ SELECT "users"."id"
521
+ FROM "users"
522
+ WHERE "users"."id" = 1
523
+ }
524
+ end
525
+
526
+ it "chains" do
527
+ table = Table.new :users
528
+ manager = Arel::SelectManager.new Table.engine
529
+ manager.from(table)
530
+ manager.project(table['id']).where(table['id'].eq 1).should == manager
531
+ end
532
+ end
533
+
534
+ describe "join" do
535
+ it "joins itself" do
536
+ left = Table.new :users
537
+ right = left.alias
538
+ predicate = left[:id].eq(right[:id])
539
+
540
+ mgr = left.join(right)
541
+ mgr.project Nodes::SqlLiteral.new('*')
542
+ check mgr.on(predicate).should == mgr
543
+
544
+ mgr.to_sql.should be_like %{
545
+ SELECT * FROM "users"
546
+ INNER JOIN "users" "users_2"
547
+ ON "users"."id" = "users_2"."id"
548
+ }
549
+ end
550
+ end
551
+
552
+ describe 'from' do
553
+ it "makes sql" do
554
+ table = Table.new :users
555
+ manager = Arel::SelectManager.new Table.engine
556
+
557
+ manager.from table
558
+ manager.project table['id']
559
+ manager.to_sql.should be_like 'SELECT "users"."id" FROM "users"'
560
+ end
561
+
562
+ it "chains" do
563
+ table = Table.new :users
564
+ manager = Arel::SelectManager.new Table.engine
565
+ check manager.from(table).project(table['id']).should == manager
566
+ manager.to_sql.should be_like 'SELECT "users"."id" FROM "users"'
567
+ end
568
+ end
569
+
570
+ describe "TreeManager" do
571
+ subject do
572
+ table = Table.new :users
573
+ Arel::SelectManager.new(Table.engine).tap do |manager|
574
+ manager.from(table).project(table['id'])
575
+ end
576
+ end
577
+
578
+ it_should_behave_like "TreeManager"
579
+ end
580
+ end
581
+ end