ibm_db 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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
|