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.
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