ibm_db 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +4 -0
- data/README +1 -1
- data/ext/Makefile.nt32 +181 -0
- data/ext/extconf.rb +55 -55
- data/ext/ibm_db.c +6367 -6367
- data/ext/ruby_ibm_db.h +179 -179
- data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
- data/test/adapter_test.rb +131 -131
- data/test/associations/eager_test.rb +445 -445
- data/test/associations_test.rb +1839 -1839
- data/test/fixtures/db_definitions/i5/ibm_db.drop.sql +32 -32
- data/test/fixtures/db_definitions/i5/ibm_db.sql +232 -232
- data/test/fixtures/db_definitions/i5/ibm_db2.drop.sql +2 -2
- data/test/fixtures/db_definitions/i5/ibm_db2.sql +5 -5
- data/test/fixtures/db_definitions/zOS/ibm_db.drop.sql +32 -32
- data/test/fixtures/db_definitions/zOS/ibm_db.sql +284 -284
- data/test/fixtures/db_definitions/zOS/ibm_db2.drop.sql +2 -2
- data/test/fixtures/db_definitions/zOS/ibm_db2.sql +7 -7
- metadata +36 -35
data/test/adapter_test.rb
CHANGED
@@ -1,131 +1,131 @@
|
|
1
|
-
require 'abstract_unit'
|
2
|
-
|
3
|
-
class AdapterTest < Test::Unit::TestCase
|
4
|
-
def setup
|
5
|
-
@connection = ActiveRecord::Base.connection
|
6
|
-
end
|
7
|
-
|
8
|
-
if current_adapter?(:IBM_DBAdapter)
|
9
|
-
def test_a_connection_attributes
|
10
|
-
if @connection.servertype.class.name.include?('::IBM_IDS')
|
11
|
-
return
|
12
|
-
end
|
13
|
-
if @connection.respond_to?(:schema)
|
14
|
-
previous_schema = ActiveRecord::Base.connection.schema
|
15
|
-
ActiveRecord::Base.connection.schema = 'SYSCAT'
|
16
|
-
assert_equal 'SYSCAT', ActiveRecord::Base.connection.schema
|
17
|
-
ActiveRecord::Base.connection.schema = previous_schema
|
18
|
-
else
|
19
|
-
warn "#{@connection.class} does not support client connection attribute schema_name"
|
20
|
-
end
|
21
|
-
|
22
|
-
if @connection.respond_to?(:app_user)
|
23
|
-
ActiveRecord::Base.connection.app_user = 'new_user'
|
24
|
-
assert_equal 'new_user', ActiveRecord::Base.connection.app_user
|
25
|
-
else
|
26
|
-
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_USER"
|
27
|
-
end
|
28
|
-
|
29
|
-
if @connection.respond_to?(:account)
|
30
|
-
ActiveRecord::Base.connection.account = 'new_acct'
|
31
|
-
assert_equal 'new_acct', ActiveRecord::Base.connection.account
|
32
|
-
else
|
33
|
-
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_ACCTSTR"
|
34
|
-
end
|
35
|
-
|
36
|
-
if @connection.respond_to?(:application)
|
37
|
-
ActiveRecord::Base.connection.application = 'new_app'
|
38
|
-
assert_equal 'new_app', ActiveRecord::Base.connection.application
|
39
|
-
else
|
40
|
-
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_APPLNAME"
|
41
|
-
end
|
42
|
-
|
43
|
-
if @connection.respond_to?(:workstation)
|
44
|
-
ActiveRecord::Base.connection.workstation = 'new_wrkst'
|
45
|
-
assert_equal 'new_wrkst', ActiveRecord::Base.connection.workstation
|
46
|
-
else
|
47
|
-
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_WRKSTNNAME"
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_tables
|
53
|
-
if @connection.respond_to?(:tables)
|
54
|
-
tables = @connection.tables
|
55
|
-
assert tables.include?("accounts")
|
56
|
-
assert tables.include?("authors")
|
57
|
-
assert tables.include?("tasks")
|
58
|
-
assert tables.include?("topics")
|
59
|
-
else
|
60
|
-
warn "#{@connection.class} does not respond to #tables"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def test_indexes
|
65
|
-
idx_name = "accounts_idx"
|
66
|
-
|
67
|
-
if @connection.respond_to?(:indexes)
|
68
|
-
indexes = @connection.indexes("accounts")
|
69
|
-
assert indexes.empty?
|
70
|
-
|
71
|
-
@connection.add_index :accounts, :firm_id, :name => idx_name
|
72
|
-
indexes = @connection.indexes("accounts")
|
73
|
-
assert_equal "accounts", indexes.first.table
|
74
|
-
# OpenBase does not have the concept of a named index
|
75
|
-
# Indexes are merely properties of columns.
|
76
|
-
assert_equal idx_name, indexes.first.name unless current_adapter?(:OpenBaseAdapter)
|
77
|
-
assert !indexes.first.unique
|
78
|
-
assert_equal ["firm_id"], indexes.first.columns
|
79
|
-
else
|
80
|
-
warn "#{@connection.class} does not respond to #indexes"
|
81
|
-
end
|
82
|
-
|
83
|
-
ensure
|
84
|
-
@connection.remove_index(:accounts, :name => idx_name) rescue nil
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_current_database
|
88
|
-
if @connection.respond_to?(:current_database)
|
89
|
-
assert_equal ENV['ARUNIT_DB_NAME'] || "activerecord_unittest", @connection.current_database
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def test_table_alias
|
94
|
-
def @connection.test_table_alias_length() 10; end
|
95
|
-
class << @connection
|
96
|
-
alias_method :old_table_alias_length, :table_alias_length
|
97
|
-
alias_method :table_alias_length, :test_table_alias_length
|
98
|
-
end
|
99
|
-
|
100
|
-
assert_equal 'posts', @connection.table_alias_for('posts')
|
101
|
-
assert_equal 'posts_comm', @connection.table_alias_for('posts_comments')
|
102
|
-
assert_equal 'dbo_posts', @connection.table_alias_for('dbo.posts')
|
103
|
-
|
104
|
-
class << @connection
|
105
|
-
alias_method :table_alias_length, :old_table_alias_length
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# test resetting sequences in odd tables in postgreSQL
|
110
|
-
if ActiveRecord::Base.connection.respond_to?(:reset_pk_sequence!)
|
111
|
-
require 'fixtures/movie'
|
112
|
-
require 'fixtures/subscriber'
|
113
|
-
|
114
|
-
def test_reset_empty_table_with_custom_pk
|
115
|
-
Movie.delete_all
|
116
|
-
Movie.connection.reset_pk_sequence! 'movies'
|
117
|
-
assert_equal 1, Movie.create(:name => 'fight club').id
|
118
|
-
end
|
119
|
-
|
120
|
-
if ActiveRecord::Base.connection.adapter_name != "FrontBase"
|
121
|
-
def test_reset_table_with_non_integer_pk
|
122
|
-
Subscriber.delete_all
|
123
|
-
Subscriber.connection.reset_pk_sequence! 'subscribers'
|
124
|
-
sub = Subscriber.new(:name => 'robert drake')
|
125
|
-
sub.id = 'bob drake'
|
126
|
-
assert_nothing_raised { sub.save! }
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
end
|
1
|
+
require 'abstract_unit'
|
2
|
+
|
3
|
+
class AdapterTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@connection = ActiveRecord::Base.connection
|
6
|
+
end
|
7
|
+
|
8
|
+
if current_adapter?(:IBM_DBAdapter)
|
9
|
+
def test_a_connection_attributes
|
10
|
+
if @connection.servertype.class.name.include?('::IBM_IDS')
|
11
|
+
return
|
12
|
+
end
|
13
|
+
if @connection.respond_to?(:schema)
|
14
|
+
previous_schema = ActiveRecord::Base.connection.schema
|
15
|
+
ActiveRecord::Base.connection.schema = 'SYSCAT'
|
16
|
+
assert_equal 'SYSCAT', ActiveRecord::Base.connection.schema
|
17
|
+
ActiveRecord::Base.connection.schema = previous_schema
|
18
|
+
else
|
19
|
+
warn "#{@connection.class} does not support client connection attribute schema_name"
|
20
|
+
end
|
21
|
+
|
22
|
+
if @connection.respond_to?(:app_user)
|
23
|
+
ActiveRecord::Base.connection.app_user = 'new_user'
|
24
|
+
assert_equal 'new_user', ActiveRecord::Base.connection.app_user
|
25
|
+
else
|
26
|
+
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_USER"
|
27
|
+
end
|
28
|
+
|
29
|
+
if @connection.respond_to?(:account)
|
30
|
+
ActiveRecord::Base.connection.account = 'new_acct'
|
31
|
+
assert_equal 'new_acct', ActiveRecord::Base.connection.account
|
32
|
+
else
|
33
|
+
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_ACCTSTR"
|
34
|
+
end
|
35
|
+
|
36
|
+
if @connection.respond_to?(:application)
|
37
|
+
ActiveRecord::Base.connection.application = 'new_app'
|
38
|
+
assert_equal 'new_app', ActiveRecord::Base.connection.application
|
39
|
+
else
|
40
|
+
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_APPLNAME"
|
41
|
+
end
|
42
|
+
|
43
|
+
if @connection.respond_to?(:workstation)
|
44
|
+
ActiveRecord::Base.connection.workstation = 'new_wrkst'
|
45
|
+
assert_equal 'new_wrkst', ActiveRecord::Base.connection.workstation
|
46
|
+
else
|
47
|
+
warn "#{@connection.class} does not support client connection attribute SQL_ATTR_INFO_WRKSTNNAME"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_tables
|
53
|
+
if @connection.respond_to?(:tables)
|
54
|
+
tables = @connection.tables
|
55
|
+
assert tables.include?("accounts")
|
56
|
+
assert tables.include?("authors")
|
57
|
+
assert tables.include?("tasks")
|
58
|
+
assert tables.include?("topics")
|
59
|
+
else
|
60
|
+
warn "#{@connection.class} does not respond to #tables"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_indexes
|
65
|
+
idx_name = "accounts_idx"
|
66
|
+
|
67
|
+
if @connection.respond_to?(:indexes)
|
68
|
+
indexes = @connection.indexes("accounts")
|
69
|
+
assert indexes.empty?
|
70
|
+
|
71
|
+
@connection.add_index :accounts, :firm_id, :name => idx_name
|
72
|
+
indexes = @connection.indexes("accounts")
|
73
|
+
assert_equal "accounts", indexes.first.table
|
74
|
+
# OpenBase does not have the concept of a named index
|
75
|
+
# Indexes are merely properties of columns.
|
76
|
+
assert_equal idx_name, indexes.first.name unless current_adapter?(:OpenBaseAdapter)
|
77
|
+
assert !indexes.first.unique
|
78
|
+
assert_equal ["firm_id"], indexes.first.columns
|
79
|
+
else
|
80
|
+
warn "#{@connection.class} does not respond to #indexes"
|
81
|
+
end
|
82
|
+
|
83
|
+
ensure
|
84
|
+
@connection.remove_index(:accounts, :name => idx_name) rescue nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_current_database
|
88
|
+
if @connection.respond_to?(:current_database)
|
89
|
+
assert_equal ENV['ARUNIT_DB_NAME'] || "activerecord_unittest", @connection.current_database
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_table_alias
|
94
|
+
def @connection.test_table_alias_length() 10; end
|
95
|
+
class << @connection
|
96
|
+
alias_method :old_table_alias_length, :table_alias_length
|
97
|
+
alias_method :table_alias_length, :test_table_alias_length
|
98
|
+
end
|
99
|
+
|
100
|
+
assert_equal 'posts', @connection.table_alias_for('posts')
|
101
|
+
assert_equal 'posts_comm', @connection.table_alias_for('posts_comments')
|
102
|
+
assert_equal 'dbo_posts', @connection.table_alias_for('dbo.posts')
|
103
|
+
|
104
|
+
class << @connection
|
105
|
+
alias_method :table_alias_length, :old_table_alias_length
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# test resetting sequences in odd tables in postgreSQL
|
110
|
+
if ActiveRecord::Base.connection.respond_to?(:reset_pk_sequence!)
|
111
|
+
require 'fixtures/movie'
|
112
|
+
require 'fixtures/subscriber'
|
113
|
+
|
114
|
+
def test_reset_empty_table_with_custom_pk
|
115
|
+
Movie.delete_all
|
116
|
+
Movie.connection.reset_pk_sequence! 'movies'
|
117
|
+
assert_equal 1, Movie.create(:name => 'fight club').id
|
118
|
+
end
|
119
|
+
|
120
|
+
if ActiveRecord::Base.connection.adapter_name != "FrontBase"
|
121
|
+
def test_reset_table_with_non_integer_pk
|
122
|
+
Subscriber.delete_all
|
123
|
+
Subscriber.connection.reset_pk_sequence! 'subscribers'
|
124
|
+
sub = Subscriber.new(:name => 'robert drake')
|
125
|
+
sub.id = 'bob drake'
|
126
|
+
assert_nothing_raised { sub.save! }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
@@ -1,445 +1,445 @@
|
|
1
|
-
require 'abstract_unit'
|
2
|
-
require 'fixtures/post'
|
3
|
-
require 'fixtures/comment'
|
4
|
-
require 'fixtures/author'
|
5
|
-
require 'fixtures/category'
|
6
|
-
require 'fixtures/company'
|
7
|
-
require 'fixtures/person'
|
8
|
-
require 'fixtures/reader'
|
9
|
-
|
10
|
-
class EagerAssociationTest < Test::Unit::TestCase
|
11
|
-
fixtures :posts, :comments, :authors, :categories, :categories_posts,
|
12
|
-
:companies, :accounts, :tags, :people, :readers
|
13
|
-
|
14
|
-
def test_loading_with_one_association
|
15
|
-
posts = Post.find(:all, :include => :comments)
|
16
|
-
post = posts.find { |p| p.id == 1 }
|
17
|
-
assert_equal 2, post.comments.size
|
18
|
-
assert post.comments.include?(comments(:greetings))
|
19
|
-
|
20
|
-
post = Post.find(:first, :include => :comments, :conditions => "posts.title = 'Welcome to the weblog'")
|
21
|
-
assert_equal 2, post.comments.size
|
22
|
-
assert post.comments.include?(comments(:greetings))
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_loading_conditions_with_or
|
26
|
-
posts = authors(:david).posts.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'")
|
27
|
-
assert_nil posts.detect { |p| p.author_id != authors(:david).id },
|
28
|
-
"expected to find only david's posts"
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_with_ordering
|
32
|
-
list = Post.find(:all, :include => :comments, :order => "posts.id DESC")
|
33
|
-
[:eager_other, :sti_habtm, :sti_post_and_comments, :sti_comments,
|
34
|
-
:authorless, :thinking, :welcome
|
35
|
-
].each_with_index do |post, index|
|
36
|
-
assert_equal posts(post), list[index]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_loading_with_multiple_associations
|
41
|
-
posts = Post.find(:all, :include => [ :comments, :author, :categories ], :order => "posts.id")
|
42
|
-
assert_equal 2, posts.first.comments.size
|
43
|
-
assert_equal 2, posts.first.categories.size
|
44
|
-
assert posts.first.comments.include?(comments(:greetings))
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_loading_from_an_association
|
48
|
-
posts = authors(:david).posts.find(:all, :include => :comments, :order => "posts.id")
|
49
|
-
assert_equal 2, posts.first.comments.size
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_loading_with_no_associations
|
53
|
-
assert_nil Post.find(posts(:authorless).id, :include => :author).author
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_eager_association_loading_with_belongs_to
|
57
|
-
comments = Comment.find(:all, :include => :post)
|
58
|
-
assert_equal 10, comments.length
|
59
|
-
titles = comments.map { |c| c.post.title }
|
60
|
-
assert titles.include?(posts(:welcome).title)
|
61
|
-
assert titles.include?(posts(:sti_post_and_comments).title)
|
62
|
-
end
|
63
|
-
|
64
|
-
def test_eager_association_loading_with_belongs_to_and_limit
|
65
|
-
comments = Comment.find(:all, :include => :post, :limit => 5, :order => 'comments.id')
|
66
|
-
assert_equal 5, comments.length
|
67
|
-
assert_equal [1,2,3,5,6], comments.collect { |c| c.id }
|
68
|
-
end
|
69
|
-
|
70
|
-
def test_eager_association_loading_with_belongs_to_and_limit_and_conditions
|
71
|
-
comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :order => 'comments.id')
|
72
|
-
assert_equal 3, comments.length
|
73
|
-
assert_equal [5,6,7], comments.collect { |c| c.id }
|
74
|
-
end
|
75
|
-
|
76
|
-
def test_eager_association_loading_with_belongs_to_and_limit_and_offset
|
77
|
-
comments = Comment.find(:all, :include => :post, :limit => 3, :offset => 2, :order => 'comments.id')
|
78
|
-
assert_equal 3, comments.length
|
79
|
-
assert_equal [3,5,6], comments.collect { |c| c.id }
|
80
|
-
end
|
81
|
-
|
82
|
-
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions
|
83
|
-
comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :offset => 1, :order => 'comments.id')
|
84
|
-
assert_equal 3, comments.length
|
85
|
-
assert_equal [6,7,8], comments.collect { |c| c.id }
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions_array
|
89
|
-
comments = Comment.find(:all, :include => :post, :conditions => ['post_id = ?',4], :limit => 3, :offset => 1, :order => 'comments.id')
|
90
|
-
assert_equal 3, comments.length
|
91
|
-
assert_equal [6,7,8], comments.collect { |c| c.id }
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_eager_association_loading_with_belongs_to_and_limit_and_multiple_associations
|
95
|
-
posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :order => 'posts.id')
|
96
|
-
assert_equal 1, posts.length
|
97
|
-
assert_equal [1], posts.collect { |p| p.id }
|
98
|
-
end
|
99
|
-
|
100
|
-
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_multiple_associations
|
101
|
-
posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :offset => 1, :order => 'posts.id')
|
102
|
-
assert_equal 1, posts.length
|
103
|
-
assert_equal [2], posts.collect { |p| p.id }
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_eager_with_has_many_through
|
107
|
-
posts_with_comments = people(:michael).posts.find(:all, :include => :comments)
|
108
|
-
posts_with_author = people(:michael).posts.find(:all, :include => :author )
|
109
|
-
posts_with_comments_and_author = people(:michael).posts.find(:all, :include => [ :comments, :author ])
|
110
|
-
assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum += post.comments.size }
|
111
|
-
assert_equal authors(:david), assert_no_queries { posts_with_author.first.author }
|
112
|
-
assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author }
|
113
|
-
end
|
114
|
-
|
115
|
-
def test_eager_with_has_many_through_an_sti_join_model
|
116
|
-
author = Author.find(:first, :include => :special_post_comments, :order => 'authors.id')
|
117
|
-
assert_equal [comments(:does_it_hurt)], assert_no_queries { author.special_post_comments }
|
118
|
-
end
|
119
|
-
|
120
|
-
def test_eager_with_has_many_through_an_sti_join_model_with_conditions_on_both
|
121
|
-
author = Author.find(:first, :include => :special_nonexistant_post_comments, :order => 'authors.id')
|
122
|
-
assert_equal [], author.special_nonexistant_post_comments
|
123
|
-
end
|
124
|
-
|
125
|
-
def test_eager_with_has_many_through_join_model_with_conditions
|
126
|
-
assert_equal Author.find(:first, :include => :hello_post_comments,
|
127
|
-
:order => 'authors.id').hello_post_comments.sort_by(&:id),
|
128
|
-
Author.find(:first, :order => 'authors.id').hello_post_comments.sort_by(&:id)
|
129
|
-
end
|
130
|
-
|
131
|
-
def test_eager_with_has_many_and_limit
|
132
|
-
posts = Post.find(:all, :order => 'posts.id asc', :include => [ :author, :comments ], :limit => 2)
|
133
|
-
assert_equal 2, posts.size
|
134
|
-
assert_equal 3, posts.inject(0) { |sum, post| sum += post.comments.size }
|
135
|
-
end
|
136
|
-
|
137
|
-
def test_eager_with_has_many_and_limit_and_conditions
|
138
|
-
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.body = 'hello'", :order => "posts.id")
|
139
|
-
assert_equal 2, posts.size
|
140
|
-
assert_equal [4,5], posts.collect { |p| p.id }
|
141
|
-
end
|
142
|
-
|
143
|
-
def test_eager_with_has_many_and_limit_and_conditions_array
|
144
|
-
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "posts.body = ?", 'hello' ], :order => "posts.id")
|
145
|
-
assert_equal 2, posts.size
|
146
|
-
assert_equal [4,5], posts.collect { |p| p.id }
|
147
|
-
end
|
148
|
-
|
149
|
-
def test_eager_with_has_many_and_limit_and_conditions_array_on_the_eagers
|
150
|
-
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
|
151
|
-
assert_equal 2, posts.size
|
152
|
-
|
153
|
-
count = Post.count(:include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
|
154
|
-
assert_equal count, posts.size
|
155
|
-
end
|
156
|
-
|
157
|
-
def test_eager_with_has_many_and_limit_ond_high_offset
|
158
|
-
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
|
159
|
-
assert_equal 0, posts.size
|
160
|
-
end
|
161
|
-
|
162
|
-
def test_count_eager_with_has_many_and_limit_ond_high_offset
|
163
|
-
posts = Post.count(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
|
164
|
-
assert_equal 0, posts
|
165
|
-
end
|
166
|
-
|
167
|
-
def test_eager_with_has_many_and_limit_with_no_results
|
168
|
-
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.title = 'magic forest'")
|
169
|
-
assert_equal 0, posts.size
|
170
|
-
end
|
171
|
-
|
172
|
-
def test_eager_with_has_and_belongs_to_many_and_limit
|
173
|
-
posts = Post.find(:all, :include => :categories, :order => "posts.id", :limit => 3)
|
174
|
-
assert_equal 3, posts.size
|
175
|
-
assert_equal 2, posts[0].categories.size
|
176
|
-
assert_equal 1, posts[1].categories.size
|
177
|
-
assert_equal 0, posts[2].categories.size
|
178
|
-
assert posts[0].categories.include?(categories(:technology))
|
179
|
-
assert posts[1].categories.include?(categories(:general))
|
180
|
-
end
|
181
|
-
|
182
|
-
def test_eager_with_has_many_and_limit_and_conditions_on_the_eagers
|
183
|
-
posts = authors(:david).posts.find(:all,
|
184
|
-
:include => :comments,
|
185
|
-
:conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
|
186
|
-
:limit => 2
|
187
|
-
)
|
188
|
-
assert_equal 2, posts.size
|
189
|
-
|
190
|
-
count = Post.count(
|
191
|
-
:include => [ :comments, :author ],
|
192
|
-
:conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
|
193
|
-
:limit => 2
|
194
|
-
)
|
195
|
-
assert_equal count, posts.size
|
196
|
-
end
|
197
|
-
|
198
|
-
def test_eager_with_has_many_and_limit_and_scoped_conditions_on_the_eagers
|
199
|
-
posts = nil
|
200
|
-
Post.with_scope(:find => {
|
201
|
-
:include => :comments,
|
202
|
-
:conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'"
|
203
|
-
}) do
|
204
|
-
posts = authors(:david).posts.find(:all, :limit => 2)
|
205
|
-
assert_equal 2, posts.size
|
206
|
-
end
|
207
|
-
|
208
|
-
Post.with_scope(:find => {
|
209
|
-
:include => [ :comments, :author ],
|
210
|
-
:conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')"
|
211
|
-
}) do
|
212
|
-
count = Post.count(:limit => 2)
|
213
|
-
assert_equal count, posts.size
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
def test_eager_with_has_many_and_limit_and_scoped_and_explicit_conditions_on_the_eagers
|
218
|
-
Post.with_scope(:find => { :conditions => "1=1" }) do
|
219
|
-
posts = authors(:david).posts.find(:all,
|
220
|
-
:include => :comments,
|
221
|
-
:conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
|
222
|
-
:limit => 2
|
223
|
-
)
|
224
|
-
assert_equal 2, posts.size
|
225
|
-
|
226
|
-
count = Post.count(
|
227
|
-
:include => [ :comments, :author ],
|
228
|
-
:conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
|
229
|
-
:limit => 2
|
230
|
-
)
|
231
|
-
assert_equal count, posts.size
|
232
|
-
end
|
233
|
-
end
|
234
|
-
def test_eager_association_loading_with_habtm
|
235
|
-
posts = Post.find(:all, :include => :categories, :order => "posts.id")
|
236
|
-
assert_equal 2, posts[0].categories.size
|
237
|
-
assert_equal 1, posts[1].categories.size
|
238
|
-
assert_equal 0, posts[2].categories.size
|
239
|
-
assert posts[0].categories.include?(categories(:technology))
|
240
|
-
assert posts[1].categories.include?(categories(:general))
|
241
|
-
end
|
242
|
-
|
243
|
-
def test_eager_with_inheritance
|
244
|
-
posts = SpecialPost.find(:all, :include => [ :comments ])
|
245
|
-
end
|
246
|
-
|
247
|
-
def test_eager_has_one_with_association_inheritance
|
248
|
-
post = Post.find(4, :include => [ :very_special_comment ])
|
249
|
-
assert_equal "VerySpecialComment", post.very_special_comment.class.to_s
|
250
|
-
end
|
251
|
-
|
252
|
-
def test_eager_has_many_with_association_inheritance
|
253
|
-
post = Post.find(4, :include => [ :special_comments ])
|
254
|
-
post.special_comments.each do |special_comment|
|
255
|
-
assert_equal "SpecialComment", special_comment.class.to_s
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
def test_eager_habtm_with_association_inheritance
|
260
|
-
post = Post.find(6, :include => [ :special_categories ])
|
261
|
-
assert_equal 1, post.special_categories.size
|
262
|
-
post.special_categories.each do |special_category|
|
263
|
-
assert_equal "SpecialCategory", special_category.class.to_s
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
def test_eager_with_has_one_dependent_does_not_destroy_dependent
|
268
|
-
assert_not_nil companies(:first_firm).account
|
269
|
-
f = Firm.find(:first, :include => :account,
|
270
|
-
:conditions => ["companies.name = ?", "37signals"])
|
271
|
-
assert_not_nil f.account
|
272
|
-
assert_equal companies(:first_firm, :reload).account, f.account
|
273
|
-
end
|
274
|
-
|
275
|
-
def test_eager_with_invalid_association_reference
|
276
|
-
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
277
|
-
post = Post.find(6, :include=> :monkeys )
|
278
|
-
}
|
279
|
-
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
280
|
-
post = Post.find(6, :include=>[ :monkeys ])
|
281
|
-
}
|
282
|
-
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
283
|
-
post = Post.find(6, :include=>[ 'monkeys' ])
|
284
|
-
}
|
285
|
-
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
|
286
|
-
post = Post.find(6, :include=>[ :monkeys, :elephants ])
|
287
|
-
}
|
288
|
-
end
|
289
|
-
|
290
|
-
def find_all_ordered(className, include=nil)
|
291
|
-
className.find(:all, :order=>"#{className.table_name}.#{className.primary_key}", :include=>include)
|
292
|
-
end
|
293
|
-
|
294
|
-
def test_limited_eager_with_order
|
295
|
-
unless current_adapter?(:IBM_DBAdapter)
|
296
|
-
assert_equal [posts(:thinking), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title)', :limit => 2, :offset => 1)
|
297
|
-
assert_equal [posts(:sti_post_and_comments), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC', :limit => 2, :offset => 1)
|
298
|
-
else
|
299
|
-
# LUW: [IBM][CLI Driver][DB2/LINUX] SQL0214N
|
300
|
-
# An expression in the ORDER BY clause in the following position,
|
301
|
-
# or starting with "UPPER..." in the "ORDER BY" clause is not valid.
|
302
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
303
|
-
# SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num
|
304
|
-
# FROM (SELECT DISTINCT posts.id FROM posts
|
305
|
-
# LEFT OUTER JOIN authors ON authors.id = posts.author_id
|
306
|
-
# LEFT OUTER JOIN comments ON comments.post_id = posts.id
|
307
|
-
# WHERE (authors.name = 'David')
|
308
|
-
# ORDER BY UPPER(posts.title)) AS I) AS O WHERE sys_row_num BETWEEN 2 AND 3
|
309
|
-
#
|
310
|
-
# i5: ActiveRecord::RecordNotFound: Couldn't find Post with ID=2
|
311
|
-
#
|
312
|
-
# zOS v9: ActiveRecord::RecordNotFound: Couldn't find Post with ID=2
|
313
|
-
#
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
def test_limited_eager_with_multiple_order_columns
|
318
|
-
unless current_adapter?(:IBM_DBAdapter)
|
319
|
-
assert_equal [posts(:thinking), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title), posts.id', :limit => 2, :offset => 1)
|
320
|
-
assert_equal [posts(:sti_post_and_comments), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1)
|
321
|
-
else
|
322
|
-
# LUW: [IBM][CLI Driver][DB2/LINUX] SQL0214N
|
323
|
-
# An expression in the ORDER BY clause in the following position,
|
324
|
-
# or starting with "UPPER..." in the "ORDER BY" clause is not valid.
|
325
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
326
|
-
# SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num
|
327
|
-
# FROM (SELECT DISTINCT posts.id FROM posts
|
328
|
-
# LEFT OUTER JOIN authors ON authors.id = posts.author_id
|
329
|
-
# LEFT OUTER JOIN comments ON comments.post_id = posts.id
|
330
|
-
# WHERE (authors.name = 'David')
|
331
|
-
# ORDER BY UPPER(posts.title), posts.id) AS I) AS O WHERE sys_row_num BETWEEN 2 AND 3
|
332
|
-
#
|
333
|
-
# i5: [IBM][CLI Driver][AS] SQL0214N
|
334
|
-
# An expression in the ORDER BY clause in the following position,
|
335
|
-
# or starting with "1" in the " OBY0002" clause is not valid.
|
336
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
337
|
-
# SELECT DISTINCT posts.id FROM posts
|
338
|
-
# LEFT OUTER JOIN authors ON authors.id = posts.author_id
|
339
|
-
# LEFT OUTER JOIN comments ON comments.post_id = posts.id
|
340
|
-
# WHERE (authors.name = 'David')
|
341
|
-
# ORDER BY UPPER(posts.title), posts.id
|
342
|
-
#
|
343
|
-
# zOS 9: [IBM][CLI Driver][DB2] SQL0214N
|
344
|
-
# An expression in the ORDER BY clause in the following position,
|
345
|
-
# or starting with "1" in the "ORDER BY" clause is not valid.
|
346
|
-
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
347
|
-
# SELECT DISTINCT posts.id FROM posts
|
348
|
-
# LEFT OUTER JOIN authors ON authors.id = posts.author_id
|
349
|
-
# LEFT OUTER JOIN comments ON comments.post_id = posts.id
|
350
|
-
# WHERE (authors.name = 'David')
|
351
|
-
# ORDER BY UPPER(posts.title), posts.id
|
352
|
-
#
|
353
|
-
end
|
354
|
-
end
|
355
|
-
|
356
|
-
def test_eager_with_multiple_associations_with_same_table_has_many_and_habtm
|
357
|
-
# Eager includes of has many and habtm associations aren't necessarily sorted in the same way
|
358
|
-
def assert_equal_after_sort(item1, item2, item3 = nil)
|
359
|
-
assert_equal(item1.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id})
|
360
|
-
assert_equal(item3.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id}) if item3
|
361
|
-
end
|
362
|
-
# Test regular association, association with conditions, association with
|
363
|
-
# STI, and association with conditions assured not to be true
|
364
|
-
post_types = [:posts, :other_posts, :special_posts]
|
365
|
-
# test both has_many and has_and_belongs_to_many
|
366
|
-
[Author, Category].each do |className|
|
367
|
-
d1 = find_all_ordered(className)
|
368
|
-
# test including all post types at once
|
369
|
-
d2 = find_all_ordered(className, post_types)
|
370
|
-
d1.each_index do |i|
|
371
|
-
assert_equal(d1[i], d2[i])
|
372
|
-
assert_equal_after_sort(d1[i].posts, d2[i].posts)
|
373
|
-
post_types[1..-1].each do |post_type|
|
374
|
-
# test including post_types together
|
375
|
-
d3 = find_all_ordered(className, [:posts, post_type])
|
376
|
-
assert_equal(d1[i], d3[i])
|
377
|
-
assert_equal_after_sort(d1[i].posts, d3[i].posts)
|
378
|
-
assert_equal_after_sort(d1[i].send(post_type), d2[i].send(post_type), d3[i].send(post_type))
|
379
|
-
end
|
380
|
-
end
|
381
|
-
end
|
382
|
-
end
|
383
|
-
|
384
|
-
def test_eager_with_multiple_associations_with_same_table_has_one
|
385
|
-
d1 = find_all_ordered(Firm)
|
386
|
-
d2 = find_all_ordered(Firm, :account)
|
387
|
-
d1.each_index do |i|
|
388
|
-
assert_equal(d1[i], d2[i])
|
389
|
-
assert_equal(d1[i].account, d2[i].account)
|
390
|
-
end
|
391
|
-
end
|
392
|
-
|
393
|
-
def test_eager_with_multiple_associations_with_same_table_belongs_to
|
394
|
-
firm_types = [:firm, :firm_with_basic_id, :firm_with_other_name, :firm_with_condition]
|
395
|
-
d1 = find_all_ordered(Client)
|
396
|
-
d2 = find_all_ordered(Client, firm_types)
|
397
|
-
d1.each_index do |i|
|
398
|
-
assert_equal(d1[i], d2[i])
|
399
|
-
firm_types.each { |type| assert_equal(d1[i].send(type), d2[i].send(type)) }
|
400
|
-
end
|
401
|
-
end
|
402
|
-
def test_eager_with_valid_association_as_string_not_symbol
|
403
|
-
assert_nothing_raised { Post.find(:all, :include => 'comments') }
|
404
|
-
end
|
405
|
-
|
406
|
-
def test_preconfigured_includes_with_belongs_to
|
407
|
-
author = posts(:welcome).author_with_posts
|
408
|
-
assert_equal 5, author.posts.size
|
409
|
-
end
|
410
|
-
|
411
|
-
def test_preconfigured_includes_with_has_one
|
412
|
-
comment = posts(:sti_comments).very_special_comment_with_post
|
413
|
-
assert_equal posts(:sti_comments), comment.post
|
414
|
-
end
|
415
|
-
|
416
|
-
def test_preconfigured_includes_with_has_many
|
417
|
-
posts = authors(:david).posts_with_comments
|
418
|
-
one = posts.detect { |p| p.id == 1 }
|
419
|
-
assert_equal 5, posts.size
|
420
|
-
assert_equal 2, one.comments.size
|
421
|
-
end
|
422
|
-
|
423
|
-
def test_preconfigured_includes_with_habtm
|
424
|
-
posts = authors(:david).posts_with_categories
|
425
|
-
one = posts.detect { |p| p.id == 1 }
|
426
|
-
assert_equal 5, posts.size
|
427
|
-
assert_equal 2, one.categories.size
|
428
|
-
end
|
429
|
-
|
430
|
-
def test_preconfigured_includes_with_has_many_and_habtm
|
431
|
-
posts = authors(:david).posts_with_comments_and_categories
|
432
|
-
one = posts.detect { |p| p.id == 1 }
|
433
|
-
assert_equal 5, posts.size
|
434
|
-
assert_equal 2, one.comments.size
|
435
|
-
assert_equal 2, one.categories.size
|
436
|
-
end
|
437
|
-
|
438
|
-
def test_count_with_include
|
439
|
-
if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
|
440
|
-
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15")
|
441
|
-
else
|
442
|
-
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(comments.body) > 15")
|
443
|
-
end
|
444
|
-
end
|
445
|
-
end
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/post'
|
3
|
+
require 'fixtures/comment'
|
4
|
+
require 'fixtures/author'
|
5
|
+
require 'fixtures/category'
|
6
|
+
require 'fixtures/company'
|
7
|
+
require 'fixtures/person'
|
8
|
+
require 'fixtures/reader'
|
9
|
+
|
10
|
+
class EagerAssociationTest < Test::Unit::TestCase
|
11
|
+
fixtures :posts, :comments, :authors, :categories, :categories_posts,
|
12
|
+
:companies, :accounts, :tags, :people, :readers
|
13
|
+
|
14
|
+
def test_loading_with_one_association
|
15
|
+
posts = Post.find(:all, :include => :comments)
|
16
|
+
post = posts.find { |p| p.id == 1 }
|
17
|
+
assert_equal 2, post.comments.size
|
18
|
+
assert post.comments.include?(comments(:greetings))
|
19
|
+
|
20
|
+
post = Post.find(:first, :include => :comments, :conditions => "posts.title = 'Welcome to the weblog'")
|
21
|
+
assert_equal 2, post.comments.size
|
22
|
+
assert post.comments.include?(comments(:greetings))
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_loading_conditions_with_or
|
26
|
+
posts = authors(:david).posts.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'")
|
27
|
+
assert_nil posts.detect { |p| p.author_id != authors(:david).id },
|
28
|
+
"expected to find only david's posts"
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_with_ordering
|
32
|
+
list = Post.find(:all, :include => :comments, :order => "posts.id DESC")
|
33
|
+
[:eager_other, :sti_habtm, :sti_post_and_comments, :sti_comments,
|
34
|
+
:authorless, :thinking, :welcome
|
35
|
+
].each_with_index do |post, index|
|
36
|
+
assert_equal posts(post), list[index]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_loading_with_multiple_associations
|
41
|
+
posts = Post.find(:all, :include => [ :comments, :author, :categories ], :order => "posts.id")
|
42
|
+
assert_equal 2, posts.first.comments.size
|
43
|
+
assert_equal 2, posts.first.categories.size
|
44
|
+
assert posts.first.comments.include?(comments(:greetings))
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_loading_from_an_association
|
48
|
+
posts = authors(:david).posts.find(:all, :include => :comments, :order => "posts.id")
|
49
|
+
assert_equal 2, posts.first.comments.size
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_loading_with_no_associations
|
53
|
+
assert_nil Post.find(posts(:authorless).id, :include => :author).author
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_eager_association_loading_with_belongs_to
|
57
|
+
comments = Comment.find(:all, :include => :post)
|
58
|
+
assert_equal 10, comments.length
|
59
|
+
titles = comments.map { |c| c.post.title }
|
60
|
+
assert titles.include?(posts(:welcome).title)
|
61
|
+
assert titles.include?(posts(:sti_post_and_comments).title)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_eager_association_loading_with_belongs_to_and_limit
|
65
|
+
comments = Comment.find(:all, :include => :post, :limit => 5, :order => 'comments.id')
|
66
|
+
assert_equal 5, comments.length
|
67
|
+
assert_equal [1,2,3,5,6], comments.collect { |c| c.id }
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_conditions
|
71
|
+
comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :order => 'comments.id')
|
72
|
+
assert_equal 3, comments.length
|
73
|
+
assert_equal [5,6,7], comments.collect { |c| c.id }
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset
|
77
|
+
comments = Comment.find(:all, :include => :post, :limit => 3, :offset => 2, :order => 'comments.id')
|
78
|
+
assert_equal 3, comments.length
|
79
|
+
assert_equal [3,5,6], comments.collect { |c| c.id }
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions
|
83
|
+
comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :offset => 1, :order => 'comments.id')
|
84
|
+
assert_equal 3, comments.length
|
85
|
+
assert_equal [6,7,8], comments.collect { |c| c.id }
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions_array
|
89
|
+
comments = Comment.find(:all, :include => :post, :conditions => ['post_id = ?',4], :limit => 3, :offset => 1, :order => 'comments.id')
|
90
|
+
assert_equal 3, comments.length
|
91
|
+
assert_equal [6,7,8], comments.collect { |c| c.id }
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_multiple_associations
|
95
|
+
posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :order => 'posts.id')
|
96
|
+
assert_equal 1, posts.length
|
97
|
+
assert_equal [1], posts.collect { |p| p.id }
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_multiple_associations
|
101
|
+
posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :offset => 1, :order => 'posts.id')
|
102
|
+
assert_equal 1, posts.length
|
103
|
+
assert_equal [2], posts.collect { |p| p.id }
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_eager_with_has_many_through
|
107
|
+
posts_with_comments = people(:michael).posts.find(:all, :include => :comments)
|
108
|
+
posts_with_author = people(:michael).posts.find(:all, :include => :author )
|
109
|
+
posts_with_comments_and_author = people(:michael).posts.find(:all, :include => [ :comments, :author ])
|
110
|
+
assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum += post.comments.size }
|
111
|
+
assert_equal authors(:david), assert_no_queries { posts_with_author.first.author }
|
112
|
+
assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author }
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_eager_with_has_many_through_an_sti_join_model
|
116
|
+
author = Author.find(:first, :include => :special_post_comments, :order => 'authors.id')
|
117
|
+
assert_equal [comments(:does_it_hurt)], assert_no_queries { author.special_post_comments }
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_eager_with_has_many_through_an_sti_join_model_with_conditions_on_both
|
121
|
+
author = Author.find(:first, :include => :special_nonexistant_post_comments, :order => 'authors.id')
|
122
|
+
assert_equal [], author.special_nonexistant_post_comments
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_eager_with_has_many_through_join_model_with_conditions
|
126
|
+
assert_equal Author.find(:first, :include => :hello_post_comments,
|
127
|
+
:order => 'authors.id').hello_post_comments.sort_by(&:id),
|
128
|
+
Author.find(:first, :order => 'authors.id').hello_post_comments.sort_by(&:id)
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_eager_with_has_many_and_limit
|
132
|
+
posts = Post.find(:all, :order => 'posts.id asc', :include => [ :author, :comments ], :limit => 2)
|
133
|
+
assert_equal 2, posts.size
|
134
|
+
assert_equal 3, posts.inject(0) { |sum, post| sum += post.comments.size }
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_eager_with_has_many_and_limit_and_conditions
|
138
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.body = 'hello'", :order => "posts.id")
|
139
|
+
assert_equal 2, posts.size
|
140
|
+
assert_equal [4,5], posts.collect { |p| p.id }
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_eager_with_has_many_and_limit_and_conditions_array
|
144
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "posts.body = ?", 'hello' ], :order => "posts.id")
|
145
|
+
assert_equal 2, posts.size
|
146
|
+
assert_equal [4,5], posts.collect { |p| p.id }
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_eager_with_has_many_and_limit_and_conditions_array_on_the_eagers
|
150
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
|
151
|
+
assert_equal 2, posts.size
|
152
|
+
|
153
|
+
count = Post.count(:include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ])
|
154
|
+
assert_equal count, posts.size
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_eager_with_has_many_and_limit_ond_high_offset
|
158
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
|
159
|
+
assert_equal 0, posts.size
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_count_eager_with_has_many_and_limit_ond_high_offset
|
163
|
+
posts = Post.count(:all, :include => [ :author, :comments ], :limit => 2, :offset => 10, :conditions => [ "authors.name = ?", 'David' ])
|
164
|
+
assert_equal 0, posts
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_eager_with_has_many_and_limit_with_no_results
|
168
|
+
posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.title = 'magic forest'")
|
169
|
+
assert_equal 0, posts.size
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_eager_with_has_and_belongs_to_many_and_limit
|
173
|
+
posts = Post.find(:all, :include => :categories, :order => "posts.id", :limit => 3)
|
174
|
+
assert_equal 3, posts.size
|
175
|
+
assert_equal 2, posts[0].categories.size
|
176
|
+
assert_equal 1, posts[1].categories.size
|
177
|
+
assert_equal 0, posts[2].categories.size
|
178
|
+
assert posts[0].categories.include?(categories(:technology))
|
179
|
+
assert posts[1].categories.include?(categories(:general))
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_eager_with_has_many_and_limit_and_conditions_on_the_eagers
|
183
|
+
posts = authors(:david).posts.find(:all,
|
184
|
+
:include => :comments,
|
185
|
+
:conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
|
186
|
+
:limit => 2
|
187
|
+
)
|
188
|
+
assert_equal 2, posts.size
|
189
|
+
|
190
|
+
count = Post.count(
|
191
|
+
:include => [ :comments, :author ],
|
192
|
+
:conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
|
193
|
+
:limit => 2
|
194
|
+
)
|
195
|
+
assert_equal count, posts.size
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_eager_with_has_many_and_limit_and_scoped_conditions_on_the_eagers
|
199
|
+
posts = nil
|
200
|
+
Post.with_scope(:find => {
|
201
|
+
:include => :comments,
|
202
|
+
:conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'"
|
203
|
+
}) do
|
204
|
+
posts = authors(:david).posts.find(:all, :limit => 2)
|
205
|
+
assert_equal 2, posts.size
|
206
|
+
end
|
207
|
+
|
208
|
+
Post.with_scope(:find => {
|
209
|
+
:include => [ :comments, :author ],
|
210
|
+
:conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')"
|
211
|
+
}) do
|
212
|
+
count = Post.count(:limit => 2)
|
213
|
+
assert_equal count, posts.size
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_eager_with_has_many_and_limit_and_scoped_and_explicit_conditions_on_the_eagers
|
218
|
+
Post.with_scope(:find => { :conditions => "1=1" }) do
|
219
|
+
posts = authors(:david).posts.find(:all,
|
220
|
+
:include => :comments,
|
221
|
+
:conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
|
222
|
+
:limit => 2
|
223
|
+
)
|
224
|
+
assert_equal 2, posts.size
|
225
|
+
|
226
|
+
count = Post.count(
|
227
|
+
:include => [ :comments, :author ],
|
228
|
+
:conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
|
229
|
+
:limit => 2
|
230
|
+
)
|
231
|
+
assert_equal count, posts.size
|
232
|
+
end
|
233
|
+
end
|
234
|
+
def test_eager_association_loading_with_habtm
|
235
|
+
posts = Post.find(:all, :include => :categories, :order => "posts.id")
|
236
|
+
assert_equal 2, posts[0].categories.size
|
237
|
+
assert_equal 1, posts[1].categories.size
|
238
|
+
assert_equal 0, posts[2].categories.size
|
239
|
+
assert posts[0].categories.include?(categories(:technology))
|
240
|
+
assert posts[1].categories.include?(categories(:general))
|
241
|
+
end
|
242
|
+
|
243
|
+
def test_eager_with_inheritance
|
244
|
+
posts = SpecialPost.find(:all, :include => [ :comments ])
|
245
|
+
end
|
246
|
+
|
247
|
+
def test_eager_has_one_with_association_inheritance
|
248
|
+
post = Post.find(4, :include => [ :very_special_comment ])
|
249
|
+
assert_equal "VerySpecialComment", post.very_special_comment.class.to_s
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_eager_has_many_with_association_inheritance
|
253
|
+
post = Post.find(4, :include => [ :special_comments ])
|
254
|
+
post.special_comments.each do |special_comment|
|
255
|
+
assert_equal "SpecialComment", special_comment.class.to_s
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_eager_habtm_with_association_inheritance
|
260
|
+
post = Post.find(6, :include => [ :special_categories ])
|
261
|
+
assert_equal 1, post.special_categories.size
|
262
|
+
post.special_categories.each do |special_category|
|
263
|
+
assert_equal "SpecialCategory", special_category.class.to_s
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_eager_with_has_one_dependent_does_not_destroy_dependent
|
268
|
+
assert_not_nil companies(:first_firm).account
|
269
|
+
f = Firm.find(:first, :include => :account,
|
270
|
+
:conditions => ["companies.name = ?", "37signals"])
|
271
|
+
assert_not_nil f.account
|
272
|
+
assert_equal companies(:first_firm, :reload).account, f.account
|
273
|
+
end
|
274
|
+
|
275
|
+
def test_eager_with_invalid_association_reference
|
276
|
+
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
277
|
+
post = Post.find(6, :include=> :monkeys )
|
278
|
+
}
|
279
|
+
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
280
|
+
post = Post.find(6, :include=>[ :monkeys ])
|
281
|
+
}
|
282
|
+
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
|
283
|
+
post = Post.find(6, :include=>[ 'monkeys' ])
|
284
|
+
}
|
285
|
+
assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
|
286
|
+
post = Post.find(6, :include=>[ :monkeys, :elephants ])
|
287
|
+
}
|
288
|
+
end
|
289
|
+
|
290
|
+
def find_all_ordered(className, include=nil)
|
291
|
+
className.find(:all, :order=>"#{className.table_name}.#{className.primary_key}", :include=>include)
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_limited_eager_with_order
|
295
|
+
unless current_adapter?(:IBM_DBAdapter)
|
296
|
+
assert_equal [posts(:thinking), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title)', :limit => 2, :offset => 1)
|
297
|
+
assert_equal [posts(:sti_post_and_comments), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC', :limit => 2, :offset => 1)
|
298
|
+
else
|
299
|
+
# LUW: [IBM][CLI Driver][DB2/LINUX] SQL0214N
|
300
|
+
# An expression in the ORDER BY clause in the following position,
|
301
|
+
# or starting with "UPPER..." in the "ORDER BY" clause is not valid.
|
302
|
+
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
303
|
+
# SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num
|
304
|
+
# FROM (SELECT DISTINCT posts.id FROM posts
|
305
|
+
# LEFT OUTER JOIN authors ON authors.id = posts.author_id
|
306
|
+
# LEFT OUTER JOIN comments ON comments.post_id = posts.id
|
307
|
+
# WHERE (authors.name = 'David')
|
308
|
+
# ORDER BY UPPER(posts.title)) AS I) AS O WHERE sys_row_num BETWEEN 2 AND 3
|
309
|
+
#
|
310
|
+
# i5: ActiveRecord::RecordNotFound: Couldn't find Post with ID=2
|
311
|
+
#
|
312
|
+
# zOS v9: ActiveRecord::RecordNotFound: Couldn't find Post with ID=2
|
313
|
+
#
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def test_limited_eager_with_multiple_order_columns
|
318
|
+
unless current_adapter?(:IBM_DBAdapter)
|
319
|
+
assert_equal [posts(:thinking), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title), posts.id', :limit => 2, :offset => 1)
|
320
|
+
assert_equal [posts(:sti_post_and_comments), posts(:sti_comments)], Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1)
|
321
|
+
else
|
322
|
+
# LUW: [IBM][CLI Driver][DB2/LINUX] SQL0214N
|
323
|
+
# An expression in the ORDER BY clause in the following position,
|
324
|
+
# or starting with "UPPER..." in the "ORDER BY" clause is not valid.
|
325
|
+
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
326
|
+
# SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num
|
327
|
+
# FROM (SELECT DISTINCT posts.id FROM posts
|
328
|
+
# LEFT OUTER JOIN authors ON authors.id = posts.author_id
|
329
|
+
# LEFT OUTER JOIN comments ON comments.post_id = posts.id
|
330
|
+
# WHERE (authors.name = 'David')
|
331
|
+
# ORDER BY UPPER(posts.title), posts.id) AS I) AS O WHERE sys_row_num BETWEEN 2 AND 3
|
332
|
+
#
|
333
|
+
# i5: [IBM][CLI Driver][AS] SQL0214N
|
334
|
+
# An expression in the ORDER BY clause in the following position,
|
335
|
+
# or starting with "1" in the " OBY0002" clause is not valid.
|
336
|
+
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
337
|
+
# SELECT DISTINCT posts.id FROM posts
|
338
|
+
# LEFT OUTER JOIN authors ON authors.id = posts.author_id
|
339
|
+
# LEFT OUTER JOIN comments ON comments.post_id = posts.id
|
340
|
+
# WHERE (authors.name = 'David')
|
341
|
+
# ORDER BY UPPER(posts.title), posts.id
|
342
|
+
#
|
343
|
+
# zOS 9: [IBM][CLI Driver][DB2] SQL0214N
|
344
|
+
# An expression in the ORDER BY clause in the following position,
|
345
|
+
# or starting with "1" in the "ORDER BY" clause is not valid.
|
346
|
+
# Reason code = "2". SQLSTATE=42822 SQLCODE=-214:
|
347
|
+
# SELECT DISTINCT posts.id FROM posts
|
348
|
+
# LEFT OUTER JOIN authors ON authors.id = posts.author_id
|
349
|
+
# LEFT OUTER JOIN comments ON comments.post_id = posts.id
|
350
|
+
# WHERE (authors.name = 'David')
|
351
|
+
# ORDER BY UPPER(posts.title), posts.id
|
352
|
+
#
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
def test_eager_with_multiple_associations_with_same_table_has_many_and_habtm
|
357
|
+
# Eager includes of has many and habtm associations aren't necessarily sorted in the same way
|
358
|
+
def assert_equal_after_sort(item1, item2, item3 = nil)
|
359
|
+
assert_equal(item1.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id})
|
360
|
+
assert_equal(item3.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id}) if item3
|
361
|
+
end
|
362
|
+
# Test regular association, association with conditions, association with
|
363
|
+
# STI, and association with conditions assured not to be true
|
364
|
+
post_types = [:posts, :other_posts, :special_posts]
|
365
|
+
# test both has_many and has_and_belongs_to_many
|
366
|
+
[Author, Category].each do |className|
|
367
|
+
d1 = find_all_ordered(className)
|
368
|
+
# test including all post types at once
|
369
|
+
d2 = find_all_ordered(className, post_types)
|
370
|
+
d1.each_index do |i|
|
371
|
+
assert_equal(d1[i], d2[i])
|
372
|
+
assert_equal_after_sort(d1[i].posts, d2[i].posts)
|
373
|
+
post_types[1..-1].each do |post_type|
|
374
|
+
# test including post_types together
|
375
|
+
d3 = find_all_ordered(className, [:posts, post_type])
|
376
|
+
assert_equal(d1[i], d3[i])
|
377
|
+
assert_equal_after_sort(d1[i].posts, d3[i].posts)
|
378
|
+
assert_equal_after_sort(d1[i].send(post_type), d2[i].send(post_type), d3[i].send(post_type))
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_eager_with_multiple_associations_with_same_table_has_one
|
385
|
+
d1 = find_all_ordered(Firm)
|
386
|
+
d2 = find_all_ordered(Firm, :account)
|
387
|
+
d1.each_index do |i|
|
388
|
+
assert_equal(d1[i], d2[i])
|
389
|
+
assert_equal(d1[i].account, d2[i].account)
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
def test_eager_with_multiple_associations_with_same_table_belongs_to
|
394
|
+
firm_types = [:firm, :firm_with_basic_id, :firm_with_other_name, :firm_with_condition]
|
395
|
+
d1 = find_all_ordered(Client)
|
396
|
+
d2 = find_all_ordered(Client, firm_types)
|
397
|
+
d1.each_index do |i|
|
398
|
+
assert_equal(d1[i], d2[i])
|
399
|
+
firm_types.each { |type| assert_equal(d1[i].send(type), d2[i].send(type)) }
|
400
|
+
end
|
401
|
+
end
|
402
|
+
def test_eager_with_valid_association_as_string_not_symbol
|
403
|
+
assert_nothing_raised { Post.find(:all, :include => 'comments') }
|
404
|
+
end
|
405
|
+
|
406
|
+
def test_preconfigured_includes_with_belongs_to
|
407
|
+
author = posts(:welcome).author_with_posts
|
408
|
+
assert_equal 5, author.posts.size
|
409
|
+
end
|
410
|
+
|
411
|
+
def test_preconfigured_includes_with_has_one
|
412
|
+
comment = posts(:sti_comments).very_special_comment_with_post
|
413
|
+
assert_equal posts(:sti_comments), comment.post
|
414
|
+
end
|
415
|
+
|
416
|
+
def test_preconfigured_includes_with_has_many
|
417
|
+
posts = authors(:david).posts_with_comments
|
418
|
+
one = posts.detect { |p| p.id == 1 }
|
419
|
+
assert_equal 5, posts.size
|
420
|
+
assert_equal 2, one.comments.size
|
421
|
+
end
|
422
|
+
|
423
|
+
def test_preconfigured_includes_with_habtm
|
424
|
+
posts = authors(:david).posts_with_categories
|
425
|
+
one = posts.detect { |p| p.id == 1 }
|
426
|
+
assert_equal 5, posts.size
|
427
|
+
assert_equal 2, one.categories.size
|
428
|
+
end
|
429
|
+
|
430
|
+
def test_preconfigured_includes_with_has_many_and_habtm
|
431
|
+
posts = authors(:david).posts_with_comments_and_categories
|
432
|
+
one = posts.detect { |p| p.id == 1 }
|
433
|
+
assert_equal 5, posts.size
|
434
|
+
assert_equal 2, one.comments.size
|
435
|
+
assert_equal 2, one.categories.size
|
436
|
+
end
|
437
|
+
|
438
|
+
def test_count_with_include
|
439
|
+
if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
|
440
|
+
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "len(comments.body) > 15")
|
441
|
+
else
|
442
|
+
assert_equal 3, authors(:david).posts_with_comments.count(:conditions => "length(comments.body) > 15")
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end
|