arel 3.0.3 → 4.0.0.beta1

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 (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 %{