arel 2.0.1 → 2.0.2
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.
- 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
|