arel 3.0.3 → 4.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +2 -2
  3. data/Gemfile +3 -4
  4. data/History.txt +0 -51
  5. data/Manifest.txt +8 -2
  6. data/README.markdown +1 -1
  7. data/Rakefile +1 -1
  8. data/arel.gemspec +21 -29
  9. data/lib/arel.rb +1 -3
  10. data/lib/arel/nodes.rb +1 -0
  11. data/lib/arel/nodes/and.rb +10 -0
  12. data/lib/arel/nodes/binary.rb +11 -0
  13. data/lib/arel/nodes/extract.rb +11 -0
  14. data/lib/arel/nodes/false.rb +7 -0
  15. data/lib/arel/nodes/function.rb +11 -0
  16. data/lib/arel/nodes/grouping.rb +7 -0
  17. data/lib/arel/nodes/insert_statement.rb +12 -0
  18. data/lib/arel/nodes/named_function.rb +9 -0
  19. data/lib/arel/nodes/select_core.rb +20 -0
  20. data/lib/arel/nodes/select_statement.rb +15 -1
  21. data/lib/arel/nodes/table_alias.rb +4 -0
  22. data/lib/arel/nodes/terminal.rb +7 -0
  23. data/lib/arel/nodes/true.rb +7 -0
  24. data/lib/arel/nodes/unary.rb +10 -1
  25. data/lib/arel/nodes/update_statement.rb +15 -0
  26. data/lib/arel/nodes/window.rb +30 -3
  27. data/lib/arel/select_manager.rb +4 -0
  28. data/lib/arel/table.rb +13 -0
  29. data/lib/arel/tree_manager.rb +0 -2
  30. data/lib/arel/visitors/bind_visitor.rb +10 -0
  31. data/lib/arel/visitors/dot.rb +1 -1
  32. data/lib/arel/visitors/oracle.rb +1 -2
  33. data/lib/arel/visitors/to_sql.rb +138 -27
  34. data/test/nodes/test_and.rb +20 -0
  35. data/test/nodes/test_as.rb +12 -0
  36. data/test/nodes/test_ascending.rb +10 -0
  37. data/test/nodes/test_bin.rb +10 -0
  38. data/test/nodes/test_count.rb +12 -0
  39. data/test/nodes/test_delete_statement.rb +20 -0
  40. data/test/nodes/test_descending.rb +10 -0
  41. data/test/nodes/test_distinct.rb +20 -0
  42. data/test/nodes/test_equality.rb +10 -0
  43. data/test/nodes/test_extract.rb +14 -0
  44. data/test/nodes/test_false.rb +20 -0
  45. data/test/nodes/test_grouping.rb +25 -0
  46. data/test/nodes/test_infix_operation.rb +10 -0
  47. data/test/nodes/test_insert_statement.rb +24 -0
  48. data/test/nodes/test_named_function.rb +16 -0
  49. data/test/nodes/test_not.rb +12 -0
  50. data/test/nodes/test_or.rb +12 -0
  51. data/test/nodes/test_over.rb +18 -0
  52. data/test/nodes/test_select_core.rb +38 -0
  53. data/test/nodes/test_select_statement.rb +36 -0
  54. data/test/nodes/test_sql_literal.rb +10 -0
  55. data/test/nodes/test_sum.rb +12 -0
  56. data/test/nodes/test_table_alias.rb +36 -0
  57. data/test/nodes/test_true.rb +21 -0
  58. data/test/nodes/test_update_statement.rb +40 -0
  59. data/test/nodes/test_window.rb +73 -0
  60. data/test/test_attributes.rb +12 -0
  61. data/test/test_insert_manager.rb +0 -2
  62. data/test/test_select_manager.rb +10 -5
  63. data/test/test_table.rb +24 -0
  64. data/test/test_update_manager.rb +8 -0
  65. data/test/visitors/test_bind_visitor.rb +20 -1
  66. data/test/visitors/test_oracle.rb +1 -2
  67. data/test/visitors/test_to_sql.rb +44 -0
  68. metadata +76 -86
  69. data/lib/arel/nodes/ordering.rb +0 -6
  70. data/lib/arel/relation.rb +0 -6
@@ -31,6 +31,16 @@ module Arel
31
31
  node = SqlLiteral.new('foo').eq(1)
32
32
  @visitor.accept(node).must_be_like %{ foo = 1 }
