cbaclig-ar-extensions 0.9.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. data/ChangeLog +148 -0
  2. data/Manifest +111 -0
  3. data/README +167 -0
  4. data/Rakefile +65 -0
  5. data/ar-extensions.gemspec +19 -0
  6. data/benchmarks/README +32 -0
  7. data/benchmarks/benchmark.rb +61 -0
  8. data/benchmarks/boot.rb +21 -0
  9. data/benchmarks/lib/base.rb +121 -0
  10. data/benchmarks/lib/cli_parser.rb +103 -0
  11. data/benchmarks/lib/float.rb +15 -0
  12. data/benchmarks/lib/mysql_benchmark.rb +27 -0
  13. data/benchmarks/lib/output_to_csv.rb +18 -0
  14. data/benchmarks/lib/output_to_html.rb +69 -0
  15. data/cbaclig-ar-extensions.gemspec +30 -0
  16. data/config/database.yml +7 -0
  17. data/config/database.yml.template +7 -0
  18. data/config/mysql.schema +72 -0
  19. data/config/postgresql.schema +39 -0
  20. data/db/migrate/generic_schema.rb +97 -0
  21. data/db/migrate/mysql_schema.rb +32 -0
  22. data/db/migrate/oracle_schema.rb +5 -0
  23. data/db/migrate/version.rb +4 -0
  24. data/init.rb +31 -0
  25. data/lib/ar-extensions.rb +5 -0
  26. data/lib/ar-extensions/adapters/abstract_adapter.rb +139 -0
  27. data/lib/ar-extensions/adapters/mysql.rb +10 -0
  28. data/lib/ar-extensions/adapters/oracle.rb +14 -0
  29. data/lib/ar-extensions/adapters/postgresql.rb +9 -0
  30. data/lib/ar-extensions/adapters/sqlite.rb +7 -0
  31. data/lib/ar-extensions/create_and_update.rb +509 -0
  32. data/lib/ar-extensions/create_and_update/mysql.rb +7 -0
  33. data/lib/ar-extensions/csv.rb +309 -0
  34. data/lib/ar-extensions/delete.rb +143 -0
  35. data/lib/ar-extensions/delete/mysql.rb +3 -0
  36. data/lib/ar-extensions/extensions.rb +506 -0
  37. data/lib/ar-extensions/finder_options.rb +275 -0
  38. data/lib/ar-extensions/finder_options/mysql.rb +6 -0
  39. data/lib/ar-extensions/finders.rb +94 -0
  40. data/lib/ar-extensions/foreign_keys.rb +70 -0
  41. data/lib/ar-extensions/fulltext.rb +62 -0
  42. data/lib/ar-extensions/fulltext/mysql.rb +44 -0
  43. data/lib/ar-extensions/import.rb +362 -0
  44. data/lib/ar-extensions/import/mysql.rb +50 -0
  45. data/lib/ar-extensions/import/postgresql.rb +7 -0
  46. data/lib/ar-extensions/import/sqlite.rb +22 -0
  47. data/lib/ar-extensions/insert_select.rb +178 -0
  48. data/lib/ar-extensions/insert_select/mysql.rb +7 -0
  49. data/lib/ar-extensions/synchronize.rb +30 -0
  50. data/lib/ar-extensions/temporary_table.rb +131 -0
  51. data/lib/ar-extensions/temporary_table/mysql.rb +3 -0
  52. data/lib/ar-extensions/union.rb +204 -0
  53. data/lib/ar-extensions/union/mysql.rb +6 -0
  54. data/lib/ar-extensions/util/sql_generation.rb +27 -0
  55. data/lib/ar-extensions/util/support_methods.rb +32 -0
  56. data/lib/ar-extensions/version.rb +9 -0
  57. data/tests/README +68 -0
  58. data/tests/boot.rb +23 -0
  59. data/tests/database.yml +31 -0
  60. data/tests/database.yml.sample +28 -0
  61. data/tests/fixtures/addresses.yml +25 -0
  62. data/tests/fixtures/books.yml +46 -0
  63. data/tests/fixtures/developers.yml +20 -0
  64. data/tests/fixtures/unit/active_record_base_finders/addresses.yml +25 -0
  65. data/tests/fixtures/unit/active_record_base_finders/books.yml +64 -0
  66. data/tests/fixtures/unit/active_record_base_finders/developers.yml +20 -0
  67. data/tests/fixtures/unit/synchronize/books.yml +16 -0
  68. data/tests/fixtures/unit/to_csv_headers/addresses.yml +8 -0
  69. data/tests/fixtures/unit/to_csv_headers/developers.yml +6 -0
  70. data/tests/fixtures/unit/to_csv_with_common_options/addresses.yml +40 -0
  71. data/tests/fixtures/unit/to_csv_with_common_options/developers.yml +13 -0
  72. data/tests/fixtures/unit/to_csv_with_common_options/languages.yml +29 -0
  73. data/tests/fixtures/unit/to_csv_with_common_options/teams.yml +3 -0
  74. data/tests/fixtures/unit/to_csv_with_default_options/developers.yml +7 -0
  75. data/tests/models/address.rb +4 -0
  76. data/tests/models/animal.rb +2 -0
  77. data/tests/models/book.rb +3 -0
  78. data/tests/models/cart_item.rb +4 -0
  79. data/tests/models/developer.rb +8 -0
  80. data/tests/models/group.rb +3 -0
  81. data/tests/models/language.rb +5 -0
  82. data/tests/models/mysql/book.rb +3 -0
  83. data/tests/models/mysql/test_innodb.rb +3 -0
  84. data/tests/models/mysql/test_memory.rb +3 -0
  85. data/tests/models/mysql/test_myisam.rb +3 -0
  86. data/tests/models/project.rb +2 -0
  87. data/tests/models/shopping_cart.rb +4 -0
  88. data/tests/models/team.rb +4 -0
  89. data/tests/models/topic.rb +13 -0
  90. data/tests/mysql/test_create_and_update.rb +290 -0
  91. data/tests/mysql/test_delete.rb +142 -0
  92. data/tests/mysql/test_finder_options.rb +121 -0
  93. data/tests/mysql/test_finders.rb +29 -0
  94. data/tests/mysql/test_import.rb +354 -0
  95. data/tests/mysql/test_insert_select.rb +173 -0
  96. data/tests/mysql/test_mysql_adapter.rb +45 -0
  97. data/tests/mysql/test_union.rb +81 -0
  98. data/tests/oracle/test_adapter.rb +14 -0
  99. data/tests/postgresql/test_adapter.rb +14 -0
  100. data/tests/prepare.rb +9 -0
  101. data/tests/run.rb +13 -0
  102. data/tests/run_from_gem.rb +17 -0
  103. data/tests/test_activerecord_compatability.rb +71 -0
  104. data/tests/test_finders.rb +543 -0
  105. data/tests/test_helper.rb +70 -0
  106. data/tests/test_import.rb +339 -0
  107. data/tests/test_synchronize.rb +31 -0
  108. data/tests/test_temporary_tables.rb +93 -0
  109. data/tests/test_to_csv_headers.rb +204 -0
  110. data/tests/test_to_csv_with_common_options.rb +670 -0
  111. data/tests/test_to_csv_with_default_options.rb +34 -0
  112. metadata +211 -0
