arel 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.autotest +26 -0
  2. data/History.txt +18 -0
  3. data/Manifest.txt +31 -30
  4. data/README.markdown +7 -99
  5. data/Rakefile +3 -2
  6. data/arel.gemspec +18 -11
  7. data/lib/arel.rb +2 -1
  8. data/lib/arel/attributes/attribute.rb +1 -174
  9. data/lib/arel/crud.rb +2 -2
  10. data/lib/arel/delete_manager.rb +4 -4
  11. data/lib/arel/insert_manager.rb +8 -8
  12. data/lib/arel/nodes/exists.rb +2 -6
  13. data/lib/arel/nodes/sql_literal.rb +1 -0
  14. data/lib/arel/predications.rb +177 -0
  15. data/lib/arel/select_manager.rb +17 -11
  16. data/lib/arel/table.rb +4 -0
  17. data/lib/arel/tree_manager.rb +4 -3
  18. data/lib/arel/update_manager.rb +8 -8
  19. data/lib/arel/visitors.rb +4 -0
  20. data/lib/arel/visitors/dot.rb +3 -3
  21. data/lib/arel/visitors/join_sql.rb +2 -0
  22. data/lib/arel/visitors/mysql.rb +14 -0
  23. data/lib/arel/visitors/oracle.rb +31 -1
  24. data/lib/arel/visitors/order_clauses.rb +2 -0
  25. data/lib/arel/visitors/sqlite.rb +11 -0
  26. data/lib/arel/visitors/to_sql.rb +8 -11
  27. data/lib/arel/visitors/visitor.rb +19 -0
  28. data/{spec/attributes/attribute_spec.rb → test/attributes/test_attribute.rb} +84 -84
  29. data/test/helper.rb +13 -0
  30. data/{spec/nodes/count_spec.rb → test/nodes/test_count.rb} +3 -3
  31. data/{spec/nodes/delete_statement_spec.rb → test/nodes/test_delete_statement.rb} +3 -4
  32. data/{spec/nodes/equality_spec.rb → test/nodes/test_equality.rb} +10 -8
  33. data/{spec/nodes/insert_statement_spec.rb → test/nodes/test_insert_statement.rb} +6 -6
  34. data/{spec/nodes/or_spec.rb → test/nodes/test_or.rb} +6 -4
  35. data/test/nodes/test_select_core.rb +22 -0
  36. data/{spec/nodes/select_statement_spec.rb → test/nodes/test_select_statement.rb} +3 -4
  37. data/test/nodes/test_sql_literal.rb +52 -0
  38. data/{spec/nodes/sum_spec.rb → test/nodes/test_sum.rb} +2 -2
  39. data/{spec/nodes/update_statement_spec.rb → test/nodes/test_update_statement.rb} +6 -6
  40. data/{spec → test}/support/fake_record.rb +4 -2
  41. data/{spec/activerecord_compat_spec.rb → test/test_activerecord_compat.rb} +3 -3
  42. data/{spec/attributes_spec.rb → test/test_attributes.rb} +7 -7
  43. data/{spec/crud_spec.rb → test/test_crud.rb} +4 -4
  44. data/{spec/delete_manager_spec.rb → test/test_delete_manager.rb} +5 -16
  45. data/{spec/insert_manager_spec.rb → test/test_insert_manager.rb} +15 -31
  46. data/{spec/select_manager_spec.rb → test/test_select_manager.rb} +95 -77
  47. data/{spec/table_spec.rb → test/test_table.rb} +38 -32
  48. data/{spec/update_manager_spec.rb → test/test_update_manager.rb} +9 -21
  49. data/{spec/visitors/join_sql_spec.rb → test/visitors/test_join_sql.rb} +3 -3
  50. data/test/visitors/test_mysql.rb +27 -0
  51. data/{spec/visitors/oracle_spec.rb → test/visitors/test_oracle.rb} +26 -10
  52. data/{spec/visitors/postgres_spec.rb → test/visitors/test_postgres.rb} +2 -2
  53. data/test/visitors/test_sqlite.rb +18 -0
  54. data/{spec/visitors/to_sql_spec.rb → test/visitors/test_to_sql.rb} +25 -18
  55. metadata +101 -43
  56. data/spec/nodes/select_core_spec.rb +0 -21
  57. data/spec/nodes/sql_literal_spec.rb +0 -26
  58. data/spec/spec.opts +0 -3
  59. data/spec/spec_helper.rb +0 -18
  60. data/spec/support/check.rb +0 -6
  61. data/spec/support/matchers.rb +0 -4
  62. data/spec/support/matchers/be_like.rb +0 -24
  63. data/spec/support/shared/tree_manager_shared.rb +0 -9
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'helper'
2
2
 