33
33
  end
34
+
35
+ it 'is equal with equal contents' do
36
+ array = [SqlLiteral.new('foo'), SqlLiteral.new('foo')]
37
+ assert_equal 1, array.uniq.size
38
+ end
39
+
40
+ it 'is not equal with different contents' do
41
+ array = [SqlLiteral.new('foo'), SqlLiteral.new('bar')]
42
+ assert_equal 2, array.uniq.size
43
+ end
34
44
  end
35
45
 
36
46
  describe 'grouped "or" equality' do
@@ -9,4 +9,16 @@ describe Arel::Nodes::Sum do
9
9
  }
10
10
  end
11
11
  end
12
+
13
+ describe 'equality' do
14
+ it 'is equal with equal ivars' do
15
+ array = [Arel::Nodes::Sum.new('foo'), Arel::Nodes::Sum.new('foo')]
16
+ assert_equal 1, array.uniq.size
17
+ end
18
+
19
+ it 'is not equal with different ivars' do
20
+ array = [Arel::Nodes::Sum.new('foo'), Arel::Nodes::Sum.new('foo!')]
21
+ assert_equal 2, array.uniq.size
22
+ end
23
+ end
12
24
  end
@@ -0,0 +1,36 @@
1
+ require 'helper'
2
+ require 'ostruct'
3
+
4
+ module Arel
5
+ module Nodes
6
+ describe 'table alias' do
7
+ it 'has an #engine which delegates to the relation' do
8
+ engine = 'vroom'
9
+ relation = Table.new(:users, engine)
10
+
11
+ node = TableAlias.new relation, :foo
12
+ node.engine.must_equal engine
13
+ end
14
+
15
+ describe 'equality' do
16
+ it 'is equal with equal ivars' do
17
+ relation1 = Table.new(:users, 'vroom')
18
+ node1 = TableAlias.new relation1, :foo
19
+ relation2 = Table.new(:users, 'vroom')
20
+ node2 = TableAlias.new relation2, :foo
21
+ array = [node1, node2]
22
+ assert_equal 1, array.uniq.size
23
+ end
24
+
25
+ it 'is not equal with different ivars' do
26
+ relation1 = Table.new(:users, 'vroom')
27
+ node1 = TableAlias.new relation1, :foo
28
+ relation2 = Table.new(:users, 'vroom')
29
+ node2 = TableAlias.new relation2, :bar
30
+ array = [node1, node2]
31
+ assert_equal 2, array.uniq.size
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ require 'helper'
2
+
3
+ module Arel
4
+ module Nodes
5
+ describe 'True' do
6
+ describe 'equality' do
7
+ it 'is equal to other true nodes' do
8
+ array = [True.new, True.new]
9
+ assert_equal 1, array.uniq.size
10
+ end
11
+
12
+ it 'is not equal with other nodes' do
13
+ array = [True.new, Node.new]
14
+ assert_equal 2, array.uniq.size
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+
@@ -15,4 +15,44 @@ describe Arel::Nodes::UpdateStatement do
15
15
  dolly.values.wont_be_same_as statement.values
16
16
  end
17
17
  end
18
+
19
+ describe 'equality' do
20
+ it 'is equal with equal ivars' do
21
+ statement1 = Arel::Nodes::UpdateStatement.new
22
+ statement1.relation = 'zomg'
23
+ statement1.wheres = 2
24
+ statement1.values = false
25
+ statement1.orders = %w[x y z]
26
+ statement1.limit = 42
27
+ statement1.key = 'zomg'
28
+ statement2 = Arel::Nodes::UpdateStatement.new
29
+ statement2.relation = 'zomg'
30
+ statement2.wheres = 2
31
+ statement2.values = false
32
+ statement2.orders = %w[x y z]
33
+ statement2.limit = 42
34
+ statement2.key = 'zomg'
35
+ array = [statement1, statement2]
36
+ assert_equal 1, array.uniq.size
37
+ end
38
+
39
+ it 'is not equal with different ivars' do
40
+ statement1 = Arel::Nodes::UpdateStatement.new
41
+ statement1.relation = 'zomg'
42
+ statement1.wheres = 2
43
+ statement1.values = false
44
+ statement1.orders = %w[x y z]
45
+ statement1.limit = 42
46
+ statement1.key = 'zomg'
47
+ statement2 = Arel::Nodes::UpdateStatement.new
48
+ statement2.relation = 'zomg'
49
+ statement2.wheres = 2
50
+ statement2.values = false
51
+ statement2.orders = %w[x y z]
52
+ statement2.limit = 42
53
+ statement2.key = 'wth'
54
+ array = [statement1, statement2]
55
+ assert_equal 2, array.uniq.size
56
+ end
57
+ end
18
58
  end
