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.
- checksums.yaml +7 -0
- data/.travis.yml +2 -2
- data/Gemfile +3 -4
- data/History.txt +0 -51
- data/Manifest.txt +8 -2
- data/README.markdown +1 -1
- data/Rakefile +1 -1
- data/arel.gemspec +21 -29
- data/lib/arel.rb +1 -3
- data/lib/arel/nodes.rb +1 -0
- data/lib/arel/nodes/and.rb +10 -0
- data/lib/arel/nodes/binary.rb +11 -0
- data/lib/arel/nodes/extract.rb +11 -0
- data/lib/arel/nodes/false.rb +7 -0
- data/lib/arel/nodes/function.rb +11 -0
- data/lib/arel/nodes/grouping.rb +7 -0
- data/lib/arel/nodes/insert_statement.rb +12 -0
- data/lib/arel/nodes/named_function.rb +9 -0
- data/lib/arel/nodes/select_core.rb +20 -0
- data/lib/arel/nodes/select_statement.rb +15 -1
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes/terminal.rb +7 -0
- data/lib/arel/nodes/true.rb +7 -0
- data/lib/arel/nodes/unary.rb +10 -1
- data/lib/arel/nodes/update_statement.rb +15 -0
- data/lib/arel/nodes/window.rb +30 -3
- data/lib/arel/select_manager.rb +4 -0
- data/lib/arel/table.rb +13 -0
- data/lib/arel/tree_manager.rb +0 -2
- data/lib/arel/visitors/bind_visitor.rb +10 -0
- data/lib/arel/visitors/dot.rb +1 -1
- data/lib/arel/visitors/oracle.rb +1 -2
- data/lib/arel/visitors/to_sql.rb +138 -27
- data/test/nodes/test_and.rb +20 -0
- data/test/nodes/test_as.rb +12 -0
- data/test/nodes/test_ascending.rb +10 -0
- data/test/nodes/test_bin.rb +10 -0
- data/test/nodes/test_count.rb +12 -0
- data/test/nodes/test_delete_statement.rb +20 -0
- data/test/nodes/test_descending.rb +10 -0
- data/test/nodes/test_distinct.rb +20 -0
- data/test/nodes/test_equality.rb +10 -0
- data/test/nodes/test_extract.rb +14 -0
- data/test/nodes/test_false.rb +20 -0
- data/test/nodes/test_grouping.rb +25 -0
- data/test/nodes/test_infix_operation.rb +10 -0
- data/test/nodes/test_insert_statement.rb +24 -0
- data/test/nodes/test_named_function.rb +16 -0
- data/test/nodes/test_not.rb +12 -0
- data/test/nodes/test_or.rb +12 -0
- data/test/nodes/test_over.rb +18 -0
- data/test/nodes/test_select_core.rb +38 -0
- data/test/nodes/test_select_statement.rb +36 -0
- data/test/nodes/test_sql_literal.rb +10 -0
- data/test/nodes/test_sum.rb +12 -0
- data/test/nodes/test_table_alias.rb +36 -0
- data/test/nodes/test_true.rb +21 -0
- data/test/nodes/test_update_statement.rb +40 -0
- data/test/nodes/test_window.rb +73 -0
- data/test/test_attributes.rb +12 -0
- data/test/test_insert_manager.rb +0 -2
- data/test/test_select_manager.rb +10 -5
- data/test/test_table.rb +24 -0
- data/test/test_update_manager.rb +8 -0
- data/test/visitors/test_bind_visitor.rb +20 -1
- data/test/visitors/test_oracle.rb +1 -2
- data/test/visitors/test_to_sql.rb +44 -0
- metadata +76 -86
- data/lib/arel/nodes/ordering.rb +0 -6
- 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
|
data/test/nodes/test_sum.rb
CHANGED
@@ -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
|
+
|
data/test/test_attributes.rb
CHANGED
@@ -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
|
data/test/test_insert_manager.rb
CHANGED
@@ -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 %{
|
data/test/test_select_manager.rb
CHANGED
@@ -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
|
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"
|
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
|
data/test/test_table.rb
CHANGED
@@ -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
|
data/test/test_update_manager.rb
CHANGED
@@ -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
|
@@ -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 %{
|