3
3
  module Arel
4
4
  describe Table do
@@ -6,23 +6,30 @@ module Arel
6
6
  @relation = Table.new(:users)
7
7
  end
8
8
 
9
+ describe 'skip' do
10
+ it 'should add an offset' do
11
+ sm = @relation.skip 2
12
+ sm.to_sql.must_be_like "SELECT FROM \"users\" OFFSET 2"
13
+ end
14
+ end
15
+
9
16
  describe 'primary_key' do
10
17
  it 'should return an attribute' do
11
- check @relation.primary_key.name.should == :id
18
+ @relation.primary_key.name.must_equal :id
12
19
  end
13
20
  end
14
21
 
15
22
  describe 'select_manager' do
16
23
  it 'should return an empty select manager' do
17
24
  sm = @relation.select_manager
18
- sm.to_sql.should be_like 'SELECT'
25
+ sm.to_sql.must_be_like 'SELECT'
19
26
  end
20
27
  end
21
28
 
22
29
  describe 'having' do
23
30
  it 'adds a having clause' do
24
31
  mgr = @relation.having @relation[:id].eq(10)
25
- mgr.to_sql.should be_like %{
32
+ mgr.to_sql.must_be_like %{
26
33
  SELECT FROM "users" HAVING "users"."id" = 10
27
34
  }
28
35
  end
@@ -31,7 +38,7 @@ module Arel
31
38
  describe 'backwards compat' do
32
39
  describe 'joins' do
33
40
  it 'returns nil' do
34
- check @relation.joins(nil).should == nil
41
+ @relation.joins(nil).must_equal nil
35
42
  end
36
43
  end
37
44
 
@@ -39,7 +46,7 @@ module Arel
39
46
  it 'noops on nil' do
40
47
  mgr = @relation.join nil
41
48
 
42
- mgr.to_sql.should be_like %{ SELECT FROM "users" }
49
+ mgr.to_sql.must_be_like %{ SELECT FROM "users" }
43
50
  end
44
51
 
45
52
  it 'takes a second argument for join type' do
@@ -47,7 +54,7 @@ module Arel
47
54
  predicate = @relation[:id].eq(right[:id])
48
55
  mgr = @relation.join(right, Nodes::OuterJoin).on(predicate)
49
56
 
50
- mgr.to_sql.should be_like %{
57
+ mgr.to_sql.must_be_like %{
51
58
  SELECT FROM "users"
52
59
  LEFT OUTER JOIN "users" "users_2"
53
60
  ON "users"."id" = "users_2"."id"
@@ -59,7 +66,7 @@ module Arel
59
66
  describe 'group' do
60
67
  it 'should create a group' do
61
68
  manager = @relation.group @relation[:id]
62
- manager.to_sql.should be_like %{
69
+ manager.to_sql.must_be_like %{
63
70
  SELECT FROM "users" GROUP BY "users"."id"
64
71
  }
65
72
  end
@@ -67,13 +74,12 @@ module Arel
67
74
 
68
75
  describe 'alias' do
69
76
  it 'should create a node that proxies to a table' do
70
- check @relation.aliases.should == []
77
+ @relation.aliases.must_equal []
71
78
 
72
79
  node = @relation.alias
73
- check @relation.aliases.should == [node]
74
- check node.name.should == 'users_2'
75
- check node[:id].relation.should == node
76
- check node[:id].relation.should != node
80
+ @relation.aliases.must_equal [node]
81
+ node.name.must_equal 'users_2'
82
+ node[:id].relation.must_equal node
77
83
  end
78
84
  end
79
85
 
@@ -81,30 +87,30 @@ module Arel
81
87
  it 'takes :columns' do
82
88
  columns = Table.engine.connection.columns("users")
83
89
  @relation = Table.new(:users, :columns => columns)
84
- check @relation.columns.first.name.should == :id
85
- check @relation.engine.should == Table.engine
90
+ @relation.columns.first.name.must_equal :id
91
+ @relation.engine.must_equal Table.engine
86
92
  end
87
93
 
88
94
  it 'should accept an engine' do
89
95
  rel = Table.new :users, 'foo'
90
- check rel.engine.should == 'foo'
96
+ rel.engine.must_equal 'foo'
91
97
  end
92
98
 
93
99
  it 'should accept a hash' do
94
100
  rel = Table.new :users, :engine => 'foo'
95
- check rel.engine.should == 'foo'
101
+ rel.engine.must_equal 'foo'
96
102
  end
97
103
 
98
104
  it 'ignores as if it equals name' do
99
105
  rel = Table.new :users, :as => 'users'
100
- rel.table_alias.should be_nil
106
+ rel.table_alias.must_be_nil
101
107
  end
102
108
  end
103
109
 
104
110
  describe 'order' do
105
111
  it "should take an order" do
106
112
  manager = @relation.order "foo"
107
- manager.to_sql.should be_like %{ SELECT FROM "users" ORDER BY foo }
113
+ manager.to_sql.must_be_like %{ SELECT FROM "users" ORDER BY foo }
108
114
  end
109
115
  end
110
116
 
@@ -112,19 +118,19 @@ module Arel
112
118
  it "should add a limit" do
113
119
  manager = @relation.take 1
114
120
  manager.project SqlLiteral.new '*'
115
- manager.to_sql.should be_like %{ SELECT * FROM "users" LIMIT 1 }
121
+ manager.to_sql.must_be_like %{ SELECT * FROM "users" LIMIT 1 }
116
122
  end
117
123
  end
118
124
 
119
125
  describe 'project' do
120
126
  it 'can project' do
121
127
  manager = @relation.project SqlLiteral.new '*'
122
- manager.to_sql.should be_like %{ SELECT * FROM "users" }
128
+ manager.to_sql.must_be_like %{ SELECT * FROM "users" }
123
129
  end
124
130
 
125
131
  it 'takes multiple parameters' do
126
132
  manager = @relation.project SqlLiteral.new('*'), SqlLiteral.new('*')
127
- manager.to_sql.should be_like %{ SELECT *, * FROM "users" }
133
+ manager.to_sql.must_be_like %{ SELECT *, * FROM "users" }
128
134
  end
129
135
  end
130
136
 
@@ -132,8 +138,8 @@ module Arel
132
138
  it "returns a tree manager" do
133
139
  manager = @relation.where @relation[:id].eq 1
134
140
  manager.project @relation[:id]
135
- manager.should be_kind_of TreeManager
136
- manager.to_sql.should be_like %{
141
+ manager.must_be_kind_of TreeManager
142
+ manager.to_sql.must_be_like %{
137
143
  SELECT "users"."id"
138
144
  FROM "users"
139
145
  WHERE "users"."id" = 1
@@ -144,31 +150,31 @@ module Arel
144
150
  describe 'columns' do
145
151
  it 'returns a list of columns' do
146
152
  columns = @relation.columns
147
- check columns.length.should == 2
148
- columns.map { |x| x.name.to_s }.sort.should == %w{ name id }.sort
153
+ columns.length.must_equal 4
154
+ columns.map { |x| x.name.to_s }.sort.must_equal %w{ created_at bool name id }.sort
149
155
  end
150
156
  end
151
157
 
152
158
  it "should have a name" do
153
- @relation.name.should == :users
159
+ @relation.name.must_equal :users
154
160
  end
155
161
 
156
162
  it "should have an engine" do
157
- @relation.engine.should == Table.engine
163
+ @relation.engine.must_equal Table.engine
158
164
  end
159
165
 
160
166
  describe '[]' do
161
- describe 'when given a', Symbol do
167
+ describe 'when given a Symbol' do
162
168
  it "manufactures an attribute if the symbol names an attribute within the relation" do
163
169
  column = @relation[:id]
164
- check column.name.should == :id
165
- column.should be_kind_of Attributes::Integer
170
+ column.name.must_equal :id
171
+ column.must_be_kind_of Attributes::Integer
166
172
  end
167
173
  end
168
174
 
169
175
  describe 'when table does not exist' do
170
176
  it 'returns nil' do
171
- @relation[:foooo].should be_nil
177
+ @relation[:foooo].must_be_nil
172
178
  end
173
179
  end
174
180
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'helper'
2
2
 
3
3
  module Arel
4
4
  describe 'update manager' do
@@ -14,7 +14,7 @@ module Arel
14
14
  um = Arel::UpdateManager.new Table.engine
15
15
  um.table table
16
16
  um.set [[table[:name], nil]]
17
- um.to_sql.should be_like %{ UPDATE "users" SET "name" = NULL }
17
+ um.to_sql.must_be_like %{ UPDATE "users" SET "name" = NULL }
18
18
  end
19
19
 
20
20
  it 'takes a string' do
@@ -22,7 +22,7 @@ module Arel
22
22
  um = Arel::UpdateManager.new Table.engine
23
23
  um.table table
24
24
  um.set Nodes::SqlLiteral.new "foo = bar"
25
- um.to_sql.should be_like %{ UPDATE "users" SET foo = bar }
25
+ um.to_sql.must_be_like %{ UPDATE "users" SET foo = bar }
26
26
  end
27
27
 
28
28
  it 'takes a list of lists' do
@@ -30,7 +30,7 @@ module Arel
30
30
  um = Arel::UpdateManager.new Table.engine
31
31
  um.table table
32
32
  um.set [[table[:id], 1], [table[:name], 'hello']]
33
- um.to_sql.should be_like %{
33
+ um.to_sql.must_be_like %{
34
34
  UPDATE "users" SET "id" = 1, "name" = 'hello'
35
35
  }
36
36
  end
@@ -38,7 +38,7 @@ module Arel
38
38
  it 'chains' do
39
39
  table = Table.new(:users)
40
40
  um = Arel::UpdateManager.new Table.engine
41
- um.set([[table[:id], 1], [table[:name], 'hello']]).should == um
41
+ um.set([[table[:id], 1], [table[:name], 'hello']]).must_equal um
42
42
  end
43
43
  end
44
44
 
@@ -46,12 +46,12 @@ module Arel
46
46
  it 'generates an update statement' do
47
47
  um = Arel::UpdateManager.new Table.engine
48
48
  um.table Table.new(:users)
49
- um.to_sql.should be_like %{ UPDATE "users" }
49
+ um.to_sql.must_be_like %{ UPDATE "users" }
50
50
  end
51
51
 
52
52
  it 'chains' do
53
53
  um = Arel::UpdateManager.new Table.engine
54
- um.table(Table.new(:users)).should == um
54
+ um.table(Table.new(:users)).must_equal um
55
55
  end
56
56
  end
57
57
 
@@ -61,7 +61,7 @@ module Arel
61
61
  um = Arel::UpdateManager.new Table.engine
62
62
  um.table table
63
63
  um.where table[:id].eq(1)
64
- um.to_sql.should be_like %{
64
+ um.to_sql.must_be_like %{
65
65
  UPDATE "users" WHERE "users"."id" = 1
66
66
  }
67
67
  end
@@ -70,20 +70,8 @@ module Arel
70
70
  table = Table.new :users
71
71
  um = Arel::UpdateManager.new Table.engine
72
72
  um.table table
73
- um.where(table[:id].eq(1)).should == um
73
+ um.where(table[:id].eq(1)).must_equal um
74
74
  end
75
75
  end
76
-
77
- describe "TreeManager" do
78
- subject do
79
- table = Table.new :users
80
- Arel::UpdateManager.new(Table.engine).tap do |manager|
81
- manager.table table
82
- manager.where table[:id].eq(1)
83
- end
84
- end
85
-
86
- it_should_behave_like "TreeManager"
87
- end
88
76
  end
89
77
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'helper'
2
2
 
3
3
  module Arel
4
4
  module Visitors
@@ -12,7 +12,7 @@ module Arel
12
12
  t = Table.new :users
13
13
  join = Nodes::InnerJoin.new t, t, Nodes::On.new(t[:id])
14
14
  j2 = Nodes::InnerJoin.new join, t, Nodes::On.new(t[:id])
15
- @visitor.accept(j2).should be_like %{
15
+ @visitor.accept(j2).must_be_like %{
16
16
  INNER JOIN "users" ON "users"."id"
17
17
  INNER JOIN "users" ON "users"."id"
18
18
  }
@@ -24,7 +24,7 @@ module Arel
24
24
  t = Table.new :users
25
25
  join = Nodes::OuterJoin.new t, t, Nodes::On.new(t[:id])
26
26
  j2 = Nodes::OuterJoin.new join, t, Nodes::On.new(t[:id])
27
- @visitor.accept(j2).should be_like %{
27
+ @visitor.accept(j2).must_be_like %{
28
28
  LEFT OUTER JOIN "users" ON "users"."id"
29
29
  LEFT OUTER JOIN "users" ON "users"."id"
30
30
  }
@@ -0,0 +1,27 @@
1
+ require 'helper'
2
+
3
+ module Arel
4
+ module Visitors
5
+ describe 'the mysql visitor' do
6
+ before do
7
+ @visitor = MySQL.new Table.engine
8
+ end
9
+
10
+ ###
11
+ # :'(
12
+ # http://dev.mysql.com/doc/refman/5.0/en/select.html#id3482214
13
+ it 'defaults limit to 18446744073709551615' do
14
+ stmt = Nodes::SelectStatement.new
15
+ stmt.offset = Nodes::Offset.new(1)
16
+ sql = @visitor.accept(stmt)
17
+ sql.must_be_like "SELECT FROM DUAL LIMIT 18446744073709551615 OFFSET 1"
18
+ end
19
+
20
+ it 'uses DUAL for empty from' do
21
+ stmt = Nodes::SelectStatement.new
22
+ sql = @visitor.accept(stmt)
23
+ sql.must_be_like "SELECT FROM DUAL"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'helper'
2
2
 
3
3
  module Arel
4
4
  module Visitors
@@ -14,7 +14,7 @@ module Arel
14
14
  stmt.cores.first.projections << Nodes::SqlLiteral.new(select)
15
15
  stmt.orders << Nodes::SqlLiteral.new('foo')
16
16
  sql = @visitor.accept(stmt)
17
- sql.should be_like %{
17
+ sql.must_be_like %{
18
18
  SELECT #{select} ORDER BY alias_0__
19
19
  }
20
20
  end
@@ -28,7 +28,7 @@ module Arel
28
28
 
29
29
  sql = @visitor.accept(stmt)
30
30
  sql2 = @visitor.accept(stmt)
31
- check sql.should == sql2
31
+ sql.must_equal sql2
32
32
  end
33
33
 
34
34
  it 'splits orders with commas' do
@@ -38,7 +38,7 @@ module Arel
38
38
  stmt.cores.first.projections << Nodes::SqlLiteral.new(select)
39
39
  stmt.orders << Nodes::SqlLiteral.new('foo, bar')
40
40
  sql = @visitor.accept(stmt)
41
- sql.should be_like %{
41
+ sql.must_be_like %{
42
42
  SELECT #{select} ORDER BY alias_0__, alias_1__
43
43
  }
44
44
  end
@@ -49,7 +49,7 @@ module Arel
49
49
  stmt = Nodes::SelectStatement.new
50
50
  stmt.limit = 10
51
51
  sql = @visitor.accept stmt
52
- sql.should be_like %{ SELECT WHERE ROWNUM <= 10 }
52
+ sql.must_be_like %{ SELECT WHERE ROWNUM <= 10 }
53
53
  end
54
54
 
55
55
  it 'is idempotent' do
@@ -58,7 +58,7 @@ module Arel
58
58
  stmt.limit = 10
59
59
  sql = @visitor.accept stmt
60
60
  sql2 = @visitor.accept stmt
61
- check sql.should == sql2
61
+ sql.must_equal sql2
62
62
  end
63
63
 
64
64
  it 'creates a subquery when there is order_by' do
@@ -66,7 +66,7 @@ module Arel
66
66
  stmt.orders << Nodes::SqlLiteral.new('foo')
67
67
  stmt.limit = 10
68
68
  sql = @visitor.accept stmt
69
- sql.should be_like %{
69
+ sql.must_be_like %{
70
70
  SELECT * FROM (SELECT ORDER BY foo) WHERE ROWNUM <= 10
71
71
  }
72
72
  end
@@ -76,7 +76,7 @@ module Arel
76
76
  stmt.cores.first.projections << Nodes::SqlLiteral.new('DISTINCT id')
77
77
  stmt.limit = 10
78
78
  sql = @visitor.accept stmt
79
- sql.should be_like %{
79
+ sql.must_be_like %{
80
80
  SELECT * FROM (SELECT DISTINCT id) WHERE ROWNUM <= 10
81
81
  }
82
82
  end
@@ -86,7 +86,7 @@ module Arel
86
86
  stmt.limit = 10
87
87
  stmt.offset = Nodes::Offset.new(10)
88
88
  sql = @visitor.accept stmt
89
- sql.should be_like %{
89
+ sql.must_be_like %{
90
90
  SELECT * FROM (
91
91
  SELECT raw_sql_.*, rownum raw_rnum_
92
92
  FROM (SELECT ) raw_sql_
@@ -102,9 +102,25 @@ module Arel
102
102
  stmt.offset = Nodes::Offset.new(10)
103
103
  sql = @visitor.accept stmt
104
104
  sql2 = @visitor.accept stmt
105
- check sql.should == sql2
105
+ sql.must_equal sql2
106
106
  end
107
107
  end
108
+
109
+ describe 'only offset' do
110
+ it 'creates a select from subquery with rownum condition' do
111
+ stmt = Nodes::SelectStatement.new
112
+ stmt.offset = Nodes::Offset.new(10)
113
+ sql = @visitor.accept stmt
114
+ sql.must_be_like %{
115
+ SELECT * FROM (
116
+ SELECT raw_sql_.*, rownum raw_rnum_
117
+ FROM (SELECT ) raw_sql_
118
+ )
119
+ WHERE raw_rnum_ > 10
120
+ }
121
+ end
122
+ end
123
+
108
124
  end
109
125
  end
110
126
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'helper'
2
2
 
3
3
  module Arel
4
4
  module Visitors
@@ -8,7 +8,7 @@ module Arel
8
8
  end
9
9
 
10
10
  it 'should produce a lock value' do
11
- @visitor.accept(Nodes::Lock.new).should be_like %{
11
+ @visitor.accept(Nodes::Lock.new).must_be_like %{
12
12
  FOR UPDATE
13
13
  }
14
14
  end