arel 6.0.0.beta2 → 6.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.
- checksums.yaml +4 -4
- data/History.txt +1 -1
- data/README.markdown +5 -5
- data/lib/arel.rb +1 -1
- data/lib/arel/collectors/sql_string.rb +7 -1
- data/lib/arel/expressions.rb +5 -4
- data/lib/arel/nodes.rb +1 -0
- data/lib/arel/nodes/bind_param.rb +6 -0
- data/lib/arel/nodes/sql_literal.rb +0 -3
- data/lib/arel/predications.rb +2 -2
- data/lib/arel/visitors/depth_first.rb +6 -0
- data/lib/arel/visitors/oracle.rb +4 -0
- data/lib/arel/visitors/postgresql.rb +4 -0
- data/lib/arel/visitors/reduce.rb +4 -4
- data/lib/arel/visitors/to_sql.rb +3 -2
- data/lib/arel/visitors/visitor.rb +15 -15
- metadata +26 -69
- data/.gitignore +0 -9
- data/.travis.yml +0 -18
- data/Gemfile +0 -5
- data/Rakefile +0 -15
- data/arel.gemspec +0 -24
- data/test/attributes/test_attribute.rb +0 -910
- data/test/collectors/test_bind_collector.rb +0 -70
- data/test/collectors/test_sql_string.rb +0 -38
- data/test/helper.rb +0 -22
- data/test/nodes/test_and.rb +0 -20
- data/test/nodes/test_as.rb +0 -34
- data/test/nodes/test_ascending.rb +0 -44
- data/test/nodes/test_bin.rb +0 -33
- data/test/nodes/test_binary.rb +0 -26
- data/test/nodes/test_count.rb +0 -33
- data/test/nodes/test_delete_statement.rb +0 -34
- data/test/nodes/test_descending.rb +0 -44
- data/test/nodes/test_distinct.rb +0 -20
- data/test/nodes/test_equality.rb +0 -84
- data/test/nodes/test_extract.rb +0 -41
- data/test/nodes/test_false.rb +0 -20
- data/test/nodes/test_grouping.rb +0 -25
- data/test/nodes/test_infix_operation.rb +0 -40
- data/test/nodes/test_insert_statement.rb +0 -42
- data/test/nodes/test_named_function.rb +0 -46
- data/test/nodes/test_node.rb +0 -39
- data/test/nodes/test_not.rb +0 -29
- data/test/nodes/test_or.rb +0 -34
- data/test/nodes/test_over.rb +0 -67
- data/test/nodes/test_select_core.rb +0 -69
- data/test/nodes/test_select_statement.rb +0 -49
- data/test/nodes/test_sql_literal.rb +0 -73
- data/test/nodes/test_sum.rb +0 -24
- data/test/nodes/test_table_alias.rb +0 -36
- data/test/nodes/test_true.rb +0 -21
- data/test/nodes/test_update_statement.rb +0 -58
- data/test/nodes/test_window.rb +0 -79
- data/test/support/fake_record.rb +0 -135
- data/test/test_attributes.rb +0 -66
- data/test/test_crud.rb +0 -63
- data/test/test_delete_manager.rb +0 -42
- data/test/test_factory_methods.rb +0 -44
- data/test/test_insert_manager.rb +0 -171
- data/test/test_select_manager.rb +0 -1181
- data/test/test_table.rb +0 -253
- data/test/test_update_manager.rb +0 -124
- data/test/visitors/test_bind_visitor.rb +0 -60
- data/test/visitors/test_depth_first.rb +0 -258
- data/test/visitors/test_dispatch_contamination.rb +0 -22
- data/test/visitors/test_dot.rb +0 -76
- data/test/visitors/test_ibm_db.rb +0 -33
- data/test/visitors/test_informix.rb +0 -58
- data/test/visitors/test_mssql.rb +0 -70
- data/test/visitors/test_mysql.rb +0 -60
- data/test/visitors/test_oracle.rb +0 -170
- data/test/visitors/test_postgres.rb +0 -122
- data/test/visitors/test_sqlite.rb +0 -23
- data/test/visitors/test_to_sql.rb +0 -598
data/test/test_attributes.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
module Arel
|
4
|
-
describe 'Attributes' do
|
5
|
-
it 'responds to lower' do
|
6
|
-
relation = Table.new(:users)
|
7
|
-
attribute = relation[:foo]
|
8
|
-
node = attribute.lower
|
9
|
-
assert_equal 'LOWER', node.name
|
10
|
-
assert_equal [attribute], node.expressions
|
11
|
-
end
|
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
|
-
|
25
|
-
describe 'for' do
|
26
|
-
it 'deals with unknown column types' do
|
27
|
-
column = Struct.new(:type).new :crazy
|
28
|
-
Attributes.for(column).must_equal Attributes::Undefined
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'returns the correct constant for strings' do
|
32
|
-
[:string, :text, :binary].each do |type|
|
33
|
-
column = Struct.new(:type).new type
|
34
|
-
Attributes.for(column).must_equal Attributes::String
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'returns the correct constant for ints' do
|
39
|
-
column = Struct.new(:type).new :integer
|
40
|
-
Attributes.for(column).must_equal Attributes::Integer
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'returns the correct constant for floats' do
|
44
|
-
column = Struct.new(:type).new :float
|
45
|
-
Attributes.for(column).must_equal Attributes::Float
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'returns the correct constant for decimals' do
|
49
|
-
column = Struct.new(:type).new :decimal
|
50
|
-
Attributes.for(column).must_equal Attributes::Decimal
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'returns the correct constant for boolean' do
|
54
|
-
column = Struct.new(:type).new :boolean
|
55
|
-
Attributes.for(column).must_equal Attributes::Boolean
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'returns the correct constant for time' do
|
59
|
-
[:date, :datetime, :timestamp, :time].each do |type|
|
60
|
-
column = Struct.new(:type).new type
|
61
|
-
Attributes.for(column).must_equal Attributes::Time
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
data/test/test_crud.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
module Arel
|
4
|
-
class FakeCrudder < SelectManager
|
5
|
-
class FakeEngine
|
6
|
-
attr_reader :calls, :connection_pool, :spec, :config
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@calls = []
|
10
|
-
@connection_pool = self
|
11
|
-
@spec = self
|
12
|
-
@config = { :adapter => 'sqlite3' }
|
13
|
-
end
|
14
|
-
|
15
|
-
def connection; self end
|
16
|
-
|
17
|
-
def method_missing name, *args
|
18
|
-
@calls << [name, args]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
include Crud
|
23
|
-
|
24
|
-
attr_reader :engine
|
25
|
-
attr_accessor :ctx
|
26
|
-
|
27
|
-
def initialize engine = FakeEngine.new
|
28
|
-
super
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe 'crud' do
|
33
|
-
describe 'insert' do
|
34
|
-
it 'should call insert on the connection' do
|
35
|
-
table = Table.new :users
|
36
|
-
fc = FakeCrudder.new
|
37
|
-
fc.from table
|
38
|
-
im = fc.compile_insert [[table[:id], 'foo']]
|
39
|
-
assert_instance_of Arel::InsertManager, im
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe 'update' do
|
44
|
-
it 'should call update on the connection' do
|
45
|
-
table = Table.new :users
|
46
|
-
fc = FakeCrudder.new
|
47
|
-
fc.from table
|
48
|
-
stmt = fc.compile_update [[table[:id], 'foo']], Arel::Attributes::Attribute.new(table, 'id')
|
49
|
-
assert_instance_of Arel::UpdateManager, stmt
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe 'delete' do
|
54
|
-
it 'should call delete on the connection' do
|
55
|
-
table = Table.new :users
|
56
|
-
fc = FakeCrudder.new
|
57
|
-
fc.from table
|
58
|
-
stmt = fc.compile_delete
|
59
|
-
assert_instance_of Arel::DeleteManager, stmt
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
data/test/test_delete_manager.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
module Arel
|
4
|
-
describe 'delete manager' do
|
5
|
-
describe 'new' do
|
6
|
-
it 'takes an engine' do
|
7
|
-
Arel::DeleteManager.new Table.engine
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
describe 'from' do
|
12
|
-
it 'uses from' do
|
13
|
-
table = Table.new(:users)
|
14
|
-
dm = Arel::DeleteManager.new Table.engine
|
15
|
-
dm.from table
|
16
|
-
dm.to_sql.must_be_like %{ DELETE FROM "users" }
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'chains' do
|
20
|
-
table = Table.new(:users)
|
21
|
-
dm = Arel::DeleteManager.new Table.engine
|
22
|
-
dm.from(table).must_equal dm
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe 'where' do
|
27
|
-
it 'uses where values' do
|
28
|
-
table = Table.new(:users)
|
29
|
-
dm = Arel::DeleteManager.new Table.engine
|
30
|
-
dm.from table
|
31
|
-
dm.where table[:id].eq(10)
|
32
|
-
dm.to_sql.must_be_like %{ DELETE FROM "users" WHERE "users"."id" = 10}
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'chains' do
|
36
|
-
table = Table.new(:users)
|
37
|
-
dm = Arel::DeleteManager.new Table.engine
|
38
|
-
dm.where(table[:id].eq(10)).must_equal dm
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
module Arel
|
4
|
-
module FactoryMethods
|
5
|
-
class TestFactoryMethods < Minitest::Test
|
6
|
-
class Factory
|
7
|
-
include Arel::FactoryMethods
|
8
|
-
end
|
9
|
-
|
10
|
-
def setup
|
11
|
-
@factory = Factory.new
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_create_join
|
15
|
-
join = @factory.create_join :one, :two
|
16
|
-
assert_kind_of Nodes::Join, join
|
17
|
-
assert_equal :two, join.right
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_create_on
|
21
|
-
on = @factory.create_on :one
|
22
|
-
assert_instance_of Nodes::On, on
|
23
|
-
assert_equal :one, on.expr
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_create_true
|
27
|
-
true_node = @factory.create_true
|
28
|
-
assert_instance_of Nodes::True, true_node
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_create_false
|
32
|
-
false_node = @factory.create_false
|
33
|
-
assert_instance_of Nodes::False, false_node
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_lower
|
37
|
-
lower = @factory.lower :one
|
38
|
-
assert_instance_of Nodes::NamedFunction, lower
|
39
|
-
assert_equal 'LOWER', lower.name
|
40
|
-
assert_equal [:one], lower.expressions.map(&:expr)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
data/test/test_insert_manager.rb
DELETED
@@ -1,171 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
module Arel
|
4
|
-
describe 'insert manager' do
|
5
|
-
describe 'new' do
|
6
|
-
it 'takes an engine' do
|
7
|
-
Arel::InsertManager.new Table.engine
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
describe 'insert' do
|
12
|
-
it 'can create a Values node' do
|
13
|
-
manager = Arel::InsertManager.new Table.engine
|
14
|
-
values = manager.create_values %w{ a b }, %w{ c d }
|
15
|
-
|
16
|
-
assert_kind_of Arel::Nodes::Values, values
|
17
|
-
assert_equal %w{ a b }, values.left
|
18
|
-
assert_equal %w{ c d }, values.right
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'allows sql literals' do
|
22
|
-
manager = Arel::InsertManager.new Table.engine
|
23
|
-
manager.into Table.new(:users)
|
24
|
-
manager.values = manager.create_values [Arel.sql('*')], %w{ a }
|
25
|
-
manager.to_sql.must_be_like %{
|
26
|
-
INSERT INTO \"users\" VALUES (*)
|
27
|
-
}
|
28
|
-
end
|
29
|
-
|
30
|
-
it "inserts false" do
|
31
|
-
table = Table.new(:users)
|
32
|
-
manager = Arel::InsertManager.new Table.engine
|
33
|
-
|
34
|
-
manager.insert [[table[:bool], false]]
|
35
|
-
manager.to_sql.must_be_like %{
|
36
|
-
INSERT INTO "users" ("bool") VALUES ('f')
|
37
|
-
}
|
38
|
-
end
|
39
|
-
|
40
|
-
it "inserts null" do
|
41
|
-
table = Table.new(:users)
|
42
|
-
manager = Arel::InsertManager.new Table.engine
|
43
|
-
manager.insert [[table[:id], nil]]
|
44
|
-
manager.to_sql.must_be_like %{
|
45
|
-
INSERT INTO "users" ("id") VALUES (NULL)
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
it "inserts time" do
|
50
|
-
table = Table.new(:users)
|
51
|
-
manager = Arel::InsertManager.new Table.engine
|
52
|
-
|
53
|
-
time = Time.now
|
54
|
-
attribute = table[:created_at]
|
55
|
-
|
56
|
-
manager.insert [[attribute, time]]
|
57
|
-
manager.to_sql.must_be_like %{
|
58
|
-
INSERT INTO "users" ("created_at") VALUES (#{Table.engine.connection.quote time})
|
59
|
-
}
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'takes a list of lists' do
|
63
|
-
table = Table.new(:users)
|
64
|
-
manager = Arel::InsertManager.new Table.engine
|
65
|
-
manager.into table
|
66
|
-
manager.insert [[table[:id], 1], [table[:name], 'aaron']]
|
67
|
-
manager.to_sql.must_be_like %{
|
68
|
-
INSERT INTO "users" ("id", "name") VALUES (1, 'aaron')
|
69
|
-
}
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'defaults the table' do
|
73
|
-
table = Table.new(:users)
|
74
|
-
manager = Arel::InsertManager.new Table.engine
|
75
|
-
manager.insert [[table[:id], 1], [table[:name], 'aaron']]
|
76
|
-
manager.to_sql.must_be_like %{
|
77
|
-
INSERT INTO "users" ("id", "name") VALUES (1, 'aaron')
|
78
|
-
}
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'noop for empty list' do
|
82
|
-
table = Table.new(:users)
|
83
|
-
manager = Arel::InsertManager.new Table.engine
|
84
|
-
manager.insert [[table[:id], 1]]
|
85
|
-
manager.insert []
|
86
|
-
manager.to_sql.must_be_like %{
|
87
|
-
INSERT INTO "users" ("id") VALUES (1)
|
88
|
-
}
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
describe 'into' do
|
93
|
-
it 'takes a Table and chains' do
|
94
|
-
manager = Arel::InsertManager.new Table.engine
|
95
|
-
manager.into(Table.new(:users)).must_equal manager
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'converts to sql' do
|
99
|
-
table = Table.new :users
|
100
|
-
manager = Arel::InsertManager.new Table.engine
|
101
|
-
manager.into table
|
102
|
-
manager.to_sql.must_be_like %{
|
103
|
-
INSERT INTO "users"
|
104
|
-
}
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
describe 'columns' do
|
109
|
-
it "converts to sql" do
|
110
|
-
table = Table.new :users
|
111
|
-
manager = Arel::InsertManager.new Table.engine
|
112
|
-
manager.into table
|
113
|
-
manager.columns << table[:id]
|
114
|
-
manager.to_sql.must_be_like %{
|
115
|
-
INSERT INTO "users" ("id")
|
116
|
-
}
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
describe "values" do
|
121
|
-
it "converts to sql" do
|
122
|
-
table = Table.new :users
|
123
|
-
manager = Arel::InsertManager.new Table.engine
|
124
|
-
manager.into table
|
125
|
-
|
126
|
-
manager.values = Nodes::Values.new [1]
|
127
|
-
manager.to_sql.must_be_like %{
|
128
|
-
INSERT INTO "users" VALUES (1)
|
129
|
-
}
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
describe "combo" do
|
134
|
-
it "combines columns and values list in order" do
|
135
|
-
table = Table.new :users
|
136
|
-
manager = Arel::InsertManager.new Table.engine
|
137
|
-
manager.into table
|
138
|
-
|
139
|
-
manager.values = Nodes::Values.new [1, 'aaron']
|
140
|
-
manager.columns << table[:id]
|
141
|
-
manager.columns << table[:name]
|
142
|
-
manager.to_sql.must_be_like %{
|
143
|
-
INSERT INTO "users" ("id", "name") VALUES (1, 'aaron')
|
144
|
-
}
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
describe "select" do
|
149
|
-
|
150
|
-
it "accepts a select query in place of a VALUES clause" do
|
151
|
-
table = Table.new :users
|
152
|
-
|
153
|
-
manager = Arel::InsertManager.new Table.engine
|
154
|
-
manager.into table
|
155
|
-
|
156
|
-
select = Arel::SelectManager.new Table.engine
|
157
|
-
select.project Arel.sql('1')
|
158
|
-
select.project Arel.sql('"aaron"')
|
159
|
-
|
160
|
-
manager.select select
|
161
|
-
manager.columns << table[:id]
|
162
|
-
manager.columns << table[:name]
|
163
|
-
manager.to_sql.must_be_like %{
|
164
|
-
INSERT INTO "users" ("id", "name") (SELECT 1, "aaron")
|
165
|
-
}
|
166
|
-
end
|
167
|
-
|
168
|
-
end
|
169
|
-
|
170
|
-
end
|
171
|
-
end
|
data/test/test_select_manager.rb
DELETED
@@ -1,1181 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
module Arel
|
4
|
-
|
5
|
-
describe 'select manager' do
|
6
|
-
def test_join_sources
|
7
|
-
manager = Arel::SelectManager.new Table.engine
|
8
|
-
manager.join_sources << Arel::Nodes::StringJoin.new(Nodes.build_quoted('foo'))
|
9
|
-
assert_equal "SELECT FROM 'foo'", manager.to_sql
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_manager_stores_bind_values
|
13
|
-
manager = Arel::SelectManager.new Table.engine
|
14
|
-
assert_equal [], manager.bind_values
|
15
|
-
manager.bind_values = [1]
|
16
|
-
assert_equal [1], manager.bind_values
|
17
|
-
end
|
18
|
-
|
19
|
-
describe 'backwards compatibility' do
|
20
|
-
describe 'project' do
|
21
|
-
it 'accepts symbols as sql literals' do
|
22
|
-
table = Table.new :users
|
23
|
-
manager = Arel::SelectManager.new Table.engine
|
24
|
-
manager.project :id
|
25
|
-
manager.from table
|
26
|
-
manager.to_sql.must_be_like %{
|
27
|
-
SELECT id FROM "users"
|
28
|
-
}
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe 'order' do
|
33
|
-
it 'accepts symbols' do
|
34
|
-
table = Table.new :users
|
35
|
-
manager = Arel::SelectManager.new Table.engine
|
36
|
-
manager.project Nodes::SqlLiteral.new '*'
|
37
|
-
manager.from table
|
38
|
-
manager.order :foo
|
39
|
-
manager.to_sql.must_be_like %{ SELECT * FROM "users" ORDER BY foo }
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe 'group' do
|
44
|
-
it 'takes a symbol' do
|
45
|
-
table = Table.new :users
|
46
|
-
manager = Arel::SelectManager.new Table.engine
|
47
|
-
manager.from table
|
48
|
-
manager.group :foo
|
49
|
-
manager.to_sql.must_be_like %{ SELECT FROM "users" GROUP BY foo }
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe 'as' do
|
54
|
-
it 'makes an AS node by grouping the AST' do
|
55
|
-
manager = Arel::SelectManager.new Table.engine
|
56
|
-
as = manager.as(Arel.sql('foo'))
|
57
|
-
assert_kind_of Arel::Nodes::Grouping, as.left
|
58
|
-
assert_equal manager.ast, as.left.expr
|
59
|
-
assert_equal 'foo', as.right
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'converts right to SqlLiteral if a string' do
|
63
|
-
manager = Arel::SelectManager.new Table.engine
|
64
|
-
as = manager.as('foo')
|
65
|
-
assert_kind_of Arel::Nodes::SqlLiteral, as.right
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'can make a subselect' do
|
69
|
-
manager = Arel::SelectManager.new Table.engine
|
70
|
-
manager.project Arel.star
|
71
|
-
manager.from Arel.sql('zomg')
|
72
|
-
as = manager.as(Arel.sql('foo'))
|
73
|
-
|
74
|
-
manager = Arel::SelectManager.new Table.engine
|
75
|
-
manager.project Arel.sql('name')
|
76
|
-
manager.from as
|
77
|
-
manager.to_sql.must_be_like "SELECT name FROM (SELECT * FROM zomg) foo"
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
describe 'from' do
|
82
|
-
it 'ignores strings when table of same name exists' do
|
83
|
-
table = Table.new :users
|
84
|
-
manager = Arel::SelectManager.new Table.engine
|
85
|
-
|
86
|
-
manager.from table
|
87
|
-
manager.from 'users'
|
88
|
-
manager.project table['id']
|
89
|
-
manager.to_sql.must_be_like 'SELECT "users"."id" FROM users'
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'should support any ast' do
|
93
|
-
table = Table.new :users
|
94
|
-
manager1 = Arel::SelectManager.new Table.engine
|
95
|
-
|
96
|
-
manager2 = Arel::SelectManager.new Table.engine
|
97
|
-
manager2.project(Arel.sql('*'))
|
98
|
-
manager2.from table
|
99
|
-
|
100
|
-
manager1.project Arel.sql('lol')
|
101
|
-
as = manager2.as Arel.sql('omg')
|
102
|
-
manager1.from(as)
|
103
|
-
|
104
|
-
manager1.to_sql.must_be_like %{
|
105
|
-
SELECT lol FROM (SELECT * FROM "users") omg
|
106
|
-
}
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
describe 'having' do
|
111
|
-
it 'converts strings to SQLLiterals' do
|
112
|
-
table = Table.new :users
|
113
|
-
mgr = table.from table
|
114
|
-
mgr.having 'foo'
|
115
|
-
mgr.to_sql.must_be_like %{ SELECT FROM "users" HAVING foo }
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'can have multiple items specified separately' do
|
119
|
-
table = Table.new :users
|
120
|
-
mgr = table.from table
|
121
|
-
mgr.having 'foo'
|
122
|
-
mgr.having 'bar'
|
123
|
-
mgr.to_sql.must_be_like %{ SELECT FROM "users" HAVING foo AND bar }
|
124
|
-
end
|
125
|
-
|
126
|
-
it 'can have multiple items specified together' do
|
127
|
-
table = Table.new :users
|
128
|
-
mgr = table.from table
|
129
|
-
mgr.having 'foo', 'bar'
|
130
|
-
mgr.to_sql.must_be_like %{ SELECT FROM "users" HAVING foo AND bar }
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
describe 'on' do
|
135
|
-
it 'converts to sqlliterals' do
|
136
|
-
table = Table.new :users
|
137
|
-
right = table.alias
|
138
|
-
mgr = table.from table
|
139
|
-
mgr.join(right).on("omg")
|
140
|
-
mgr.to_sql.must_be_like %{ SELECT FROM "users" INNER JOIN "users" "users_2" ON omg }
|
141
|
-
end
|
142
|
-
|
143
|
-
it 'converts to sqlliterals with multiple items' do
|
144
|
-
table = Table.new :users
|
145
|
-
right = table.alias
|
146
|
-
mgr = table.from table
|
147
|
-
mgr.join(right).on("omg", "123")
|
148
|
-
mgr.to_sql.must_be_like %{ SELECT FROM "users" INNER JOIN "users" "users_2" ON omg AND 123 }
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
describe 'clone' do
|
154
|
-
it 'creates new cores' do
|
155
|
-
table = Table.new :users, :as => 'foo'
|
156
|
-
mgr = table.from table
|
157
|
-
m2 = mgr.clone
|
158
|
-
m2.project "foo"
|
159
|
-
mgr.to_sql.wont_equal m2.to_sql
|
160
|
-
end
|
161
|
-
|
162
|
-
it 'makes updates to the correct copy' do
|
163
|
-
table = Table.new :users, :as => 'foo'
|
164
|
-
mgr = table.from table
|
165
|
-
m2 = mgr.clone
|
166
|
-
m3 = m2.clone
|
167
|
-
m2.project "foo"
|
168
|
-
mgr.to_sql.wont_equal m2.to_sql
|
169
|
-
m3.to_sql.must_equal mgr.to_sql
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
describe 'initialize' do
|
174
|
-
it 'uses alias in sql' do
|
175
|
-
table = Table.new :users, :as => 'foo'
|
176
|
-
mgr = table.from table
|
177
|
-
mgr.skip 10
|
178
|
-
mgr.to_sql.must_be_like %{ SELECT FROM "users" "foo" OFFSET 10 }
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
describe 'skip' do
|
183
|
-
it 'should add an offset' do
|
184
|
-
table = Table.new :users
|
185
|
-
mgr = table.from table
|
186
|
-
mgr.skip 10
|
187
|
-
mgr.to_sql.must_be_like %{ SELECT FROM "users" OFFSET 10 }
|
188
|
-
end
|
189
|
-
|
190
|
-
it 'should chain' do
|
191
|
-
table = Table.new :users
|
192
|
-
mgr = table.from table
|
193
|
-
mgr.skip(10).to_sql.must_be_like %{ SELECT FROM "users" OFFSET 10 }
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
describe 'offset' do
|
198
|
-
it 'should add an offset' do
|
199
|
-
table = Table.new :users
|
200
|
-
mgr = table.from table
|
201
|
-
mgr.offset = 10
|
202
|
-
mgr.to_sql.must_be_like %{ SELECT FROM "users" OFFSET 10 }
|
203
|
-
end
|
204
|
-
|
205
|
-
it 'should remove an offset' do
|
206
|
-
table = Table.new :users
|
207
|
-
mgr = table.from table
|
208
|
-
mgr.offset = 10
|
209
|
-
mgr.to_sql.must_be_like %{ SELECT FROM "users" OFFSET 10 }
|
210
|
-
|
211
|
-
mgr.offset = nil
|
212
|
-
mgr.to_sql.must_be_like %{ SELECT FROM "users" }
|
213
|
-
end
|
214
|
-
|
215
|
-
it 'should return the offset' do
|
216
|
-
table = Table.new :users
|
217
|
-
mgr = table.from table
|
218
|
-
mgr.offset = 10
|
219
|
-
assert_equal 10, mgr.offset
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
describe 'exists' do
|
224
|
-
it 'should create an exists clause' do
|
225
|
-
table = Table.new(:users)
|
226
|
-
manager = Arel::SelectManager.new Table.engine, table
|
227
|
-
manager.project Nodes::SqlLiteral.new '*'
|
228
|
-
m2 = Arel::SelectManager.new(manager.engine)
|
229
|
-
m2.project manager.exists
|
230
|
-
m2.to_sql.must_be_like %{ SELECT EXISTS (#{manager.to_sql}) }
|
231
|
-
end
|
232
|
-
|
233
|
-
it 'can be aliased' do
|
234
|
-
table = Table.new(:users)
|
235
|
-
manager = Arel::SelectManager.new Table.engine, table
|
236
|
-
manager.project Nodes::SqlLiteral.new '*'
|
237
|
-
m2 = Arel::SelectManager.new(manager.engine)
|
238
|
-
m2.project manager.exists.as('foo')
|
239
|
-
m2.to_sql.must_be_like %{ SELECT EXISTS (#{manager.to_sql}) AS foo }
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
describe 'union' do
|
244
|
-
before do
|
245
|
-
table = Table.new :users
|
246
|
-
@m1 = Arel::SelectManager.new Table.engine, table
|
247
|
-
@m1.project Arel.star
|
248
|
-
@m1.where(table[:age].lt(18))
|
249
|
-
|
250
|
-
@m2 = Arel::SelectManager.new Table.engine, table
|
251
|
-
@m2.project Arel.star
|
252
|
-
@m2.where(table[:age].gt(99))
|
253
|
-
|
254
|
-
|
255
|
-
end
|
256
|
-
|
257
|
-
it 'should union two managers' do
|
258
|
-
# FIXME should this union "managers" or "statements" ?
|
259
|
-
# FIXME this probably shouldn't return a node
|
260
|
-
node = @m1.union @m2
|
261
|
-
|
262
|
-
# maybe FIXME: decide when wrapper parens are needed
|
263
|
-
node.to_sql.must_be_like %{
|
264
|
-
( SELECT * FROM "users" WHERE "users"."age" < 18 UNION SELECT * FROM "users" WHERE "users"."age" > 99 )
|
265
|
-
}
|
266
|
-
end
|
267
|
-
|
268
|
-
it 'should union all' do
|
269
|
-
node = @m1.union :all, @m2
|
270
|
-
|
271
|
-
node.to_sql.must_be_like %{
|
272
|
-
( SELECT * FROM "users" WHERE "users"."age" < 18 UNION ALL SELECT * FROM "users" WHERE "users"."age" > 99 )
|
273
|
-
}
|
274
|
-
end
|
275
|
-
|
276
|
-
end
|
277
|
-
|
278
|
-
describe 'intersect' do
|
279
|
-
before do
|
280
|
-
table = Table.new :users
|
281
|
-
@m1 = Arel::SelectManager.new Table.engine, table
|
282
|
-
@m1.project Arel.star
|
283
|
-
@m1.where(table[:age].gt(18))
|
284
|
-
|
285
|
-
@m2 = Arel::SelectManager.new Table.engine, table
|
286
|
-
@m2.project Arel.star
|
287
|
-
@m2.where(table[:age].lt(99))
|
288
|
-
|
289
|
-
|
290
|
-
end
|
291
|
-
|
292
|
-
it 'should interect two managers' do
|
293
|
-
# FIXME should this intersect "managers" or "statements" ?
|
294
|
-
# FIXME this probably shouldn't return a node
|
295
|
-
node = @m1.intersect @m2
|
296
|
-
|
297
|
-
# maybe FIXME: decide when wrapper parens are needed
|
298
|
-
node.to_sql.must_be_like %{
|
299
|
-
( SELECT * FROM "users" WHERE "users"."age" > 18 INTERSECT SELECT * FROM "users" WHERE "users"."age" < 99 )
|
300
|
-
}
|
301
|
-
end
|
302
|
-
|
303
|
-
end
|
304
|
-
|
305
|
-
describe 'except' do
|
306
|
-
before do
|
307
|
-
table = Table.new :users
|
308
|
-
@m1 = Arel::SelectManager.new Table.engine, table
|
309
|
-
@m1.project Arel.star
|
310
|
-
@m1.where(table[:age].between(18..60))
|
311
|
-
|
312
|
-
@m2 = Arel::SelectManager.new Table.engine, table
|
313
|
-
@m2.project Arel.star
|
314
|
-
@m2.where(table[:age].between(40..99))
|
315
|
-
end
|
316
|
-
|
317
|
-
it 'should except two managers' do
|
318
|
-
# FIXME should this except "managers" or "statements" ?
|
319
|
-
# FIXME this probably shouldn't return a node
|
320
|
-
node = @m1.except @m2
|
321
|
-
|
322
|
-
# maybe FIXME: decide when wrapper parens are needed
|
323
|
-
node.to_sql.must_be_like %{
|
324
|
-
( SELECT * FROM "users" WHERE "users"."age" BETWEEN 18 AND 60 EXCEPT SELECT * FROM "users" WHERE "users"."age" BETWEEN 40 AND 99 )
|
325
|
-
}
|
326
|
-
end
|
327
|
-
|
328
|
-
end
|
329
|
-
|
330
|
-
describe 'with' do
|
331
|
-
it 'should support basic WITH' do
|
332
|
-
users = Table.new(:users)
|
333
|
-
users_top = Table.new(:users_top)
|
334
|
-
comments = Table.new(:comments)
|
335
|
-
|
336
|
-
top = users.project(users[:id]).where(users[:karma].gt(100))
|
337
|
-
users_as = Arel::Nodes::As.new(users_top, top)
|
338
|
-
select_manager = comments.project(Arel.star).with(users_as)
|
339
|
-
.where(comments[:author_id].in(users_top.project(users_top[:id])))
|
340
|
-
|
341
|
-
select_manager.to_sql.must_be_like %{
|
342
|
-
WITH "users_top" AS (SELECT "users"."id" FROM "users" WHERE "users"."karma" > 100) SELECT * FROM "comments" WHERE "comments"."author_id" IN (SELECT "users_top"."id" FROM "users_top")
|
343
|
-
}
|
344
|
-
end
|
345
|
-
|
346
|
-
it "should support WITH RECURSIVE" do
|
347
|
-
comments = Table.new(:comments)
|
348
|
-
comments_id = comments[:id]
|
349
|
-
comments_parent_id = comments[:parent_id]
|
350
|
-
|
351
|
-
replies = Table.new(:replies)
|
352
|
-
replies_id = replies[:id]
|
353
|
-
|
354
|
-
recursive_term = Arel::SelectManager.new Table.engine
|
355
|
-
recursive_term.from(comments).project(comments_id, comments_parent_id).where(comments_id.eq 42)
|
356
|
-
|
357
|
-
non_recursive_term = Arel::SelectManager.new Table.engine
|
358
|
-
non_recursive_term.from(comments).project(comments_id, comments_parent_id).join(replies).on(comments_parent_id.eq replies_id)
|
359
|
-
|
360
|
-
union = recursive_term.union(non_recursive_term)
|
361
|
-
|
362
|
-
as_statement = Arel::Nodes::As.new replies, union
|
363
|
-
|
364
|
-
manager = Arel::SelectManager.new Table.engine
|
365
|
-
manager.with(:recursive, as_statement).from(replies).project(Arel.star)
|
366
|
-
|
367
|
-
sql = manager.to_sql
|
368
|
-
sql.must_be_like %{
|
369
|
-
WITH RECURSIVE "replies" AS (
|
370
|
-
SELECT "comments"."id", "comments"."parent_id" FROM "comments" WHERE "comments"."id" = 42
|
371
|
-
UNION
|
372
|
-
SELECT "comments"."id", "comments"."parent_id" FROM "comments" INNER JOIN "replies" ON "comments"."parent_id" = "replies"."id"
|
373
|
-
)
|
374
|
-
SELECT * FROM "replies"
|
375
|
-
}
|
376
|
-
end
|
377
|
-
end
|
378
|
-
|
379
|
-
describe 'ast' do
|
380
|
-
it 'should return the ast' do
|
381
|
-
table = Table.new :users
|
382
|
-
mgr = table.from table
|
383
|
-
assert mgr.ast
|
384
|
-
end
|
385
|
-
|
386
|
-
it 'should allow orders to work when the ast is grepped' do
|
387
|
-
table = Table.new :users
|
388
|
-
mgr = table.from table
|
389
|
-
mgr.project Arel.sql '*'
|
390
|
-
mgr.from table
|
391
|
-
mgr.orders << Arel::Nodes::Ascending.new(Arel.sql('foo'))
|
392
|
-
mgr.ast.grep(Arel::Nodes::OuterJoin)
|
393
|
-
mgr.to_sql.must_be_like %{ SELECT * FROM "users" ORDER BY foo ASC }
|
394
|
-
end
|
395
|
-
end
|
396
|
-
|
397
|
-
describe 'taken' do
|
398
|
-
it 'should return limit' do
|
399
|
-
manager = Arel::SelectManager.new Table.engine
|
400
|
-
manager.take 10
|
401
|
-
manager.taken.must_equal 10
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
|
-
describe 'lock' do
|
406
|
-
# This should fail on other databases
|
407
|
-
it 'adds a lock node' do
|
408
|
-
table = Table.new :users
|
409
|
-
mgr = table.from table
|
410
|
-
mgr.lock.to_sql.must_be_like %{ SELECT FROM "users" FOR UPDATE }
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
|
-
describe 'orders' do
|
415
|
-
it 'returns order clauses' do
|
416
|
-
table = Table.new :users
|
417
|
-
manager = Arel::SelectManager.new Table.engine
|
418
|
-
order = table[:id]
|
419
|
-
manager.order table[:id]
|
420
|
-
manager.orders.must_equal [order]
|
421
|
-
end
|
422
|
-
end
|
423
|
-
|
424
|
-
describe 'order' do
|
425
|
-
it 'generates order clauses' do
|
426
|
-
table = Table.new :users
|
427
|
-
manager = Arel::SelectManager.new Table.engine
|
428
|
-
manager.project Nodes::SqlLiteral.new '*'
|
429
|
-
manager.from table
|
430
|
-
manager.order table[:id]
|
431
|
-
manager.to_sql.must_be_like %{
|
432
|
-
SELECT * FROM "users" ORDER BY "users"."id"
|
433
|
-
}
|
434
|
-
end
|
435
|
-
|
436
|
-
# FIXME: I would like to deprecate this
|
437
|
-
it 'takes *args' do
|
438
|
-
table = Table.new :users
|
439
|
-
manager = Arel::SelectManager.new Table.engine
|
440
|
-
manager.project Nodes::SqlLiteral.new '*'
|
441
|
-
manager.from table
|
442
|
-
manager.order table[:id], table[:name]
|
443
|
-
manager.to_sql.must_be_like %{
|
444
|
-
SELECT * FROM "users" ORDER BY "users"."id", "users"."name"
|
445
|
-
}
|
446
|
-
end
|
447
|
-
|
448
|
-
it 'chains' do
|
449
|
-
table = Table.new :users
|
450
|
-
manager = Arel::SelectManager.new Table.engine
|
451
|
-
manager.order(table[:id]).must_equal manager
|
452
|
-
end
|
453
|
-
|
454
|
-
it 'has order attributes' do
|
455
|
-
table = Table.new :users
|
456
|
-
manager = Arel::SelectManager.new Table.engine
|
457
|
-
manager.project Nodes::SqlLiteral.new '*'
|
458
|
-
manager.from table
|
459
|
-
manager.order table[:id].desc
|
460
|
-
manager.to_sql.must_be_like %{
|
461
|
-
SELECT * FROM "users" ORDER BY "users"."id" DESC
|
462
|
-
}
|
463
|
-
end
|
464
|
-
end
|
465
|
-
|
466
|
-
describe 'on' do
|
467
|
-
it 'takes two params' do
|
468
|
-
left = Table.new :users
|
469
|
-
right = left.alias
|
470
|
-
predicate = left[:id].eq(right[:id])
|
471
|
-
manager = Arel::SelectManager.new Table.engine
|
472
|
-
|
473
|
-
manager.from left
|
474
|
-
manager.join(right).on(predicate, predicate)
|
475
|
-
manager.to_sql.must_be_like %{
|
476
|
-
SELECT FROM "users"
|
477
|
-
INNER JOIN "users" "users_2"
|
478
|
-
ON "users"."id" = "users_2"."id" AND
|
479
|
-
"users"."id" = "users_2"."id"
|
480
|
-
}
|
481
|
-
end
|
482
|
-
|
483
|
-
it 'takes three params' do
|
484
|
-
left = Table.new :users
|
485
|
-
right = left.alias
|
486
|
-
predicate = left[:id].eq(right[:id])
|
487
|
-
manager = Arel::SelectManager.new Table.engine
|
488
|
-
|
489
|
-
manager.from left
|
490
|
-
manager.join(right).on(
|
491
|
-
predicate,
|
492
|
-
predicate,
|
493
|
-
left[:name].eq(right[:name])
|
494
|
-
)
|
495
|
-
manager.to_sql.must_be_like %{
|
496
|
-
SELECT FROM "users"
|
497
|
-
INNER JOIN "users" "users_2"
|
498
|
-
ON "users"."id" = "users_2"."id" AND
|
499
|
-
"users"."id" = "users_2"."id" AND
|
500
|
-
"users"."name" = "users_2"."name"
|
501
|
-
}
|
502
|
-
end
|
503
|
-
end
|
504
|
-
|
505
|
-
it 'should hand back froms' do
|
506
|
-
relation = Arel::SelectManager.new Table.engine
|
507
|
-
assert_equal [], relation.froms
|
508
|
-
end
|
509
|
-
|
510
|
-
it 'should create and nodes' do
|
511
|
-
relation = Arel::SelectManager.new Table.engine
|
512
|
-
children = ['foo', 'bar', 'baz']
|
513
|
-
clause = relation.create_and children
|
514
|
-
assert_kind_of Arel::Nodes::And, clause
|
515
|
-
assert_equal children, clause.children
|
516
|
-
end
|
517
|
-
|
518
|
-
it 'should create insert managers' do
|
519
|
-
relation = Arel::SelectManager.new Table.engine
|
520
|
-
insert = relation.create_insert
|
521
|
-
assert_kind_of Arel::InsertManager, insert
|
522
|
-
end
|
523
|
-
|
524
|
-
it 'should create join nodes' do
|
525
|
-
relation = Arel::SelectManager.new Table.engine
|
526
|
-
join = relation.create_join 'foo', 'bar'
|
527
|
-
assert_kind_of Arel::Nodes::InnerJoin, join
|
528
|
-
assert_equal 'foo', join.left
|
529
|
-
assert_equal 'bar', join.right
|
530
|
-
end
|
531
|
-
|
532
|
-
it 'should create join nodes with a full outer join klass' do
|
533
|
-
relation = Arel::SelectManager.new Table.engine
|
534
|
-
join = relation.create_join 'foo', 'bar', Arel::Nodes::FullOuterJoin
|
535
|
-
assert_kind_of Arel::Nodes::FullOuterJoin, join
|
536
|
-
assert_equal 'foo', join.left
|
537
|
-
assert_equal 'bar', join.right
|
538
|
-
end
|
539
|
-
|
540
|
-
it 'should create join nodes with a outer join klass' do
|
541
|
-
relation = Arel::SelectManager.new Table.engine
|
542
|
-
join = relation.create_join 'foo', 'bar', Arel::Nodes::OuterJoin
|
543
|
-
assert_kind_of Arel::Nodes::OuterJoin, join
|
544
|
-
assert_equal 'foo', join.left
|
545
|
-
assert_equal 'bar', join.right
|
546
|
-
end
|
547
|
-
|
548
|
-
it 'should create join nodes with a right outer join klass' do
|
549
|
-
relation = Arel::SelectManager.new Table.engine
|
550
|
-
join = relation.create_join 'foo', 'bar', Arel::Nodes::RightOuterJoin
|
551
|
-
assert_kind_of Arel::Nodes::RightOuterJoin, join
|
552
|
-
assert_equal 'foo', join.left
|
553
|
-
assert_equal 'bar', join.right
|
554
|
-
end
|
555
|
-
|
556
|
-
describe 'join' do
|
557
|
-
it 'responds to join' do
|
558
|
-
left = Table.new :users
|
559
|
-
right = left.alias
|
560
|
-
predicate = left[:id].eq(right[:id])
|
561
|
-
manager = Arel::SelectManager.new Table.engine
|
562
|
-
|
563
|
-
manager.from left
|
564
|
-
manager.join(right).on(predicate)
|
565
|
-
manager.to_sql.must_be_like %{
|
566
|
-
SELECT FROM "users"
|
567
|
-
INNER JOIN "users" "users_2"
|
568
|
-
ON "users"."id" = "users_2"."id"
|
569
|
-
}
|
570
|
-
end
|
571
|
-
|
572
|
-
it 'takes a class' do
|
573
|
-
left = Table.new :users
|
574
|
-
right = left.alias
|
575
|
-
predicate = left[:id].eq(right[:id])
|
576
|
-
manager = Arel::SelectManager.new Table.engine
|
577
|
-
|
578
|
-
manager.from left
|
579
|
-
manager.join(right, Nodes::OuterJoin).on(predicate)
|
580
|
-
manager.to_sql.must_be_like %{
|
581
|
-
SELECT FROM "users"
|
582
|
-
LEFT OUTER JOIN "users" "users_2"
|
583
|
-
ON "users"."id" = "users_2"."id"
|
584
|
-
}
|
585
|
-
end
|
586
|
-
|
587
|
-
it 'noops on nil' do
|
588
|
-
manager = Arel::SelectManager.new Table.engine
|
589
|
-
manager.join(nil).must_equal manager
|
590
|
-
end
|
591
|
-
end
|
592
|
-
|
593
|
-
describe 'outer join' do
|
594
|
-
it 'responds to join' do
|
595
|
-
left = Table.new :users
|
596
|
-
right = left.alias
|
597
|
-
predicate = left[:id].eq(right[:id])
|
598
|
-
manager = Arel::SelectManager.new Table.engine
|
599
|
-
|
600
|
-
manager.from left
|
601
|
-
manager.outer_join(right).on(predicate)
|
602
|
-
manager.to_sql.must_be_like %{
|
603
|
-
SELECT FROM "users"
|
604
|
-
LEFT OUTER JOIN "users" "users_2"
|
605
|
-
ON "users"."id" = "users_2"."id"
|
606
|
-
}
|
607
|
-
end
|
608
|
-
|
609
|
-
it 'noops on nil' do
|
610
|
-
manager = Arel::SelectManager.new Table.engine
|
611
|
-
manager.outer_join(nil).must_equal manager
|
612
|
-
end
|
613
|
-
end
|
614
|
-
|
615
|
-
describe 'joins' do
|
616
|
-
|
617
|
-
it 'returns inner join sql' do
|
618
|
-
table = Table.new :users
|
619
|
-
aliaz = table.alias
|
620
|
-
manager = Arel::SelectManager.new Table.engine
|
621
|
-
manager.from Nodes::InnerJoin.new(aliaz, table[:id].eq(aliaz[:id]))
|
622
|
-
assert_match 'INNER JOIN "users" "users_2" "users"."id" = "users_2"."id"',
|
623
|
-
manager.to_sql
|
624
|
-
end
|
625
|
-
|
626
|
-
it 'returns outer join sql' do
|
627
|
-
table = Table.new :users
|
628
|
-
aliaz = table.alias
|
629
|
-
manager = Arel::SelectManager.new Table.engine
|
630
|
-
manager.from Nodes::OuterJoin.new(aliaz, table[:id].eq(aliaz[:id]))
|
631
|
-
assert_match 'LEFT OUTER JOIN "users" "users_2" "users"."id" = "users_2"."id"',
|
632
|
-
manager.to_sql
|
633
|
-
end
|
634
|
-
|
635
|
-
it 'can have a non-table alias as relation name' do
|
636
|
-
users = Table.new :users
|
637
|
-
comments = Table.new :comments
|
638
|
-
|
639
|
-
counts = comments.from(comments).
|
640
|
-
group(comments[:user_id]).
|
641
|
-
project(
|
642
|
-
comments[:user_id].as("user_id"),
|
643
|
-
comments[:user_id].count.as("count")
|
644
|
-
).as("counts")
|
645
|
-
|
646
|
-
joins = users.join(counts).on(counts[:user_id].eq(10))
|
647
|
-
joins.to_sql.must_be_like %{
|
648
|
-
SELECT FROM "users" INNER JOIN (SELECT "comments"."user_id" AS user_id, COUNT("comments"."user_id") AS count FROM "comments" GROUP BY "comments"."user_id") counts ON counts."user_id" = 10
|
649
|
-
}
|
650
|
-
end
|
651
|
-
|
652
|
-
it "joins itself" do
|
653
|
-
left = Table.new :users
|
654
|
-
right = left.alias
|
655
|
-
predicate = left[:id].eq(right[:id])
|
656
|
-
|
657
|
-
mgr = left.join(right)
|
658
|
-
mgr.project Nodes::SqlLiteral.new('*')
|
659
|
-
mgr.on(predicate).must_equal mgr
|
660
|
-
|
661
|
-
mgr.to_sql.must_be_like %{
|
662
|
-
SELECT * FROM "users"
|
663
|
-
INNER JOIN "users" "users_2"
|
664
|
-
ON "users"."id" = "users_2"."id"
|
665
|
-
}
|
666
|
-
end
|
667
|
-
|
668
|
-
it 'returns string join sql' do
|
669
|
-
manager = Arel::SelectManager.new Table.engine
|
670
|
-
manager.from Nodes::StringJoin.new(Nodes.build_quoted('hello'))
|
671
|
-
assert_match "'hello'", manager.to_sql
|
672
|
-
end
|
673
|
-
end
|
674
|
-
|
675
|
-
describe 'group' do
|
676
|
-
it 'takes an attribute' do
|
677
|
-
table = Table.new :users
|
678
|
-
manager = Arel::SelectManager.new Table.engine
|
679
|
-
manager.from table
|
680
|
-
manager.group table[:id]
|
681
|
-
manager.to_sql.must_be_like %{
|
682
|
-
SELECT FROM "users" GROUP BY "users"."id"
|
683
|
-
}
|
684
|
-
end
|
685
|
-
|
686
|
-
it 'chains' do
|
687
|
-
table = Table.new :users
|
688
|
-
manager = Arel::SelectManager.new Table.engine
|
689
|
-
manager.group(table[:id]).must_equal manager
|
690
|
-
end
|
691
|
-
|
692
|
-
it 'takes multiple args' do
|
693
|
-
table = Table.new :users
|
694
|
-
manager = Arel::SelectManager.new Table.engine
|
695
|
-
manager.from table
|
696
|
-
manager.group table[:id], table[:name]
|
697
|
-
manager.to_sql.must_be_like %{
|
698
|
-
SELECT FROM "users" GROUP BY "users"."id", "users"."name"
|
699
|
-
}
|
700
|
-
end
|
701
|
-
|
702
|
-
# FIXME: backwards compat
|
703
|
-
it 'makes strings literals' do
|
704
|
-
table = Table.new :users
|
705
|
-
manager = Arel::SelectManager.new Table.engine
|
706
|
-
manager.from table
|
707
|
-
manager.group 'foo'
|
708
|
-
manager.to_sql.must_be_like %{ SELECT FROM "users" GROUP BY foo }
|
709
|
-
end
|
710
|
-
end
|
711
|
-
|
712
|
-
describe 'window definition' do
|
713
|
-
it 'can be empty' do
|
714
|
-
table = Table.new :users
|
715
|
-
manager = Arel::SelectManager.new Table.engine
|
716
|
-
manager.from table
|
717
|
-
manager.window('a_window')
|
718
|
-
manager.to_sql.must_be_like %{
|
719
|
-
SELECT FROM "users" WINDOW "a_window" AS ()
|
720
|
-
}
|
721
|
-
end
|
722
|
-
|
723
|
-
it 'takes an order' do
|
724
|
-
table = Table.new :users
|
725
|
-
manager = Arel::SelectManager.new Table.engine
|
726
|
-
manager.from table
|
727
|
-
manager.window('a_window').order(table['foo'].asc)
|
728
|
-
manager.to_sql.must_be_like %{
|
729
|
-
SELECT FROM "users" WINDOW "a_window" AS (ORDER BY "users"."foo" ASC)
|
730
|
-
}
|
731
|
-
end
|
732
|
-
|
733
|
-
it 'takes an order with multiple columns' do
|
734
|
-
table = Table.new :users
|
735
|
-
manager = Arel::SelectManager.new Table.engine
|
736
|
-
manager.from table
|
737
|
-
manager.window('a_window').order(table['foo'].asc, table['bar'].desc)
|
738
|
-
manager.to_sql.must_be_like %{
|
739
|
-
SELECT FROM "users" WINDOW "a_window" AS (ORDER BY "users"."foo" ASC, "users"."bar" DESC)
|
740
|
-
}
|
741
|
-
end
|
742
|
-
|
743
|
-
it 'takes a partition' do
|
744
|
-
table = Table.new :users
|
745
|
-
manager = Arel::SelectManager.new Table.engine
|
746
|
-
manager.from table
|
747
|
-
manager.window('a_window').partition(table['bar'])
|
748
|
-
manager.to_sql.must_be_like %{
|
749
|
-
SELECT FROM "users" WINDOW "a_window" AS (PARTITION BY "users"."bar")
|
750
|
-
}
|
751
|
-
end
|
752
|
-
|
753
|
-
it 'takes a partition and an order' do
|
754
|
-
table = Table.new :users
|
755
|
-
manager = Arel::SelectManager.new Table.engine
|
756
|
-
manager.from table
|
757
|
-
manager.window('a_window').partition(table['foo']).order(table['foo'].asc)
|
758
|
-
manager.to_sql.must_be_like %{
|
759
|
-
SELECT FROM "users" WINDOW "a_window" AS (PARTITION BY "users"."foo"
|
760
|
-
ORDER BY "users"."foo" ASC)
|
761
|
-
}
|
762
|
-
end
|
763
|
-
|
764
|
-
it 'takes a partition with multiple columns' do
|
765
|
-
table = Table.new :users
|
766
|
-
manager = Arel::SelectManager.new Table.engine
|
767
|
-
manager.from table
|
768
|
-
manager.window('a_window').partition(table['bar'], table['baz'])
|
769
|
-
manager.to_sql.must_be_like %{
|
770
|
-
SELECT FROM "users" WINDOW "a_window" AS (PARTITION BY "users"."bar", "users"."baz")
|
771
|
-
}
|
772
|
-
end
|
773
|
-
|
774
|
-
it 'takes a rows frame, unbounded preceding' do
|
775
|
-
table = Table.new :users
|
776
|
-
manager = Arel::SelectManager.new Table.engine
|
777
|
-
manager.from table
|
778
|
-
manager.window('a_window').rows(Arel::Nodes::Preceding.new)
|
779
|
-
manager.to_sql.must_be_like %{
|
780
|
-
SELECT FROM "users" WINDOW "a_window" AS (ROWS UNBOUNDED PRECEDING)
|
781
|
-
}
|
782
|
-
end
|
783
|
-
|
784
|
-
it 'takes a rows frame, bounded preceding' do
|
785
|
-
table = Table.new :users
|
786
|
-
manager = Arel::SelectManager.new Table.engine
|
787
|
-
manager.from table
|
788
|
-
manager.window('a_window').rows(Arel::Nodes::Preceding.new(5))
|
789
|
-
manager.to_sql.must_be_like %{
|
790
|
-
SELECT FROM "users" WINDOW "a_window" AS (ROWS 5 PRECEDING)
|
791
|
-
}
|
792
|
-
end
|
793
|
-
|
794
|
-
it 'takes a rows frame, unbounded following' do
|
795
|
-
table = Table.new :users
|
796
|
-
manager = Arel::SelectManager.new Table.engine
|
797
|
-
manager.from table
|
798
|
-
manager.window('a_window').rows(Arel::Nodes::Following.new)
|
799
|
-
manager.to_sql.must_be_like %{
|
800
|
-
SELECT FROM "users" WINDOW "a_window" AS (ROWS UNBOUNDED FOLLOWING)
|
801
|
-
}
|
802
|
-
end
|
803
|
-
|
804
|
-
it 'takes a rows frame, bounded following' do
|
805
|
-
table = Table.new :users
|
806
|
-
manager = Arel::SelectManager.new Table.engine
|
807
|
-
manager.from table
|
808
|
-
manager.window('a_window').rows(Arel::Nodes::Following.new(5))
|
809
|
-
manager.to_sql.must_be_like %{
|
810
|
-
SELECT FROM "users" WINDOW "a_window" AS (ROWS 5 FOLLOWING)
|
811
|
-
}
|
812
|
-
end
|
813
|
-
|
814
|
-
it 'takes a rows frame, current row' do
|
815
|
-
table = Table.new :users
|
816
|
-
manager = Arel::SelectManager.new Table.engine
|
817
|
-
manager.from table
|
818
|
-
manager.window('a_window').rows(Arel::Nodes::CurrentRow.new)
|
819
|
-
manager.to_sql.must_be_like %{
|
820
|
-
SELECT FROM "users" WINDOW "a_window" AS (ROWS CURRENT ROW)
|
821
|
-
}
|
822
|
-
end
|
823
|
-
|
824
|
-
it 'takes a rows frame, between two delimiters' do
|
825
|
-
table = Table.new :users
|
826
|
-
manager = Arel::SelectManager.new Table.engine
|
827
|
-
manager.from table
|
828
|
-
window = manager.window('a_window')
|
829
|
-
window.frame(
|
830
|
-
Arel::Nodes::Between.new(
|
831
|
-
window.rows,
|
832
|
-
Nodes::And.new([
|
833
|
-
Arel::Nodes::Preceding.new,
|
834
|
-
Arel::Nodes::CurrentRow.new
|
835
|
-
])))
|
836
|
-
manager.to_sql.must_be_like %{
|
837
|
-
SELECT FROM "users" WINDOW "a_window" AS (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
|
838
|
-
}
|
839
|
-
end
|
840
|
-
|
841
|
-
it 'takes a range frame, unbounded preceding' do
|
842
|
-
table = Table.new :users
|
843
|
-
manager = Arel::SelectManager.new Table.engine
|
844
|
-
manager.from table
|
845
|
-
manager.window('a_window').range(Arel::Nodes::Preceding.new)
|
846
|
-
manager.to_sql.must_be_like %{
|
847
|
-
SELECT FROM "users" WINDOW "a_window" AS (RANGE UNBOUNDED PRECEDING)
|
848
|
-
}
|
849
|
-
end
|
850
|
-
|
851
|
-
it 'takes a range frame, bounded preceding' do
|
852
|
-
table = Table.new :users
|
853
|
-
manager = Arel::SelectManager.new Table.engine
|
854
|
-
manager.from table
|
855
|
-
manager.window('a_window').range(Arel::Nodes::Preceding.new(5))
|
856
|
-
manager.to_sql.must_be_like %{
|
857
|
-
SELECT FROM "users" WINDOW "a_window" AS (RANGE 5 PRECEDING)
|
858
|
-
}
|
859
|
-
end
|
860
|
-
|
861
|
-
it 'takes a range frame, unbounded following' do
|
862
|
-
table = Table.new :users
|
863
|
-
manager = Arel::SelectManager.new Table.engine
|
864
|
-
manager.from table
|
865
|
-
manager.window('a_window').range(Arel::Nodes::Following.new)
|
866
|
-
manager.to_sql.must_be_like %{
|
867
|
-
SELECT FROM "users" WINDOW "a_window" AS (RANGE UNBOUNDED FOLLOWING)
|
868
|
-
}
|
869
|
-
end
|
870
|
-
|
871
|
-
it 'takes a range frame, bounded following' do
|
872
|
-
table = Table.new :users
|
873
|
-
manager = Arel::SelectManager.new Table.engine
|
874
|
-
manager.from table
|
875
|
-
manager.window('a_window').range(Arel::Nodes::Following.new(5))
|
876
|
-
manager.to_sql.must_be_like %{
|
877
|
-
SELECT FROM "users" WINDOW "a_window" AS (RANGE 5 FOLLOWING)
|
878
|
-
}
|
879
|
-
end
|
880
|
-
|
881
|
-
it 'takes a range frame, current row' do
|
882
|
-
table = Table.new :users
|
883
|
-
manager = Arel::SelectManager.new Table.engine
|
884
|
-
manager.from table
|
885
|
-
manager.window('a_window').range(Arel::Nodes::CurrentRow.new)
|
886
|
-
manager.to_sql.must_be_like %{
|
887
|
-
SELECT FROM "users" WINDOW "a_window" AS (RANGE CURRENT ROW)
|
888
|
-
}
|
889
|
-
end
|
890
|
-
|
891
|
-
it 'takes a range frame, between two delimiters' do
|
892
|
-
table = Table.new :users
|
893
|
-
manager = Arel::SelectManager.new Table.engine
|
894
|
-
manager.from table
|
895
|
-
window = manager.window('a_window')
|
896
|
-
window.frame(
|
897
|
-
Arel::Nodes::Between.new(
|
898
|
-
window.range,
|
899
|
-
Nodes::And.new([
|
900
|
-
Arel::Nodes::Preceding.new,
|
901
|
-
Arel::Nodes::CurrentRow.new
|
902
|
-
])))
|
903
|
-
manager.to_sql.must_be_like %{
|
904
|
-
SELECT FROM "users" WINDOW "a_window" AS (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
|
905
|
-
}
|
906
|
-
end
|
907
|
-
end
|
908
|
-
|
909
|
-
describe 'delete' do
|
910
|
-
it "copies from" do
|
911
|
-
table = Table.new :users
|
912
|
-
manager = Arel::SelectManager.new Table.engine
|
913
|
-
manager.from table
|
914
|
-
stmt = manager.compile_delete
|
915
|
-
|
916
|
-
stmt.to_sql.must_be_like %{ DELETE FROM "users" }
|
917
|
-
end
|
918
|
-
|
919
|
-
it "copies where" do
|
920
|
-
table = Table.new :users
|
921
|
-
manager = Arel::SelectManager.new Table.engine
|
922
|
-
manager.from table
|
923
|
-
manager.where table[:id].eq 10
|
924
|
-
stmt = manager.compile_delete
|
925
|
-
|
926
|
-
stmt.to_sql.must_be_like %{
|
927
|
-
DELETE FROM "users" WHERE "users"."id" = 10
|
928
|
-
}
|
929
|
-
end
|
930
|
-
end
|
931
|
-
|
932
|
-
describe 'where_sql' do
|
933
|
-
it 'gives me back the where sql' do
|
934
|
-
table = Table.new :users
|
935
|
-
manager = Arel::SelectManager.new Table.engine
|
936
|
-
manager.from table
|
937
|
-
manager.where table[:id].eq 10
|
938
|
-
manager.where_sql.must_be_like %{ WHERE "users"."id" = 10 }
|
939
|
-
end
|
940
|
-
|
941
|
-
it 'returns nil when there are no wheres' do
|
942
|
-
table = Table.new :users
|
943
|
-
manager = Arel::SelectManager.new Table.engine
|
944
|
-
manager.from table
|
945
|
-
manager.where_sql.must_be_nil
|
946
|
-
end
|
947
|
-
end
|
948
|
-
|
949
|
-
describe 'update' do
|
950
|
-
|
951
|
-
it 'creates an update statement' do
|
952
|
-
table = Table.new :users
|
953
|
-
manager = Arel::SelectManager.new Table.engine
|
954
|
-
manager.from table
|
955
|
-
stmt = manager.compile_update({table[:id] => 1}, Arel::Attributes::Attribute.new(table, 'id'))
|
956
|
-
|
957
|
-
stmt.to_sql.must_be_like %{
|
958
|
-
UPDATE "users" SET "id" = 1
|
959
|
-
}
|
960
|
-
end
|
961
|
-
|
962
|
-
it 'takes a string' do
|
963
|
-
table = Table.new :users
|
964
|
-
manager = Arel::SelectManager.new Table.engine
|
965
|
-
manager.from table
|
966
|
-
stmt = manager.compile_update(Nodes::SqlLiteral.new('foo = bar'), Arel::Attributes::Attribute.new(table, 'id'))
|
967
|
-
|
968
|
-
stmt.to_sql.must_be_like %{ UPDATE "users" SET foo = bar }
|
969
|
-
end
|
970
|
-
|
971
|
-
it 'copies limits' do
|
972
|
-
table = Table.new :users
|
973
|
-
manager = Arel::SelectManager.new Table.engine
|
974
|
-
manager.from table
|
975
|
-
manager.take 1
|
976
|
-
stmt = manager.compile_update(Nodes::SqlLiteral.new('foo = bar'), Arel::Attributes::Attribute.new(table, 'id'))
|
977
|
-
stmt.key = table['id']
|
978
|
-
|
979
|
-
stmt.to_sql.must_be_like %{
|
980
|
-
UPDATE "users" SET foo = bar
|
981
|
-
WHERE "users"."id" IN (SELECT "users"."id" FROM "users" LIMIT 1)
|
982
|
-
}
|
983
|
-
end
|
984
|
-
|
985
|
-
it 'copies order' do
|
986
|
-
table = Table.new :users
|
987
|
-
manager = Arel::SelectManager.new Table.engine
|
988
|
-
manager.from table
|
989
|
-
manager.order :foo
|
990
|
-
stmt = manager.compile_update(Nodes::SqlLiteral.new('foo = bar'), Arel::Attributes::Attribute.new(table, 'id'))
|
991
|
-
stmt.key = table['id']
|
992
|
-
|
993
|
-
stmt.to_sql.must_be_like %{
|
994
|
-
UPDATE "users" SET foo = bar
|
995
|
-
WHERE "users"."id" IN (SELECT "users"."id" FROM "users" ORDER BY foo)
|
996
|
-
}
|
997
|
-
end
|
998
|
-
|
999
|
-
it 'copies where clauses' do
|
1000
|
-
table = Table.new :users
|
1001
|
-
manager = Arel::SelectManager.new Table.engine
|
1002
|
-
manager.where table[:id].eq 10
|
1003
|
-
manager.from table
|
1004
|
-
stmt = manager.compile_update({table[:id] => 1}, Arel::Attributes::Attribute.new(table, 'id'))
|
1005
|
-
|
1006
|
-
stmt.to_sql.must_be_like %{
|
1007
|
-
UPDATE "users" SET "id" = 1 WHERE "users"."id" = 10
|
1008
|
-
}
|
1009
|
-
end
|
1010
|
-
|
1011
|
-
it 'copies where clauses when nesting is triggered' do
|
1012
|
-
table = Table.new :users
|
1013
|
-
manager = Arel::SelectManager.new Table.engine
|
1014
|
-
manager.where table[:foo].eq 10
|
1015
|
-
manager.take 42
|
1016
|
-
manager.from table
|
1017
|
-
stmt = manager.compile_update({table[:id] => 1}, Arel::Attributes::Attribute.new(table, 'id'))
|
1018
|
-
|
1019
|
-
stmt.to_sql.must_be_like %{
|
1020
|
-
UPDATE "users" SET "id" = 1 WHERE "users"."id" IN (SELECT "users"."id" FROM "users" WHERE "users"."foo" = 10 LIMIT 42)
|
1021
|
-
}
|
1022
|
-
end
|
1023
|
-
|
1024
|
-
end
|
1025
|
-
|
1026
|
-
describe 'project' do
|
1027
|
-
it "takes sql literals" do
|
1028
|
-
manager = Arel::SelectManager.new Table.engine
|
1029
|
-
manager.project Nodes::SqlLiteral.new '*'
|
1030
|
-
manager.to_sql.must_be_like %{ SELECT * }
|
1031
|
-
end
|
1032
|
-
|
1033
|
-
it 'takes multiple args' do
|
1034
|
-
manager = Arel::SelectManager.new Table.engine
|
1035
|
-
manager.project Nodes::SqlLiteral.new('foo'),
|
1036
|
-
Nodes::SqlLiteral.new('bar')
|
1037
|
-
manager.to_sql.must_be_like %{ SELECT foo, bar }
|
1038
|
-
end
|
1039
|
-
|
1040
|
-
it 'takes strings' do
|
1041
|
-
manager = Arel::SelectManager.new Table.engine
|
1042
|
-
manager.project '*'
|
1043
|
-
manager.to_sql.must_be_like %{ SELECT * }
|
1044
|
-
end
|
1045
|
-
|
1046
|
-
end
|
1047
|
-
|
1048
|
-
describe 'projections' do
|
1049
|
-
it 'reads projections' do
|
1050
|
-
manager = Arel::SelectManager.new Table.engine
|
1051
|
-
manager.project Arel.sql('foo'), Arel.sql('bar')
|
1052
|
-
manager.projections.must_equal [Arel.sql('foo'), Arel.sql('bar')]
|
1053
|
-
end
|
1054
|
-
end
|
1055
|
-
|
1056
|
-
describe 'projections=' do
|
1057
|
-
it 'overwrites projections' do
|
1058
|
-
manager = Arel::SelectManager.new Table.engine
|
1059
|
-
manager.project Arel.sql('foo')
|
1060
|
-
manager.projections = [Arel.sql('bar')]
|
1061
|
-
manager.to_sql.must_be_like %{ SELECT bar }
|
1062
|
-
end
|
1063
|
-
end
|
1064
|
-
|
1065
|
-
describe 'take' do
|
1066
|
-
it "knows take" do
|
1067
|
-
table = Table.new :users
|
1068
|
-
manager = Arel::SelectManager.new Table.engine
|
1069
|
-
manager.from(table).project(table['id'])
|
1070
|
-
manager.where(table['id'].eq(1))
|
1071
|
-
manager.take 1
|
1072
|
-
|
1073
|
-
manager.to_sql.must_be_like %{
|
1074
|
-
SELECT "users"."id"
|
1075
|
-
FROM "users"
|
1076
|
-
WHERE "users"."id" = 1
|
1077
|
-
LIMIT 1
|
1078
|
-
}
|
1079
|
-
end
|
1080
|
-
|
1081
|
-
it "chains" do
|
1082
|
-
manager = Arel::SelectManager.new Table.engine
|
1083
|
-
manager.take(1).must_equal manager
|
1084
|
-
end
|
1085
|
-
|
1086
|
-
it 'removes LIMIT when nil is passed' do
|
1087
|
-
manager = Arel::SelectManager.new Table.engine
|
1088
|
-
manager.limit = 10
|
1089
|
-
assert_match('LIMIT', manager.to_sql)
|
1090
|
-
|
1091
|
-
manager.limit = nil
|
1092
|
-
refute_match('LIMIT', manager.to_sql)
|
1093
|
-
end
|
1094
|
-
end
|
1095
|
-
|
1096
|
-
describe 'where' do
|
1097
|
-
it "knows where" do
|
1098
|
-
table = Table.new :users
|
1099
|
-
manager = Arel::SelectManager.new Table.engine
|
1100
|
-
manager.from(table).project(table['id'])
|
1101
|
-
manager.where(table['id'].eq(1))
|
1102
|
-
manager.to_sql.must_be_like %{
|
1103
|
-
SELECT "users"."id"
|
1104
|
-
FROM "users"
|
1105
|
-
WHERE "users"."id" = 1
|
1106
|
-
}
|
1107
|
-
end
|
1108
|
-
|
1109
|
-
it "chains" do
|
1110
|
-
table = Table.new :users
|
1111
|
-
manager = Arel::SelectManager.new Table.engine
|
1112
|
-
manager.from(table)
|
1113
|
-
manager.project(table['id']).where(table['id'].eq 1).must_equal manager
|
1114
|
-
end
|
1115
|
-
end
|
1116
|
-
|
1117
|
-
describe 'from' do
|
1118
|
-
it "makes sql" do
|
1119
|
-
table = Table.new :users
|
1120
|
-
manager = Arel::SelectManager.new Table.engine
|
1121
|
-
|
1122
|
-
manager.from table
|
1123
|
-
manager.project table['id']
|
1124
|
-
manager.to_sql.must_be_like 'SELECT "users"."id" FROM "users"'
|
1125
|
-
end
|
1126
|
-
|
1127
|
-
it "chains" do
|
1128
|
-
table = Table.new :users
|
1129
|
-
manager = Arel::SelectManager.new Table.engine
|
1130
|
-
manager.from(table).project(table['id']).must_equal manager
|
1131
|
-
manager.to_sql.must_be_like 'SELECT "users"."id" FROM "users"'
|
1132
|
-
end
|
1133
|
-
end
|
1134
|
-
|
1135
|
-
describe 'source' do
|
1136
|
-
it 'returns the join source of the select core' do
|
1137
|
-
manager = Arel::SelectManager.new Table.engine
|
1138
|
-
manager.source.must_equal manager.ast.cores.last.source
|
1139
|
-
end
|
1140
|
-
end
|
1141
|
-
|
1142
|
-
describe 'distinct' do
|
1143
|
-
it 'sets the quantifier' do
|
1144
|
-
manager = Arel::SelectManager.new Table.engine
|
1145
|
-
|
1146
|
-
manager.distinct
|
1147
|
-
manager.ast.cores.last.set_quantifier.class.must_equal Arel::Nodes::Distinct
|
1148
|
-
|
1149
|
-
manager.distinct(false)
|
1150
|
-
manager.ast.cores.last.set_quantifier.must_equal nil
|
1151
|
-
end
|
1152
|
-
|
1153
|
-
it "chains" do
|
1154
|
-
manager = Arel::SelectManager.new Table.engine
|
1155
|
-
manager.distinct.must_equal manager
|
1156
|
-
manager.distinct(false).must_equal manager
|
1157
|
-
end
|
1158
|
-
end
|
1159
|
-
|
1160
|
-
describe 'distinct_on' do
|
1161
|
-
it 'sets the quantifier' do
|
1162
|
-
manager = Arel::SelectManager.new Table.engine
|
1163
|
-
table = Table.new :users
|
1164
|
-
|
1165
|
-
manager.distinct_on(table['id'])
|
1166
|
-
manager.ast.cores.last.set_quantifier.must_equal Arel::Nodes::DistinctOn.new(table['id'])
|
1167
|
-
|
1168
|
-
manager.distinct_on(false)
|
1169
|
-
manager.ast.cores.last.set_quantifier.must_equal nil
|
1170
|
-
end
|
1171
|
-
|
1172
|
-
it "chains" do
|
1173
|
-
manager = Arel::SelectManager.new Table.engine
|
1174
|
-
table = Table.new :users
|
1175
|
-
|
1176
|
-
manager.distinct_on(table['id']).must_equal manager
|
1177
|
-
manager.distinct_on(false).must_equal manager
|
1178
|
-
end
|
1179
|
-
end
|
1180
|
-
end
|
1181
|
-
end
|