arel 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +26 -0
- data/History.txt +18 -0
- data/Manifest.txt +31 -30
- data/README.markdown +7 -99
- data/Rakefile +3 -2
- data/arel.gemspec +18 -11
- data/lib/arel.rb +2 -1
- data/lib/arel/attributes/attribute.rb +1 -174
- data/lib/arel/crud.rb +2 -2
- data/lib/arel/delete_manager.rb +4 -4
- data/lib/arel/insert_manager.rb +8 -8
- data/lib/arel/nodes/exists.rb +2 -6
- data/lib/arel/nodes/sql_literal.rb +1 -0
- data/lib/arel/predications.rb +177 -0
- data/lib/arel/select_manager.rb +17 -11
- data/lib/arel/table.rb +4 -0
- data/lib/arel/tree_manager.rb +4 -3
- data/lib/arel/update_manager.rb +8 -8
- data/lib/arel/visitors.rb +4 -0
- data/lib/arel/visitors/dot.rb +3 -3
- data/lib/arel/visitors/join_sql.rb +2 -0
- data/lib/arel/visitors/mysql.rb +14 -0
- data/lib/arel/visitors/oracle.rb +31 -1
- data/lib/arel/visitors/order_clauses.rb +2 -0
- data/lib/arel/visitors/sqlite.rb +11 -0
- data/lib/arel/visitors/to_sql.rb +8 -11
- data/lib/arel/visitors/visitor.rb +19 -0
- data/{spec/attributes/attribute_spec.rb → test/attributes/test_attribute.rb} +84 -84
- data/test/helper.rb +13 -0
- data/{spec/nodes/count_spec.rb → test/nodes/test_count.rb} +3 -3
- data/{spec/nodes/delete_statement_spec.rb → test/nodes/test_delete_statement.rb} +3 -4
- data/{spec/nodes/equality_spec.rb → test/nodes/test_equality.rb} +10 -8
- data/{spec/nodes/insert_statement_spec.rb → test/nodes/test_insert_statement.rb} +6 -6
- data/{spec/nodes/or_spec.rb → test/nodes/test_or.rb} +6 -4
- data/test/nodes/test_select_core.rb +22 -0
- data/{spec/nodes/select_statement_spec.rb → test/nodes/test_select_statement.rb} +3 -4
- data/test/nodes/test_sql_literal.rb +52 -0
- data/{spec/nodes/sum_spec.rb → test/nodes/test_sum.rb} +2 -2
- data/{spec/nodes/update_statement_spec.rb → test/nodes/test_update_statement.rb} +6 -6
- data/{spec → test}/support/fake_record.rb +4 -2
- data/{spec/activerecord_compat_spec.rb → test/test_activerecord_compat.rb} +3 -3
- data/{spec/attributes_spec.rb → test/test_attributes.rb} +7 -7
- data/{spec/crud_spec.rb → test/test_crud.rb} +4 -4
- data/{spec/delete_manager_spec.rb → test/test_delete_manager.rb} +5 -16
- data/{spec/insert_manager_spec.rb → test/test_insert_manager.rb} +15 -31
- data/{spec/select_manager_spec.rb → test/test_select_manager.rb} +95 -77
- data/{spec/table_spec.rb → test/test_table.rb} +38 -32
- data/{spec/update_manager_spec.rb → test/test_update_manager.rb} +9 -21
- data/{spec/visitors/join_sql_spec.rb → test/visitors/test_join_sql.rb} +3 -3
- data/test/visitors/test_mysql.rb +27 -0
- data/{spec/visitors/oracle_spec.rb → test/visitors/test_oracle.rb} +26 -10
- data/{spec/visitors/postgres_spec.rb → test/visitors/test_postgres.rb} +2 -2
- data/test/visitors/test_sqlite.rb +18 -0
- data/{spec/visitors/to_sql_spec.rb → test/visitors/test_to_sql.rb} +25 -18
- metadata +101 -43
- data/spec/nodes/select_core_spec.rb +0 -21
- data/spec/nodes/sql_literal_spec.rb +0 -26
- data/spec/spec.opts +0 -3
- data/spec/spec_helper.rb +0 -18
- data/spec/support/check.rb +0 -6
- data/spec/support/matchers.rb +0 -4
- data/spec/support/matchers/be_like.rb +0 -24
- data/spec/support/shared/tree_manager_shared.rb +0 -9
data/test/helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'arel'
|
5
|
+
|
6
|
+
require 'support/fake_record'
|
7
|
+
Arel::Table.engine = Arel::Sql::Engine.new(FakeRecord::Base.new)
|
8
|
+
|
9
|
+
class Object
|
10
|
+
def must_be_like other
|
11
|
+
self.gsub(/\s+/, ' ').strip.must_equal other.gsub(/\s+/, ' ').strip
|
12
|
+
end
|
13
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
|
-
require '
|
1
|
+
require 'helper'
|
2
2
|
|
3
3
|
describe Arel::Nodes::Count do
|
4
4
|
describe 'backwards compatibility' do
|
5
5
|
it 'must be an expression' do
|
6
|
-
Arel::Nodes::Count.new('foo').
|
6
|
+
Arel::Nodes::Count.new('foo').must_be_kind_of Arel::Expression
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
10
|
describe "as" do
|
11
11
|
it 'should alias the count' do
|
12
12
|
table = Arel::Table.new :users
|
13
|
-
table[:id].count.as('foo').to_sql.
|
13
|
+
table[:id].count.as('foo').to_sql.must_be_like %{
|
14
14
|
COUNT("users"."id") AS foo
|
15
15
|
}
|
16
16
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'helper'
|
2
2
|
|
3
3
|
describe Arel::Nodes::DeleteStatement do
|
4
4
|
describe "#clone" do
|
@@ -6,10 +6,9 @@ describe Arel::Nodes::DeleteStatement do
|
|
6
6
|
statement = Arel::Nodes::DeleteStatement.new
|
7
7
|
statement.wheres = %w[a b c]
|
8
8
|
|
9
|
-
statement.wheres.should_receive(:clone).and_return([:wheres])
|
10
|
-
|
11
9
|
dolly = statement.clone
|
12
|
-
dolly.wheres.
|
10
|
+
dolly.wheres.must_equal statement.wheres
|
11
|
+
dolly.wheres.wont_be_same_as statement.wheres
|
13
12
|
end
|
14
13
|
end
|
15
14
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
1
3
|
module Arel
|
2
4
|
module Nodes
|
3
5
|
describe 'equality' do
|
@@ -7,7 +9,7 @@ module Arel
|
|
7
9
|
it 'returns :==' do
|
8
10
|
attr = Table.new(:users)[:id]
|
9
11
|
left = attr.eq(10)
|
10
|
-
|
12
|
+
left.operator.must_equal :==
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
@@ -15,7 +17,7 @@ module Arel
|
|
15
17
|
it "should equal left" do
|
16
18
|
attr = Table.new(:users)[:id]
|
17
19
|
left = attr.eq(10)
|
18
|
-
|
20
|
+
left.left.must_equal left.operand1
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
@@ -23,7 +25,7 @@ module Arel
|
|
23
25
|
it "should equal right" do
|
24
26
|
attr = Table.new(:users)[:id]
|
25
27
|
left = attr.eq(10)
|
26
|
-
|
28
|
+
left.right.must_equal left.operand2
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
@@ -41,7 +43,7 @@ module Arel
|
|
41
43
|
attr = Table.new(:users)[:id]
|
42
44
|
test = attr.eq(10)
|
43
45
|
test.to_sql engine
|
44
|
-
|
46
|
+
engine.connection.quote_count.must_equal 2
|
45
47
|
end
|
46
48
|
end
|
47
49
|
end
|
@@ -52,8 +54,8 @@ module Arel
|
|
52
54
|
left = attr.eq(10)
|
53
55
|
right = attr.eq(11)
|
54
56
|
node = left.or right
|
55
|
-
|
56
|
-
|
57
|
+
node.expr.left.must_equal left
|
58
|
+
node.expr.right.must_equal right
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
@@ -63,8 +65,8 @@ module Arel
|
|
63
65
|
left = attr.eq(10)
|
64
66
|
right = attr.eq(11)
|
65
67
|
node = left.and right
|
66
|
-
|
67
|
-
|
68
|
+
node.left.must_equal left
|
69
|
+
node.right.must_equal right
|
68
70
|
end
|
69
71
|
end
|
70
72
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'helper'
|
2
2
|
|
3
3
|
describe Arel::Nodes::InsertStatement do
|
4
4
|
describe "#clone" do
|
@@ -7,12 +7,12 @@ describe Arel::Nodes::InsertStatement do
|
|
7
7
|
statement.columns = %w[a b c]
|
8
8
|
statement.values = %w[x y z]
|
9
9
|
|
10
|
-
statement.columns.should_receive(:clone).and_return([:columns])
|
11
|
-
statement.values.should_receive(:clone).and_return([:values])
|
12
|
-
|
13
10
|
dolly = statement.clone
|
14
|
-
|
15
|
-
|
11
|
+
dolly.columns.must_equal statement.columns
|
12
|
+
dolly.values.must_equal statement.values
|
13
|
+
|
14
|
+
dolly.columns.wont_be_same_as statement.columns
|
15
|
+
dolly.values.wont_be_same_as statement.values
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
1
3
|
module Arel
|
2
4
|
module Nodes
|
3
5
|
describe 'or' do
|
@@ -7,12 +9,12 @@ module Arel
|
|
7
9
|
left = attr.eq(10)
|
8
10
|
right = attr.eq(11)
|
9
11
|
node = left.or right
|
10
|
-
|
11
|
-
|
12
|
+
node.expr.left.must_equal left
|
13
|
+
node.expr.right.must_equal right
|
12
14
|
|
13
15
|
oror = node.or(right)
|
14
|
-
|
15
|
-
|
16
|
+
oror.expr.left.must_equal node
|
17
|
+
oror.expr.right.must_equal right
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Arel::Nodes::SelectCore do
|
4
|
+
describe "#clone" do
|
5
|
+
it "clones froms, projections and wheres" do
|
6
|
+
core = Arel::Nodes::SelectCore.new
|
7
|
+
core.froms = %w[a b c]
|
8
|
+
core.projections = %w[d e f]
|
9
|
+
core.wheres = %w[g h i]
|
10
|
+
|
11
|
+
dolly = core.clone
|
12
|
+
|
13
|
+
dolly.froms.must_equal core.froms
|
14
|
+
dolly.projections.must_equal core.projections
|
15
|
+
dolly.wheres.must_equal core.wheres
|
16
|
+
|
17
|
+
dolly.froms.wont_be_same_as core.froms
|
18
|
+
dolly.projections.wont_be_same_as core.projections
|
19
|
+
dolly.wheres.wont_be_same_as core.wheres
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,14 +1,13 @@
|
|
1
|
-
require '
|
1
|
+
require 'helper'
|
2
2
|
|
3
3
|
describe Arel::Nodes::SelectStatement do
|
4
4
|
describe "#clone" do
|
5
5
|
it "clones cores" do
|
6
6
|
statement = Arel::Nodes::SelectStatement.new %w[a b c]
|
7
7
|
|
8
|
-
statement.cores.map { |x| x.should_receive(:clone).and_return(:f) }
|
9
|
-
|
10
8
|
dolly = statement.clone
|
11
|
-
dolly.cores.
|
9
|
+
dolly.cores.must_equal statement.cores
|
10
|
+
dolly.cores.wont_be_same_as statement.cores
|
12
11
|
end
|
13
12
|
end
|
14
13
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
module Nodes
|
5
|
+
describe 'sql literal' do
|
6
|
+
describe 'sql' do
|
7
|
+
it 'makes a sql literal node' do
|
8
|
+
sql = Arel.sql 'foo'
|
9
|
+
sql.must_be_kind_of Arel::Nodes::SqlLiteral
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'count' do
|
14
|
+
it 'makes a count node' do
|
15
|
+
node = SqlLiteral.new('*').count
|
16
|
+
viz = Visitors::ToSql.new Table.engine
|
17
|
+
viz.accept(node).must_be_like %{ COUNT(*) }
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'makes a distinct node' do
|
21
|
+
node = SqlLiteral.new('*').count true
|
22
|
+
viz = Visitors::ToSql.new Table.engine
|
23
|
+
viz.accept(node).must_be_like %{ COUNT(DISTINCT *) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'equality' do
|
28
|
+
it 'makes an equality node' do
|
29
|
+
node = SqlLiteral.new('foo').eq(1)
|
30
|
+
viz = Visitors::ToSql.new Table.engine
|
31
|
+
viz.accept(node).must_be_like %{ foo = 1 }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'grouped "or" equality' do
|
36
|
+
it 'makes a grouping node with an or node' do
|
37
|
+
node = SqlLiteral.new('foo').eq_any([1,2])
|
38
|
+
viz = Visitors::ToSql.new Table.engine
|
39
|
+
viz.accept(node).must_be_like %{ (foo = 1 OR foo = 2) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'grouped "and" equality' do
|
44
|
+
it 'makes a grouping node with an or node' do
|
45
|
+
node = SqlLiteral.new('foo').eq_all([1,2])
|
46
|
+
viz = Visitors::ToSql.new Table.engine
|
47
|
+
viz.accept(node).must_be_like %{ (foo = 1 AND foo = 2) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require '
|
1
|
+
require 'helper'
|
2
2
|
|
3
3
|
describe Arel::Nodes::Sum do
|
4
4
|
describe "as" do
|
5
5
|
it 'should alias the sum' do
|
6
6
|
table = Arel::Table.new :users
|
7
|
-
table[:id].sum.as('foo').to_sql.
|
7
|
+
table[:id].sum.as('foo').to_sql.must_be_like %{
|
8
8
|
SUM("users"."id") AS foo
|
9
9
|
}
|
10
10
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'helper'
|
2
2
|
|
3
3
|
describe Arel::Nodes::UpdateStatement do
|
4
4
|
describe "#clone" do
|
@@ -7,12 +7,12 @@ describe Arel::Nodes::UpdateStatement do
|
|
7
7
|
statement.wheres = %w[a b c]
|
8
8
|
statement.values = %w[x y z]
|
9
9
|
|
10
|
-
statement.wheres.should_receive(:clone).and_return([:wheres])
|
11
|
-
statement.values.should_receive(:clone).and_return([:values])
|
12
|
-
|
13
10
|
dolly = statement.clone
|
14
|
-
|
15
|
-
|
11
|
+
dolly.wheres.must_equal statement.wheres
|
12
|
+
dolly.wheres.wont_be_same_as statement.wheres
|
13
|
+
|
14
|
+
dolly.values.must_equal statement.values
|
15
|
+
dolly.values.wont_be_same_as statement.values
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -10,7 +10,9 @@ module FakeRecord
|
|
10
10
|
@columns = {
|
11
11
|
'users' => [
|
12
12
|
Column.new('id', :integer),
|
13
|
-
Column.new('name', :string)
|
13
|
+
Column.new('name', :string),
|
14
|
+
Column.new('bool', :boolean),
|
15
|
+
Column.new('created_at', :date),
|
14
16
|
]
|
15
17
|
}
|
16
18
|
@primary_keys = {
|
@@ -66,7 +68,7 @@ module FakeRecord
|
|
66
68
|
attr_reader :spec, :connection
|
67
69
|
|
68
70
|
def initialize
|
69
|
-
@spec = Spec.new(:adapter => '
|
71
|
+
@spec = Spec.new(:adapter => 'america')
|
70
72
|
@connection = Connection.new
|
71
73
|
end
|
72
74
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'helper'
|
2
2
|
|
3
3
|
module Arel
|
4
4
|
describe 'activerecord compatibility' do
|
@@ -9,9 +9,9 @@ module Arel
|
|
9
9
|
manager.where table[:id].eq 1
|
10
10
|
manager.where table[:name].eq 'Aaron'
|
11
11
|
|
12
|
-
|
12
|
+
manager.wheres.map { |x|
|
13
13
|
x.value
|
14
|
-
}.join(', ').
|
14
|
+
}.join(', ').must_equal "\"users\".\"id\" = 1, \"users\".\"name\" = 'Aaron'"
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'helper'
|
2
2
|
|
3
3
|
module Arel
|
4
4
|
describe 'Attributes' do
|
@@ -6,34 +6,34 @@ module Arel
|
|
6
6
|
it 'returns the correct constant for strings' do
|
7
7
|
[:string, :text, :binary].each do |type|
|
8
8
|
column = Struct.new(:type).new type
|
9
|
-
Attributes.for(column).
|
9
|
+
Attributes.for(column).must_equal Attributes::String
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'returns the correct constant for ints' do
|
14
14
|
column = Struct.new(:type).new :integer
|
15
|
-
Attributes.for(column).
|
15
|
+
Attributes.for(column).must_equal Attributes::Integer
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'returns the correct constant for floats' do
|
19
19
|
column = Struct.new(:type).new :float
|
20
|
-
Attributes.for(column).
|
20
|
+
Attributes.for(column).must_equal Attributes::Float
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'returns the correct constant for decimals' do
|
24
24
|
column = Struct.new(:type).new :decimal
|
25
|
-
Attributes.for(column).
|
25
|
+
Attributes.for(column).must_equal Attributes::Decimal
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'returns the correct constant for boolean' do
|
29
29
|
column = Struct.new(:type).new :boolean
|
30
|
-
Attributes.for(column).
|
30
|
+
Attributes.for(column).must_equal Attributes::Boolean
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'returns the correct constant for time' do
|
34
34
|
[:date, :datetime, :timestamp, :time].each do |type|
|
35
35
|
column = Struct.new(:type).new type
|
36
|
-
Attributes.for(column).
|
36
|
+
Attributes.for(column).must_equal Attributes::Time
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'helper'
|
2
2
|
|
3
3
|
module Arel
|
4
4
|
class FakeCrudder < SelectManager
|
@@ -38,7 +38,7 @@ module Arel
|
|
38
38
|
fc.insert [[table[:id], 'foo']]
|
39
39
|
fc.engine.calls.find { |method, _|
|
40
40
|
method == :insert
|
41
|
-
}.
|
41
|
+
}.wont_be_nil
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -50,7 +50,7 @@ module Arel
|
|
50
50
|
fc.update [[table[:id], 'foo']]
|
51
51
|
fc.engine.calls.find { |method, _|
|
52
52
|
method == :update
|
53
|
-
}.
|
53
|
+
}.wont_be_nil
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -62,7 +62,7 @@ module Arel
|
|
62
62
|
fc.delete
|
63
63
|
fc.engine.calls.find { |method, _|
|
64
64
|
method == :delete
|
65
|
-
}.
|
65
|
+
}.wont_be_nil
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'helper'
|
2
2
|
|
3
3
|
module Arel
|
4
4
|
describe 'delete manager' do
|
@@ -13,13 +13,13 @@ module Arel
|
|
13
13
|
table = Table.new(:users)
|
14
14
|
dm = Arel::DeleteManager.new Table.engine
|
15
15
|
dm.from table
|
16
|
-
dm.to_sql.
|
16
|
+
dm.to_sql.must_be_like %{ DELETE FROM "users" }
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'chains' do
|
20
20
|
table = Table.new(:users)
|
21
21
|
dm = Arel::DeleteManager.new Table.engine
|
22
|
-
|
22
|
+
dm.from(table).must_equal dm
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -29,25 +29,14 @@ module Arel
|
|
29
29
|
dm = Arel::DeleteManager.new Table.engine
|
30
30
|
dm.from table
|
31
31
|
dm.where table[:id].eq(10)
|
32
|
-
dm.to_sql.
|
32
|
+
dm.to_sql.must_be_like %{ DELETE FROM "users" WHERE "users"."id" = 10}
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'chains' do
|
36
36
|
table = Table.new(:users)
|
37
37
|
dm = Arel::DeleteManager.new Table.engine
|
38
|
-
|
38
|
+
dm.where(table[:id].eq(10)).must_equal dm
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
42
|
-
describe "TreeManager" do
|
43
|
-
subject do
|
44
|
-
table = Table.new :users
|
45
|
-
Arel::DeleteManager.new(Table.engine).tap do |manager|
|
46
|
-
manager.where(table[:id].eq(10))
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
it_should_behave_like "TreeManager"
|
51
|
-
end
|
52
41
|
end
|
53
42
|
end
|