@@ -0,0 +1,73 @@
1
+ require 'helper'
2
+
3
+ module Arel
4
+ module Nodes
5
+ describe 'Window' do
6
+ describe 'equality' do
7
+ it 'is equal with equal ivars' do
8
+ window1 = Window.new
9
+ window1.orders = [1, 2]
10
+ window1.frame 3
11
+ window2 = Window.new
12
+ window2.orders = [1, 2]
13
+ window2.frame 3
14
+ array = [window1, window2]
15
+ assert_equal 1, array.uniq.size
16
+ end
17
+
18
+ it 'is not equal with different ivars' do
19
+ window1 = Window.new
20
+ window1.orders = [1, 2]
21
+ window1.frame 3
22
+ window2 = Window.new
23
+ window2.orders = [1, 2]
24
+ window2.frame 4
25
+ array = [window1, window2]
26
+ assert_equal 2, array.uniq.size
27
+ end
28
+ end
29
+ end
30
+
31
+ describe 'NamedWindow' do
32
+ describe 'equality' do
33
+ it 'is equal with equal ivars' do
34
+ window1 = NamedWindow.new 'foo'
35
+ window1.orders = [1, 2]
36
+ window1.frame 3
37
+ window2 = NamedWindow.new 'foo'
38
+ window2.orders = [1, 2]
39
+ window2.frame 3
40
+ array = [window1, window2]
41
+ assert_equal 1, array.uniq.size
42
+ end
43
+
44
+ it 'is not equal with different ivars' do
45
+ window1 = NamedWindow.new 'foo'
46
+ window1.orders = [1, 2]
47
+ window1.frame 3
48
+ window2 = NamedWindow.new 'bar'
49
+ window2.orders = [1, 2]
50
+ window2.frame 3
51
+ array = [window1, window2]
52
+ assert_equal 2, array.uniq.size
53
+ end
54
+ end
55
+ end
56
+
57
+ describe 'CurrentRow' do
58
+ describe 'equality' do
59
+ it 'is equal to other current row nodes' do
60
+ array = [CurrentRow.new, CurrentRow.new]
61
+ assert_equal 1, array.uniq.size
62
+ end
63
+
64
+ it 'is not equal with other nodes' do
65
+ array = [CurrentRow.new, Node.new]
66
+ assert_equal 2, array.uniq.size
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+
@@ -10,6 +10,18 @@ module Arel
10
10
  assert_equal [attribute], node.expressions
11
11
  end
12
12
 
13
+ describe 'equality' do
14
+ it 'is equal with equal ivars' do
15
+ array = [Attribute.new('foo', 'bar'), Attribute.new('foo', 'bar')]
16
+ assert_equal 1, array.uniq.size
17
+ end
18
+
19
+ it 'is not equal with different ivars' do
20
+ array = [Attribute.new('foo', 'bar'), Attribute.new('foo', 'baz')]
21
+ assert_equal 2, array.uniq.size
22
+ end
23
+ end
24
+
13
25
  describe 'for' do
14
26
  it 'deals with unknown column types' do
15
27
  column = Struct.new(:type).new :crazy
@@ -10,7 +10,6 @@ module Arel
10
10
 
11
11
  describe 'insert' do
12
12
  it 'can create a Values node' do
13
- table = Table.new(:users)
14
13
  manager = Arel::InsertManager.new Table.engine
15
14
  values = manager.create_values %w{ a b }, %w{ c d }
16
15
 
@@ -20,7 +19,6 @@ module Arel
20
19
  end
21
20
 
22
21
  it 'allows sql literals' do
23
- table = Table.new(:users)
24
22
  manager = Arel::InsertManager.new Table.engine
25
23
  manager.values = manager.create_values [Arel.sql('*')], %w{ a }