@@ -0,0 +1,173 @@
1
+ require File.expand_path( File.join( File.dirname( __FILE__ ), '..', 'test_helper' ))
2
+
3
+ class InsertSelectTest < TestCaseSuperClass
4
+ self.fixtures 'books'
5
+ if ActiveRecord::Base.connection.class.name =~ /sqlite/i
6
+ self.use_transactional_fixtures = false
7
+ end
8
+
9
+ #define the duplicate key update for mysql for testing
10
+ #add oracle, postgre, sqlite, etc when implemented
11
+ if ENV["ARE_DB"] == 'mysql'
12
+ DUPLICATE_UPDATE_STR = 'cart_items.updated_at=VALUES(`updated_at`), copies=VALUES(copies), book_id=VALUES(`book_id`)'
13
+ else
14
+ DUPLICATE_UPDATE_STR = [:updated_at, :copies, :book_id]
15
+ end
16
+
17
+ def setup
18
+ @connection = ActiveRecord::Base.connection
19
+ @conditions = ['author_name like :author_name', {:author_name => 'Terry Brooks'}]
20
+ @into_columns = [:book_id, :shopping_cart_id, :copies, :updated_at, :created_at]
21
+ @cart = ShoppingCart.create!(:name => 'My Shopping Cart')
22
+ @time = Time.now - 2.seconds
23
+
24
+ Topic.destroy_all
25
+ ShoppingCart.destroy_all
26
+ end
27
+
28
+ def teardown
29
+ Topic.destroy_all
30
+ ShoppingCart.destroy_all
31
+ end
32
+
33
+ #test simple insert select
34
+ def test_insert_select_should_import_data_from_one_model_into_another
35
+ assert_equal 0, Topic.count
36
+
37
+ timestamp = Time.now
38
+ Topic.insert_select(
39
+ :from => :book,
40
+ :select => ['title, author_name, ?', timestamp],
41
+ :into => [:title, :author_name, :updated_at])
42
+
43
+ books = Book.find :all, :order => 'title'
44
+ topics = Topic.find :all, :order => 'title'
45
+
46
+ assert_equal books.length, topics.length
47
+
48
+ topics.each_with_index {|topic, idx|
49
+ assert_equal topic.author_name, books[idx].author_name
50
+ assert_equal topic.title, books[idx].title
51
+ assert_equal topic.updated_at.to_s, timestamp.to_s
52
+ }
53
+ end
54
+
55
+ def test_insert_select_should_import_data_from_one_model_into_another_ignoring_existing_data
56
+ time = Time.now - 4.seconds
57
+ #insert book data into cart
58
+ CartItem.insert_select(
59
+ :from => :book,
60
+ :select => ['books.id, ?, ?, ?, now()', @cart.to_param, 1, time],
61
+ :into => [:book_id, :shopping_cart_id, :copies, :updated_at, :created_at])
62
+
63
+ total = CartItem.count(:id, :conditions => ['shopping_cart_id = ? and updated_at = ?', @cart.to_param, time])
64
+ assert_equal 9, total, "Expecting 6 cart items. Instead got #{total}"
65
+
66
+ #insert the same data from book into the cart
67
+ CartItem.insert_select(:from => Book,
68
+ :select => ['books.id, ?, ?, ?, now()', @cart.to_param, 1, Time.now],
69
+ :into => 'cart_items.book_id, shopping_cart_id, copies, updated_at, created_at',
70
+ :ignore => true )
71
+
72
+ #ensure that the data has not changed
73
+ total = CartItem.count(:id, :conditions => ['shopping_cart_id = ? and updated_at = ?', @cart.to_param, time])
74
+ assert_equal 9, total, "Expecting 6 cart items. Instead got #{total}"
75
+ end
76
+
77
+ def test_insert_select_should_import_data_from_one_model_into_another_updating_existing_data(options_one={}, options_two={})
78
+ fun_topic = Topic.create!(:title => 'Fun Books', :author_name => 'Big Bird')
79
+ ok_topic = Topic.create!(:title => 'OK Books', :author_name => 'sloth')
80
+ boring_topic = Topic.create!(:title => 'Boring Books', :author_name => 'Giraffe')
81
+
82
+ Book.update_all(['topic_id = ?', boring_topic])
83
+ Book.update_all(['topic_id = ?', fun_topic], 'books.id < 3')
84
+ Book.update_all(['topic_id = ?', ok_topic], 'books.id = 3')
85
+
86
+ CartItem.insert_select(
87
+ {:from => :book,
88
+ :select => ['books.id, ?, ?, ?, ?', @cart.to_param, 1, @time, @time],
89
+ :into => @into_columns,
90
+ :conditions => ['topics.title = :title', {:title => 'Fun Books'}],
91
+ :include => :topic }.merge(options_one))
92
+
93
+ validate_cart_items({:total => 2, :copies => 1 },
94
+ :conditions => ['topics.title in (?)', ['Fun Books']],
95
+ :include => { :book => :topic })
96
+
97
+ #insert select with on duplicate key update written as a string
98
+ new_time = Time.now
99
+ CartItem.insert_select(
100
+ {:from => :book,
101
+ :select => ['books.id, ?, ?, ?, ?', @cart.to_param, 2, new_time, new_time],
102
+ :into => @into_columns,
103
+ :conditions => ['topics.title in (?)', ['Fun Books', 'OK Books']],
104
+ :include => :topic ,
105
+ :on_duplicate_key_update => DUPLICATE_UPDATE_STR}.merge(options_two))
106
+
107
+ # 3 total items
108
+ assert_equal 3, CartItem.count
109
+
110
+ #2 fun books should have updated the updated_at and copies field
111
+ validate_cart_items({:total => 2, :updated_at => new_time, :copies => 2},
112
+ :conditions => ['topics.title in (?)', ['Fun Books']],
113
+ :include => { :book => :topic })
114
+
115
+ #1 ok book
116
+ validate_cart_items({:total => 1, :updated_at => new_time, :created_at => new_time, :copies => 2},
117
+ :conditions => ['topics.title in (?)', ['OK Books']],
118
+ :include => { :book => :topic })
119
+ end
120
+
121
+ def test_insert_select_should_import_data_from_one_model_into_another_updating_existing_data_using_joins_and_limit
122
+ #use a join instead of include
123
+ options = {:include => nil, :joins => 'inner join topics on topics.id = books.topic_id', :limit => 4}
124
+ test_insert_select_should_import_data_from_one_model_into_another_updating_existing_data options, options
125
+ end
126
+
127
+ #test insert select with ignore and duplicate options
128
+ def test_insert_select_should_import_data_from_one_model_into_another_updating_multiple_columns
129
+
130
+ @cart_copies = Book.count(:all, :conditions => @conditions)
131
+ assert @cart_copies > 0
132
+
133
+ @time = Time.now
134
+ CartItem.insert_select(
135
+ :from => :book,
136
+ :select => ['books.id, ?, ?, ?, ?', @cart.to_param, 1, @time, @time],
137
+ :conditions => @conditions,
138
+ :into => @into_columns)
139
+
140
+ validate_cart_items :total => @cart_copies, :copies => 1
141
+
142
+ #use on duplicate update
143
+ #this means that the book count should change to 2 and the updated time should be changed to new_time
144
+ new_time = Time.now
145
+ CartItem.insert_select(
146
+ :from => :book,
147
+ :select => ['books.id, :cart, :copies, :updated_at, :created_at', {:copies => 2, :cart => @cart, :created_at => new_time, :updated_at => new_time}],
148
+ :conditions => @conditions,
149
+ :into => @into_columns,
150
+ :on_duplicate_key_update => [:updated_at, :copies])
151
+
152
+ validate_cart_items :total => @cart_copies, :updated_at => new_time, :copies => 2
153
+ end
154
+
155
+ protected
156
+
157
+ def validate_cart_items(expected_values = {}, find_options = {})
158
+
159
+ vals = {:shopping_cart_id => @cart.to_param, :updated_at => @time, :created_at => @time, :copies => 1}.merge expected_values
160
+ total_count = vals.delete(:total)
161
+
162
+ items = CartItem.find(:all, find_options)
163
+ assert_equal(total_count, items.length, "Expecting #{total_count}, recieved #{items.length}") unless total_count.nil?
164
+
165
+ items.each do |item|
166
+ vals.each do |method, val|
167
+ actual = item.send method
168
+ assert_equal val.to_s, actual.to_s, "Expecting #{method} = #{val}. Instead got #{actual}"
169
+ end
170
+ end
171
+ end
172
+ end
173
+
@@ -0,0 +1,45 @@
1
+ class MysqlAdapterTest< TestCaseSuperClass
2
+ include ActiveRecord::ConnectionAdapters
3
+
4
+ def setup
5
+ @connection = ActiveRecord::Base.connection
6
+ end
7
+
8
+ def test_get_insert_value_sets
9
+ values = [
10
+ "('1','2','3')",
11
+ "('4','5','6')",
12
+ "('7','8','9')" ]
13
+
14
+ values_size_in_bytes = MysqlAdapter.sum_sizes( *values )
15
+ base_sql_size_in_bytes = 15
16
+ max_bytes = 30
17
+
18
+ value_sets = MysqlAdapter.get_insert_value_sets( values, base_sql_size_in_bytes, max_bytes )
19
+ assert_equal 3, value_sets.size, 'Three value sets were expected!'
20
+
21
+ # Each element in the value_sets array must be an array
22
+ value_sets.each_with_index { |e,i|
23
+ assert_kind_of Array, e, "Element #{i} was expected to be an Array!" }
24
+
25
+ # Each element in the values array should have a 1:1 correlation to the elements
26
+ # in the returned value_sets arrays
27
+ assert_equal values[0], value_sets[0].first
28
+ assert_equal values[1], value_sets[1].first
29
+ assert_equal values[2], value_sets[2].first
30
+ end
31
+
32
+ def test_insert_many
33
+ base_sql = "INSERT INTO #{Topic.table_name} (`title`,`author_name`) VALUES "
34
+ values = [
35
+ "('Morgawr','Brooks, Terry')",
36
+ "('Antrax', 'Brooks, Terry')",
37
+ "('Jarka Ruus', 'Brooks, Terry')" ]
38
+
39
+ expected_count = Topic.count + values.size
40
+ @connection.insert_many( base_sql, values )
41
+ assert_equal expected_count, Topic.count, "Incorrect number of records in the database!"
42
+ Topic.destroy_all
43
+ end
44
+
45
+ end
@@ -0,0 +1,81 @@
1
+ require File.expand_path( File.join( File.dirname( __FILE__ ), '../test_helper') )
2
+
3
+ class UnionTest < TestCaseSuperClass
4
+ fixtures 'books'
5
+
6
+ def test_union_should_query_five_records
7
+ books = Book.find_union({:conditions => ['author_name = ?', 'Terry Brooks']},
8
+ {:conditions => 'id > 3 and id < 6'})
9
+
10
+
11
+ assert_equal(5, books.length)
12
+ books.each {|book|
13
+ assert(book.author_name == 'Terry Brooks' || (book.id > 3 && book.id < 6))
14
+ }
15
+ end
16
+
17
+ def test_union_with_unused_include_should_query_five_records
18
+ books = Book.find_union({:conditions => ['author_name = ?', 'Terry Brooks']},
19
+ {:conditions => 'books.id > 3 and books.id < 6', :include => :topic})
20
+
21
+
22
+ assert_equal(5, books.length)
23
+ books.each {|book|
24
+ assert(book.author_name == 'Terry Brooks' || (book.id > 3 && book.id < 6))
25
+ }
26
+ end
27
+
28
+
29
+ def test_union_with_include_should_load_5_books
30
+ @topic = Topic.create!(:title => 'funtimes', :author_name => 'giraffe')
31
+ Book.update_all(['topic_id = ? ', @topic.id], ['books.id > 3 and books.id < 6'])
32
+
33
+
34
+ books = Book.find_union({:conditions => ['author_name = ?', 'Terry Brooks']},
35
+ {:conditions => ['topics.title = :name',{:name => @topic.title}],
36
+ :include => ['topic']})
37
+
38
+
39
+ assert_equal(5, books.length)
40
+
41
+ books.each {|book|
42
+ assert(book.author_name == 'Terry Brooks' || (book.id > 3 && book.id < 6))
43
+ }
44
+ end
45
+
46
+ def test_union_with_limit_should_query_four_records
47
+ books = Book.find_union({:conditions => ['author_name = ?', 'Terry Brooks']},
48
+ {:conditions => 'id > 3 and id < 6', :limit => 1})
49
+
50
+ assert_equal(4, books.length)
51
+ books.each {|book|
52
+ assert(book.author_name == 'Terry Brooks' || (book.id > 3 && book.id < 6))
53
+ }
54
+ end
55
+
56
+ def test_count_union_should_query_five_records_for_id
57
+ count = Book.count_union(:id, {:conditions => ['author_name = ?', 'Terry Brooks']},
58
+ {:conditions => 'id > 3 and id < 6'})
59
+
60
+ assert_equal(5, count)
61
+ end
62
+
63
+ def test_union_should_query_four_records_using_limit
64
+ count = Book.count_union(:all,
65
+ {:conditions => ['author_name = ?', 'Terry Brooks']},
66
+ {:conditions => 'id > 3 and id < 6', :limit => 1})
67
+
68
+ assert_equal(4, count)
69
+ end
70
+
71
+ def test_count_union_should_count_two_authors
72
+ count = Book.count_union(:author_name, {:conditions => ['author_name = ?', 'Terry Brooks']},
73
+ {:conditions => 'id > 3 and id < 6'})
74
+
75
+ assert_equal(2, count)
76
+ end
77
+
78
+
79
+ end
80
+
81
+
@@ -0,0 +1,14 @@
1
+ require File.expand_path( File.join( File.dirname( __FILE__ ), '..', 'test_helper' ) )
2
+
3
+ class OracleAdapterTest< TestCaseSuperClass
4
+
5
+ def setup
6
+ @target = ActiveRecord::ConnectionAdapters::OracleAdapter.allocate
7
+ end
8
+
9
+ def test_should_generate_the_correct_next_value_for_sequence
10
+ result = @target.next_value_for_sequence("blah")
11
+ assert_equal 'blah.nextval', result, "wrong next value sequence identifier"
12
+ end
13
+
14
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path( File.join( File.dirname( __FILE__ ), '..', 'test_helper' ) )
2
+
3
+ class PostgreSQLAdapterTest< TestCaseSuperClass
4
+
5
+ def setup
6
+ @target = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.allocate
7
+ end
8
+
9
+ def test_should_generate_the_correct_next_value_for_sequence
10
+ result = @target.next_value_for_sequence("blah")
11
+ assert_equal %{nextval('blah')}, result, "wrong next value sequence identifier"
12
+ end
13
+
14
+ end
data/tests/prepare.rb ADDED
@@ -0,0 +1,9 @@
1
+ adapter = ARGV.shift
2
+ ENV["ARE_DB"] = adapter
3
+
4
+ dir = File.dirname(__FILE__)
5
+ require File.expand_path(File.join(dir, 'test_helper'))
6
+
7
+ require File.join(dir, "..", "db", "migrate", "generic_schema")
8
+ db_schema = File.join(dir, "..", "db", "migrate", "#{adapter}_schema.rb")
9
+ require db_schema if File.exists?(db_schema)
data/tests/run.rb ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/ruby
2
+
3
+ ADAPTER = ARGV.shift
4
+ ENV["ARE_DB"] = ADAPTER
5
+
6
+ dir = File.dirname(__FILE__)
7
+ require File.expand_path(File.join(dir, "test_helper"))
8
+
9
+ Dir[File.join(dir, ADAPTER, "test_*.rb") ].each{ |f| require(f) }
10
+
11
+ Dir[File.join(dir, "test_*.rb")].each do |f|
12
+ require File.expand_path(f) unless f == "test_helper.rb"
13
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/ruby
2
+
3
+ dir = File.expand_path(File.dirname(__FILE__))
4
+
5
+ ADAPTER = ARGV.shift
6
+ ENV["ARE_DB"] = ADAPTER
7
+
8
+ require "rubygems"
9
+
10
+ gem "ar-extensions"
11
+ require "ar-extensions"
12
+
13
+ require File.join(dir, "test_helper")
14
+
15
+ Dir[File.join(dir, ADAPTER, "test_*.rb")].each { |f| require(f) }
16
+
17
+ Dir[File.join(dir, "test_*.rb")].each { |f| require(f) unless f == 'test_helper.rb' }
@@ -0,0 +1,71 @@
1
+ require File.expand_path( File.join( File.dirname( __FILE__ ), 'test_helper' ) )
2
+
3
+ class FindersTest< TestCaseSuperClass
4
+ include ActiveRecord::ConnectionAdapters
5
+
6
+ def setup
7
+ @connection = ActiveRecord::Base.connection
8
+ end
9
+
10
+ def test_activerecord_model_can_be_used_with_reserved_words
11
+ group1 = Group.create!(:order => "x")
12
+ group2 = Group.create!(:order => "y")
13
+ x = nil
14
+ assert_nothing_raised { x = Group.new }
15
+ x.order = 'x'
16
+ assert_nothing_raised { x.save }
17
+ x.order = 'y'
18
+ assert_nothing_raised { x.save }
19
+ assert_nothing_raised { y = Group.find_by_order('y') }
20
+ assert_nothing_raised { y = Group.find(group2.id) }
21
+ x = Group.find(group1.id)
22
+ end
23
+
24
+ def test_find_on_hash_conditions_with_explicit_table_name
25
+ group1 = Group.create!(:order => "x")
26
+ assert Group.find(group1.id, :conditions => { "group.order" => "x" })
27
+ assert_raises(ActiveRecord::RecordNotFound) {
28
+ Group.find(group1.id, :conditions => { 'group.order' => "y" })
29
+ }
30
+ end
31
+
32
+ def test_exists_with_aggregate_having_three_mappings
33
+ topic = Topic.create! :title => "SomeBook", :author_name => "Joe Smith"
34
+ assert Topic.exists?(:description => topic.description)
35
+
36
+ topic = Topic.new :title => "MayDay", :author_name => "Joe Smith the 2nd"
37
+ assert !Topic.exists?(:description => topic.description)
38
+ end
39
+
40
+ def test_find_with_aggregate
41
+ topic = Topic.create! :title => "SomeBook", :author_name => "Joe Smith"
42
+ assert_equal topic, Topic.find(:first, :conditions => { :description => topic.description })
43
+
44
+ topic = Topic.new :title => "MayDay", :author_name => "Joe Smith the 2nd"
45
+ assert !Topic.find(:first, :conditions => { :description => topic.description })
46
+ end
47
+
48
+ def test_find_with_blank_conditions
49
+ Topic.destroy_all
50
+ Book.destroy_all
51
+ topic = Topic.create! :author_name => "Zach Dennis", :title => "Books by Brooks"
52
+ topic.books << Book.create!(:title => "Sword of Shannara", :author_name => "Terry Brooks", :publisher => "DelRey")
53
+ topic.books << Book.create!(:title => "Gemstones of Shannara", :author_name => "Terry Brooks", :publisher => "DelRey")
54
+ [[], {}, nil, ""].each do |blank|
55
+ assert_equal 2, Topic.find(:first).books.find(:all, :conditions => blank).size
56
+ end
57
+ end
58
+
59
+ if ActiveRecord::VERSION::STRING >= '2.2.0'
60
+ def test_find_with_hash_conditions_and_joins
61
+ Topic.destroy_all
62
+ Book.destroy_all
63
+ topic = Topic.create! :author_name => "Zach Dennis", :title => "Books by Brooks"
64
+ sword_of_shannara_book = Book.create!(:title => "Sword of Shannara", :author_name => "Terry Brooks", :publisher => "DelRey")
65
+ topic.books << sword_of_shannara_book
66
+ found_topic = Topic.find(:all, :conditions => {:books => {:title => "Sword of Shannara"}}, :joins => :books)
67
+ assert_equal [topic], found_topic
68
+ end
69
+ end
70
+
71
+ end