26
24
  manager.to_sql.must_be_like %{
@@ -119,7 +119,7 @@ module Arel
119
119
  manager = Arel::SelectManager.new Table.engine
120
120
  manager.project Arel.sql('name')
121
121
  manager.from as
122
- manager.to_sql.must_be_like "SELECT name FROM (SELECT * FROM zomg ) foo"
122
+ manager.to_sql.must_be_like "SELECT name FROM (SELECT * FROM zomg) foo"
123
123
  end
124
124
  end
125
125
 
@@ -147,7 +147,7 @@ module Arel
147
147
  manager1.from(as)
148
148
 
149
149
  manager1.to_sql.must_be_like %{
150
- SELECT lol FROM (SELECT * FROM "users" ) omg
150
+ SELECT lol FROM (SELECT * FROM "users") omg
151
151
  }
152
152
  end
153
153
  end
@@ -672,7 +672,6 @@ module Arel
672
672
  end
673
673
 
674
674
  it 'returns string join sql' do
675
- table = Table.new :users
676
675
  manager = Arel::SelectManager.new Table.engine
677
676
  manager.from Nodes::StringJoin.new('hello')
678
677
  manager.join_sql.must_be_like %{ 'hello' }
@@ -1033,6 +1032,14 @@ module Arel
1033
1032
  end
1034
1033
  end
1035
1034
 
1035
+ describe 'projections' do
1036
+ it 'reads projections' do
1037
+ manager = Arel::SelectManager.new Table.engine
1038
+ manager.project Arel.sql('foo'), Arel.sql('bar')
1039
+ manager.projections.must_equal [Arel.sql('foo'), Arel.sql('bar')]
1040
+ end
1041
+ end
1042
+
1036
1043
  describe 'projections=' do
1037
1044
  it 'overwrites projections' do
1038
1045
  manager = Arel::SelectManager.new Table.engine
@@ -1132,7 +1139,6 @@ module Arel
1132
1139
 
1133
1140
  describe 'source' do
1134
1141
  it 'returns the join source of the select core' do
1135
- table = Table.new :users
1136
1142
  manager = Arel::SelectManager.new Table.engine
1137
1143
  manager.source.must_equal manager.ast.cores.last.source
1138
1144
  end
@@ -1140,7 +1146,6 @@ module Arel
1140
1146
 
1141
1147
  describe 'distinct' do
1142
1148
  it 'sets the quantifier' do
1143
- table = Table.new :users
1144
1149
  manager = Arel::SelectManager.new Table.engine
1145
1150
 
1146
1151
  manager.distinct
@@ -180,5 +180,29 @@ module Arel
180
180
  end
181
181
  end
182
182
  end
183
+
184
+ describe 'equality' do
185
+ it 'is equal with equal ivars' do
186
+ relation1 = Table.new(:users, 'vroom')
187
+ relation1.aliases = %w[a b c]
188
+ relation1.table_alias = 'zomg'
189
+ relation2 = Table.new(:users, 'vroom')
190
+ relation2.aliases = %w[a b c]
191
+ relation2.table_alias = 'zomg'
192
+ array = [relation1, relation2]
193
+ assert_equal 1, array.uniq.size
194
+ end
195
+
196
+ it 'is not equal with different ivars' do
197
+ relation1 = Table.new(:users, 'vroom')
198
+ relation1.aliases = %w[a b c]
199
+ relation1.table_alias = 'zomg'
200
+ relation2 = Table.new(:users, 'vroom')
201
+ relation2.aliases = %w[x y z]
202
+ relation2.table_alias = 'zomg'
203
+ array = [relation1, relation2]
204
+ assert_equal 2, array.uniq.size
205
+ end
206
+ end
183
207
  end
184
208
  end
@@ -8,6 +8,14 @@ module Arel
8
8
  end
9
9
  end
10
10
 
11
+ it "should not quote sql literals" do
12
+ table = Table.new(:users)
13
+ um = Arel::UpdateManager.new Table.engine
14
+ um.table table
15
+ um.set [[table[:name], (Arel::Nodes::BindParam.new '?')]]
16
+ um.to_sql.must_be_like %{ UPDATE "users" SET "name" = ? }
17
+ end
18
+
11
19
  it 'handles limit properly' do
12
20
  table = Table.new(:users)
13
21
  um = Arel::UpdateManager.new Table.engine
@@ -1,9 +1,28 @@
1
1
  require 'helper'
2
2
  require 'arel/visitors/bind_visitor'
3
+ require 'support/fake_record'
3
4
 
4
5
  module Arel
5
6
  module Visitors
6
- class TestBindVisitor < MiniTest::Unit::TestCase
7
+ class TestBindVisitor < MiniTest::Unit::TestCase
8
+
9
+ ##
10
+ # Tests visit_Arel_Nodes_Assignment correctly
11
+ # substitutes binds with values from block
12
+ def test_assignment_binds_are_substituted
13
+ table = Table.new(:users)
14
+ um = Arel::UpdateManager.new Table.engine
15
+ bp = Nodes::BindParam.new '?'
16
+ um.set [[table[:name], bp]]
17
+ visitor = Class.new(Arel::Visitors::ToSql) {
18
+ include Arel::Visitors::BindVisitor
19
+ }.new Table.engine.connection
20
+
21
+ assignment = um.ast.values[0]
22
+ actual = visitor.accept(assignment) { "replace" }
23
+ actual.must_be_like "\"name\" = replace"
24
+ end
25
+
7
26
  def test_visitor_yields_on_binds
8
27
  visitor = Class.new(Arel::Visitors::Visitor) {
9
28
  def initialize omg
@@ -102,9 +102,8 @@ module Arel
102
102
  SELECT * FROM (
103
103
  SELECT raw_sql_.*, rownum raw_rnum_
104
104
  FROM (SELECT) raw_sql_
105
- WHERE rownum <= 20
106
105
  )
107
- WHERE raw_rnum_ > 10
106
+ WHERE raw_rnum_ >= 11 and rownum <= 10
108
107
  }
109
108
  end
110
109
 
@@ -48,6 +48,45 @@ module Arel
48
48
  sql.must_be_like %{ omg(*) = 2 }
49
49
  end
50
50
 
51
+ it 'should visit built-in functions' do
52
+ function = Nodes::Count.new([Arel.star])
53
+ assert_equal 'COUNT(*)', @visitor.accept(function)
54
+
55
+ function = Nodes::Sum.new([Arel.star])
56
+ assert_equal 'SUM(*)', @visitor.accept(function)
57
+
58
+ function = Nodes::Max.new([Arel.star])
59
+ assert_equal 'MAX(*)', @visitor.accept(function)
60
+
61
+ function = Nodes::Min.new([Arel.star])
62
+ assert_equal 'MIN(*)', @visitor.accept(function)
63
+
64
+ function = Nodes::Avg.new([Arel.star])
65
+ assert_equal 'AVG(*)', @visitor.accept(function)
66
+ end
67
+
68
+ it 'should visit built-in functions operating on distinct values' do
69
+ function = Nodes::Count.new([Arel.star])
70
+ function.distinct = true
71
+ assert_equal 'COUNT(DISTINCT *)', @visitor.accept(function)
72
+
73
+ function = Nodes::Sum.new([Arel.star])
74
+ function.distinct = true
75
+ assert_equal 'SUM(DISTINCT *)', @visitor.accept(function)
76
+
77
+ function = Nodes::Max.new([Arel.star])
78
+ function.distinct = true
79
+ assert_equal 'MAX(DISTINCT *)', @visitor.accept(function)
80
+
81
+ function = Nodes::Min.new([Arel.star])
82
+ function.distinct = true
83
+ assert_equal 'MIN(DISTINCT *)', @visitor.accept(function)
84
+
85
+ function = Nodes::Avg.new([Arel.star])
86
+ function.distinct = true
87
+ assert_equal 'AVG(DISTINCT *)', @visitor.accept(function)
88
+ end
89
+
51
90
  it 'works with lists' do
52
91
  function = Nodes::NamedFunction.new('omg', [Arel.star, Arel.star])
53
92
  assert_equal 'omg(*, *)', @visitor.accept(function)
@@ -126,6 +165,11 @@ module Arel
126
165
  @visitor.accept(nil).must_be_like "NULL"
127
166
  end
128
167
 
168
+ it "should visit_Arel_SelectManager, which is a subquery" do
169
+ mgr = Table.new(:foo).project(:bar)
170
+ @visitor.accept(mgr).must_be_like '(SELECT bar FROM "foo")'
171
+ end
172
+
129
173
  it "should visit_Arel_Nodes_And" do
130
174
  node = Nodes::And.new [@attr.eq(10), @attr.eq(11)]
131
175
  @visitor.accept(node).must_be_like %{