ibm_db 1.1.1-mswin32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. data/CHANGES +155 -0
  2. data/LICENSE +18 -0
  3. data/MANIFEST +14 -0
  4. data/README +274 -0
  5. data/ext/Makefile.nt32 +181 -0
  6. data/ext/extconf.rb +58 -0
  7. data/ext/ibm_db.c +6553 -0
  8. data/ext/ruby_ibm_db.h +214 -0
  9. data/init.rb +42 -0
  10. data/lib/IBM_DB.rb +2 -0
  11. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +2218 -0
  12. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -0
  13. data/lib/mswin32/ibm_db.so +0 -0
  14. data/test/cases/adapter_test.rb +180 -0
  15. data/test/cases/associations/cascaded_eager_loading_test.rb +133 -0
  16. data/test/cases/associations/eager_test.rb +842 -0
  17. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +874 -0
  18. data/test/cases/associations/has_many_through_associations_test.rb +281 -0
  19. data/test/cases/associations/join_model_test.rb +801 -0
  20. data/test/cases/attribute_methods_test.rb +312 -0
  21. data/test/cases/base_test.rb +2114 -0
  22. data/test/cases/calculations_test.rb +346 -0
  23. data/test/cases/finder_test.rb +1092 -0
  24. data/test/cases/fixtures_test.rb +660 -0
  25. data/test/cases/migration_test.rb +1618 -0
  26. data/test/cases/schema_dumper_test.rb +197 -0
  27. data/test/cases/validations_test.rb +1604 -0
  28. data/test/connections/native_ibm_db/connection.rb +40 -0
  29. data/test/ibm_db_test.rb +25 -0
  30. data/test/models/warehouse_thing.rb +5 -0
  31. data/test/schema/i5/ibm_db_specific_schema.rb +134 -0
  32. data/test/schema/ids/ibm_db_specific_schema.rb +137 -0
  33. data/test/schema/luw/ibm_db_specific_schema.rb +134 -0
  34. data/test/schema/schema.rb +499 -0
  35. data/test/schema/zOS/ibm_db_specific_schema.rb +205 -0
  36. metadata +115 -0
@@ -0,0 +1,874 @@
1
+ require "cases/helper"
2
+ require 'models/developer'
3
+ require 'models/project'
4
+ require 'models/company'
5
+ require 'models/topic'
6
+ require 'models/reply'
7
+ require 'models/computer'
8
+ require 'models/customer'
9
+ require 'models/order'
10
+ require 'models/categorization'
11
+ require 'models/category'
12
+ require 'models/post'
13
+ require 'models/author'
14
+ require 'models/comment'
15
+ require 'models/tag'
16
+ require 'models/tagging'
17
+ require 'models/person'
18
+ require 'models/reader'
19
+ require 'models/parrot'
20
+ require 'models/pirate'
21
+ require 'models/treasure'
22
+ require 'models/price_estimate'
23
+ require 'models/club'
24
+ require 'models/member'
25
+ require 'models/membership'
26
+ require 'models/sponsor'
27
+
28
+ class ProjectWithAfterCreateHook < ActiveRecord::Base
29
+ set_table_name 'projects'
30
+ has_and_belongs_to_many :developers,
31
+ :class_name => "DeveloperForProjectWithAfterCreateHook",
32
+ :join_table => "developers_projects",
33
+ :foreign_key => "project_id",
34
+ :association_foreign_key => "developer_id"
35
+
36
+ after_create :add_david
37
+
38
+ def add_david
39
+ david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
40
+ david.projects << self
41
+ end
42
+ end
43
+
44
+ class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
45
+ set_table_name 'developers'
46
+ has_and_belongs_to_many :projects,
47
+ :class_name => "ProjectWithAfterCreateHook",
48
+ :join_table => "developers_projects",
49
+ :association_foreign_key => "project_id",
50
+ :foreign_key => "developer_id"
51
+ end
52
+
53
+ class ProjectWithSymbolsForKeys < ActiveRecord::Base
54
+ set_table_name 'projects'
55
+ has_and_belongs_to_many :developers,
56
+ :class_name => "DeveloperWithSymbolsForKeys",
57
+ :join_table => :developers_projects,
58
+ :foreign_key => :project_id,
59
+ :association_foreign_key => "developer_id"
60
+ end
61
+
62
+ class DeveloperWithSymbolsForKeys < ActiveRecord::Base
63
+ set_table_name 'developers'
64
+ has_and_belongs_to_many :projects,
65
+ :class_name => "ProjectWithSymbolsForKeys",
66
+ :join_table => :developers_projects,
67
+ :association_foreign_key => :project_id,
68
+ :foreign_key => "developer_id"
69
+ end
70
+
71
+ class DeveloperWithCounterSQL < ActiveRecord::Base
72
+ set_table_name 'developers'
73
+ has_and_belongs_to_many :projects,
74
+ :class_name => "DeveloperWithCounterSQL",
75
+ :join_table => "developers_projects",
76
+ :association_foreign_key => "project_id",
77
+ :foreign_key => "developer_id",
78
+ :counter_sql => 'SELECT COUNT(*) AS count_all FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE developers_projects.developer_id =#{id}'
79
+ end
80
+
81
+ if current_adapter?(:IBM_DBAdapter)
82
+ class Novel < ActiveRecord::Base
83
+ has_and_belongs_to_many :writers
84
+ end
85
+
86
+ class Writer < ActiveRecord::Base
87
+ has_and_belongs_to_many :novels
88
+ end
89
+
90
+ class NovelsWriter < ActiveRecord::Base
91
+ belongs_to :writers
92
+ belongs_to :novels
93
+ end
94
+ end
95
+
96
+ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
97
+ fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
98
+ :parrots, :pirates, :treasures, :price_estimates, :tags, :taggings
99
+
100
+ def test_has_and_belongs_to_many
101
+ david = Developer.find(1)
102
+
103
+ assert !david.projects.empty?
104
+ assert_equal 2, david.projects.size
105
+
106
+ active_record = Project.find(1)
107
+ assert !active_record.developers.empty?
108
+ assert_equal 3, active_record.developers.size
109
+ assert active_record.developers.include?(david)
110
+ end
111
+
112
+ def test_triple_equality
113
+ assert !(Array === Developer.find(1).projects)
114
+ assert Developer.find(1).projects === Array
115
+ end
116
+
117
+ def test_adding_single
118
+ jamis = Developer.find(2)
119
+ jamis.projects.reload # causing the collection to load
120
+ action_controller = Project.find(2)
121
+ assert_equal 1, jamis.projects.size
122
+ assert_equal 1, action_controller.developers.size
123
+
124
+ jamis.projects << action_controller
125
+
126
+ assert_equal 2, jamis.projects.size
127
+ assert_equal 2, jamis.projects(true).size
128
+ assert_equal 2, action_controller.developers(true).size
129
+ end
130
+
131
+ def test_adding_type_mismatch
132
+ jamis = Developer.find(2)
133
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << nil }
134
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << 1 }
135
+ end
136
+
137
+ def test_adding_from_the_project
138
+ jamis = Developer.find(2)
139
+ action_controller = Project.find(2)
140
+ action_controller.developers.reload
141
+ assert_equal 1, jamis.projects.size
142
+ assert_equal 1, action_controller.developers.size
143
+
144
+ action_controller.developers << jamis
145
+
146
+ assert_equal 2, jamis.projects(true).size
147
+ assert_equal 2, action_controller.developers.size
148
+ assert_equal 2, action_controller.developers(true).size
149
+ end
150
+
151
+ def test_adding_from_the_project_fixed_timestamp
152
+ jamis = Developer.find(2)
153
+ action_controller = Project.find(2)
154
+ action_controller.developers.reload
155
+ assert_equal 1, jamis.projects.size
156
+ assert_equal 1, action_controller.developers.size
157
+ updated_at = jamis.updated_at
158
+
159
+ action_controller.developers << jamis
160
+
161
+ assert_equal updated_at, jamis.updated_at
162
+ assert_equal 2, jamis.projects(true).size
163
+ assert_equal 2, action_controller.developers.size
164
+ assert_equal 2, action_controller.developers(true).size
165
+ end
166
+
167
+ def test_adding_multiple
168
+ aredridel = Developer.new("name" => "Aredridel")
169
+ aredridel.save
170
+ aredridel.projects.reload
171
+ aredridel.projects.push(Project.find(1), Project.find(2))
172
+ assert_equal 2, aredridel.projects.size
173
+ assert_equal 2, aredridel.projects(true).size
174
+ end
175
+
176
+ def test_adding_a_collection
177
+ aredridel = Developer.new("name" => "Aredridel")
178
+ aredridel.save
179
+ aredridel.projects.reload
180
+ aredridel.projects.concat([Project.find(1), Project.find(2)])
181
+ assert_equal 2, aredridel.projects.size
182
+ assert_equal 2, aredridel.projects(true).size
183
+ end
184
+
185
+ def test_adding_uses_default_values_on_join_table
186
+ ac = projects(:action_controller)
187
+ assert !developers(:jamis).projects.include?(ac)
188
+ developers(:jamis).projects << ac
189
+
190
+ assert developers(:jamis, :reload).projects.include?(ac)
191
+ project = developers(:jamis).projects.detect { |p| p == ac }
192
+ assert_equal 1, project.access_level.to_i
193
+ end
194
+
195
+ def test_habtm_attribute_access_and_respond_to
196
+ project = developers(:jamis).projects[0]
197
+ assert project.has_attribute?("name")
198
+ assert project.has_attribute?("joined_on")
199
+ assert project.has_attribute?("access_level")
200
+ assert project.respond_to?("name")
201
+ assert project.respond_to?("name=")
202
+ assert project.respond_to?("name?")
203
+ assert project.respond_to?("joined_on")
204
+ # given that the 'join attribute' won't be persisted, I don't
205
+ # think we should define the mutators
206
+ #assert project.respond_to?("joined_on=")
207
+ assert project.respond_to?("joined_on?")
208
+ assert project.respond_to?("access_level")
209
+ #assert project.respond_to?("access_level=")
210
+ assert project.respond_to?("access_level?")
211
+ end
212
+
213
+ def test_habtm_adding_before_save
214
+ no_of_devels = Developer.count
215
+ no_of_projects = Project.count
216
+ aredridel = Developer.new("name" => "Aredridel")
217
+ aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")])
218
+ assert aredridel.new_record?
219
+ assert p.new_record?
220
+ assert aredridel.save
221
+ assert !aredridel.new_record?
222
+ assert_equal no_of_devels+1, Developer.count
223
+ assert_equal no_of_projects+1, Project.count
224
+ assert_equal 2, aredridel.projects.size
225
+ assert_equal 2, aredridel.projects(true).size
226
+ end
227
+
228
+ def test_habtm_saving_multiple_relationships
229
+ new_project = Project.new("name" => "Grimetime")
230
+ amount_of_developers = 4
231
+ developers = (0...amount_of_developers).collect {|i| Developer.create(:name => "JME #{i}") }.reverse
232
+
233
+ new_project.developer_ids = [developers[0].id, developers[1].id]
234
+ new_project.developers_with_callback_ids = [developers[2].id, developers[3].id]
235
+ assert new_project.save
236
+
237
+ new_project.reload
238
+ assert_equal amount_of_developers, new_project.developers.size
239
+ assert_equal developers, new_project.developers
240
+ end
241
+
242
+ def test_habtm_unique_order_preserved
243
+ assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).non_unique_developers
244
+ assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).developers
245
+ end
246
+
247
+ def test_build
248
+ devel = Developer.find(1)
249
+ proj = assert_no_queries { devel.projects.build("name" => "Projekt") }
250
+ assert !devel.projects.loaded?
251
+
252
+ assert_equal devel.projects.last, proj
253
+ assert devel.projects.loaded?
254
+
255
+ assert proj.new_record?
256
+ devel.save
257
+ assert !proj.new_record?
258
+ assert_equal devel.projects.last, proj
259
+ assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
260
+ end
261
+
262
+ def test_build_by_new_record
263
+ devel = Developer.new(:name => "Marcel", :salary => 75000)
264
+ proj1 = devel.projects.build(:name => "Make bed")
265
+ proj2 = devel.projects.build(:name => "Lie in it")
266
+ assert_equal devel.projects.last, proj2
267
+ assert proj2.new_record?
268
+ devel.save
269
+ assert !devel.new_record?
270
+ assert !proj2.new_record?
271
+ assert_equal devel.projects.last, proj2
272
+ assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
273
+ end
274
+
275
+ def test_create
276
+ devel = Developer.find(1)
277
+ proj = devel.projects.create("name" => "Projekt")
278
+ assert !devel.projects.loaded?
279
+
280
+ assert_equal devel.projects.last, proj
281
+ assert !devel.projects.loaded?
282
+
283
+ assert !proj.new_record?
284
+ assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
285
+ end
286
+
287
+ if current_adapter?(:IBM_DBAdapter)
288
+ def test_lob_handling
289
+ assert_nothing_raised do
290
+ Novel.connection.create_table 'novels' do |t|
291
+ t.text :story
292
+ t.string :title
293
+ end
294
+ Writer.connection.create_table 'writers' do |t|
295
+ t.string :name
296
+ end
297
+ NovelsWriter.connection.create_table 'novels_writers' do |t|
298
+ t.belongs_to :novels
299
+ t.belongs_to :writers
300
+ end
301
+ end
302
+
303
+ w = Writer.new :name => 'Praveen'
304
+ w.save!
305
+
306
+ novel_story = "This is a short and sweet story"
307
+
308
+ novel = Novel.new :story => novel_story,:title => "Cool isn't it"
309
+ novel.writers << w
310
+ novel.save!
311
+
312
+ assert_equal novel_story,Novel.find(novel.id).story
313
+ ensure
314
+ Novel.connection.drop_table 'novels' rescue nil
315
+ Writer.connection.drop_table 'writers' rescue nil
316
+ NovelsWriter.connection.drop_table 'novels_writers' rescue nil
317
+ end
318
+ end
319
+
320
+ def test_create_by_new_record
321
+ devel = Developer.new(:name => "Marcel", :salary => 75000)
322
+ proj1 = devel.projects.build(:name => "Make bed")
323
+ proj2 = devel.projects.build(:name => "Lie in it")
324
+ assert_equal devel.projects.last, proj2
325
+ assert proj2.new_record?
326
+ devel.save
327
+ assert !devel.new_record?
328
+ assert !proj2.new_record?
329
+ assert_equal devel.projects.last, proj2
330
+ assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
331
+ end
332
+
333
+ def test_creation_respects_hash_condition
334
+ post = categories(:general).post_with_conditions.build(:body => '')
335
+
336
+ assert post.save
337
+ assert_equal 'Yet Another Testing Title', post.title
338
+
339
+ another_post = categories(:general).post_with_conditions.create(:body => '')
340
+
341
+ assert !another_post.new_record?
342
+ assert_equal 'Yet Another Testing Title', another_post.title
343
+ end
344
+
345
+ def test_uniq_after_the_fact
346
+ dev = developers(:jamis)
347
+ dev.projects << projects(:active_record)
348
+ dev.projects << projects(:active_record)
349
+
350
+ assert_equal 3, dev.projects.size
351
+ assert_equal 1, dev.projects.uniq.size
352
+ end
353
+
354
+ def test_uniq_before_the_fact
355
+ projects(:active_record).developers << developers(:jamis)
356
+ projects(:active_record).developers << developers(:david)
357
+ assert_equal 3, projects(:active_record, :reload).developers.size
358
+ end
359
+
360
+ def test_uniq_option_prevents_duplicate_push
361
+ project = projects(:active_record)
362
+ project.developers << developers(:jamis)
363
+ project.developers << developers(:david)
364
+ assert_equal 3, project.developers.size
365
+
366
+ project.developers << developers(:david)
367
+ project.developers << developers(:jamis)
368
+ assert_equal 3, project.developers.size
369
+ end
370
+
371
+ def test_deleting
372
+ david = Developer.find(1)
373
+ active_record = Project.find(1)
374
+ david.projects.reload
375
+ assert_equal 2, david.projects.size
376
+ assert_equal 3, active_record.developers.size
377
+
378
+ david.projects.delete(active_record)
379
+
380
+ assert_equal 1, david.projects.size
381
+ assert_equal 1, david.projects(true).size
382
+ assert_equal 2, active_record.developers(true).size
383
+ end
384
+
385
+ def test_deleting_array
386
+ david = Developer.find(1)
387
+ david.projects.reload
388
+ david.projects.delete(Project.find(:all))
389
+ assert_equal 0, david.projects.size
390
+ assert_equal 0, david.projects(true).size
391
+ end
392
+
393
+ def test_deleting_with_sql
394
+ david = Developer.find(1)
395
+ active_record = Project.find(1)
396
+ active_record.developers.reload
397
+ assert_equal 3, active_record.developers_by_sql.size
398
+
399
+ active_record.developers_by_sql.delete(david)
400
+ assert_equal 2, active_record.developers_by_sql(true).size
401
+ end
402
+
403
+ def test_deleting_array_with_sql
404
+ active_record = Project.find(1)
405
+ active_record.developers.reload
406
+ assert_equal 3, active_record.developers_by_sql.size
407
+
408
+ active_record.developers_by_sql.delete(Developer.find(:all))
409
+ assert_equal 0, active_record.developers_by_sql(true).size
410
+ end
411
+
412
+ def test_deleting_all
413
+ david = Developer.find(1)
414
+ david.projects.reload
415
+ david.projects.clear
416
+ assert_equal 0, david.projects.size
417
+ assert_equal 0, david.projects(true).size
418
+ end
419
+
420
+ def test_removing_associations_on_destroy
421
+ david = DeveloperWithBeforeDestroyRaise.find(1)
422
+ assert !david.projects.empty?
423
+ assert_nothing_raised { david.destroy }
424
+ assert david.projects.empty?
425
+ assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty?
426
+ end
427
+
428
+ def test_additional_columns_from_join_table
429
+ assert_date_from_db Date.new(2004, 10, 10), Developer.find(1).projects.first.joined_on.to_date
430
+ end
431
+
432
+ def test_destroying
433
+ david = Developer.find(1)
434
+ active_record = Project.find(1)
435
+ david.projects.reload
436
+ assert_equal 2, david.projects.size
437
+ assert_equal 3, active_record.developers.size
438
+
439
+ assert_difference "Project.count", -1 do
440
+ david.projects.destroy(active_record)
441
+ end
442
+
443
+ assert_equal 1, david.reload.projects.size
444
+ assert_equal 1, david.projects(true).size
445
+ end
446
+
447
+ def test_destroying_array
448
+ david = Developer.find(1)
449
+ david.projects.reload
450
+
451
+ assert_difference "Project.count", -Project.count do
452
+ david.projects.destroy(Project.find(:all))
453
+ end
454
+
455
+ assert_equal 0, david.reload.projects.size
456
+ assert_equal 0, david.projects(true).size
457
+ end
458
+
459
+ def test_destroy_all
460
+ david = Developer.find(1)
461
+ david.projects.reload
462
+ assert !david.projects.empty?
463
+ david.projects.destroy_all
464
+ assert david.projects.empty?
465
+ assert david.projects(true).empty?
466
+ end
467
+
468
+ def test_deprecated_push_with_attributes_was_removed
469
+ jamis = developers(:jamis)
470
+ assert_raise(NoMethodError) do
471
+ jamis.projects.push_with_attributes(projects(:action_controller), :joined_on => Date.today)
472
+ end
473
+ end
474
+
475
+ def test_associations_with_conditions
476
+ assert_equal 3, projects(:active_record).developers.size
477
+ assert_equal 1, projects(:active_record).developers_named_david.size
478
+ assert_equal 1, projects(:active_record).developers_named_david_with_hash_conditions.size
479
+
480
+ assert_equal developers(:david), projects(:active_record).developers_named_david.find(developers(:david).id)
481
+ assert_equal developers(:david), projects(:active_record).developers_named_david_with_hash_conditions.find(developers(:david).id)
482
+ assert_equal developers(:david), projects(:active_record).salaried_developers.find(developers(:david).id)
483
+
484
+ projects(:active_record).developers_named_david.clear
485
+ assert_equal 2, projects(:active_record, :reload).developers.size
486
+ end
487
+
488
+ def test_find_in_association
489
+ # Using sql
490
+ assert_equal developers(:david), projects(:active_record).developers.find(developers(:david).id), "SQL find"
491
+
492
+ # Using ruby
493
+ active_record = projects(:active_record)
494
+ active_record.developers.reload
495
+ assert_equal developers(:david), active_record.developers.find(developers(:david).id), "Ruby find"
496
+ end
497
+
498
+ def test_include_uses_array_include_after_loaded
499
+ project = projects(:active_record)
500
+ project.developers.class # force load target
501
+
502
+ developer = project.developers.first
503
+
504
+ assert_no_queries do
505
+ assert project.developers.loaded?
506
+ assert project.developers.include?(developer)
507
+ end
508
+ end
509
+
510
+ def test_include_checks_if_record_exists_if_target_not_loaded
511
+ project = projects(:active_record)
512
+ developer = project.developers.first
513
+
514
+ project.reload
515
+ assert ! project.developers.loaded?
516
+ assert_queries(1) do
517
+ assert project.developers.include?(developer)
518
+ end
519
+ assert ! project.developers.loaded?
520
+ end
521
+
522
+ def test_include_returns_false_for_non_matching_record_to_verify_scoping
523
+ project = projects(:active_record)
524
+ developer = Developer.create :name => "Bryan", :salary => 50_000
525
+
526
+ assert ! project.developers.loaded?
527
+ assert ! project.developers.include?(developer)
528
+ end
529
+
530
+ def test_find_in_association_with_custom_finder_sql
531
+ assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id), "SQL find"
532
+
533
+ active_record = projects(:active_record)
534
+ active_record.developers_with_finder_sql.reload
535
+ assert_equal developers(:david), active_record.developers_with_finder_sql.find(developers(:david).id), "Ruby find"
536
+ end
537
+
538
+ def test_find_in_association_with_custom_finder_sql_and_multiple_interpolations
539
+ # interpolate once:
540
+ assert_equal [developers(:david), developers(:jamis), developers(:poor_jamis)], projects(:active_record).developers_with_finder_sql, "first interpolation"
541
+ # interpolate again, for a different project id
542
+ assert_equal [developers(:david)], projects(:action_controller).developers_with_finder_sql, "second interpolation"
543
+ end
544
+
545
+ def test_find_in_association_with_custom_finder_sql_and_string_id
546
+ assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id.to_s), "SQL find"
547
+ end
548
+
549
+ def test_find_with_merged_options
550
+ assert_equal 1, projects(:active_record).limited_developers.size
551
+ assert_equal 1, projects(:active_record).limited_developers.find(:all).size
552
+ assert_equal 3, projects(:active_record).limited_developers.find(:all, :limit => nil).size
553
+ end
554
+
555
+ def test_dynamic_find_should_respect_association_order
556
+ # Developers are ordered 'name DESC, id DESC'
557
+ low_id_jamis = developers(:jamis)
558
+ middle_id_jamis = developers(:poor_jamis)
559
+ high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
560
+
561
+ assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'")
562
+ assert_equal high_id_jamis, projects(:active_record).developers.find_by_name('Jamis')
563
+ end
564
+
565
+ def test_dynamic_find_order_should_override_association_order
566
+ # Developers are ordered 'name DESC, id DESC'
567
+ low_id_jamis = developers(:jamis)
568
+ middle_id_jamis = developers(:poor_jamis)
569
+ high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
570
+
571
+ assert_equal low_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'", :order => 'id')
572
+ assert_equal low_id_jamis, projects(:active_record).developers.find_by_name('Jamis', :order => 'id')
573
+ end
574
+
575
+ def test_dynamic_find_all_should_respect_association_order
576
+ # Developers are ordered 'name DESC, id DESC'
577
+ low_id_jamis = developers(:jamis)
578
+ middle_id_jamis = developers(:poor_jamis)
579
+ high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
580
+
581
+ assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'")
582
+ assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis')
583
+ end
584
+
585
+ def test_dynamic_find_all_order_should_override_association_order
586
+ # Developers are ordered 'name DESC, id DESC'
587
+ low_id_jamis = developers(:jamis)
588
+ middle_id_jamis = developers(:poor_jamis)
589
+ high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
590
+
591
+ assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'", :order => 'id')
592
+ assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis', :order => 'id')
593
+ end
594
+
595
+ def test_dynamic_find_all_should_respect_association_limit
596
+ assert_equal 1, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'").length
597
+ assert_equal 1, projects(:active_record).limited_developers.find_all_by_name('Jamis').length
598
+ end
599
+
600
+ def test_dynamic_find_all_order_should_override_association_limit
601
+ assert_equal 2, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'", :limit => 9_000).length
602
+ assert_equal 2, projects(:active_record).limited_developers.find_all_by_name('Jamis', :limit => 9_000).length
603
+ end
604
+
605
+ def test_dynamic_find_all_should_respect_readonly_access
606
+ projects(:active_record).readonly_developers.each { |d| assert_raise(ActiveRecord::ReadOnlyRecord) { d.save! } if d.valid?}
607
+ projects(:active_record).readonly_developers.each { |d| d.readonly? }
608
+ end
609
+
610
+ def test_new_with_values_in_collection
611
+ jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis')
612
+ david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
613
+ project = ProjectWithAfterCreateHook.new(:name => "Cooking with Bertie")
614
+ project.developers << jamis
615
+ project.save!
616
+ project.reload
617
+
618
+ assert project.developers.include?(jamis)
619
+ assert project.developers.include?(david)
620
+ end
621
+
622
+ def test_find_in_association_with_options
623
+ developers = projects(:active_record).developers.find(:all)
624
+ assert_equal 3, developers.size
625
+
626
+ assert_equal developers(:poor_jamis), projects(:active_record).developers.find(:first, :conditions => "salary < 10000")
627
+ assert_equal developers(:jamis), projects(:active_record).developers.find(:first, :order => "salary DESC")
628
+ end
629
+
630
+ def test_replace_with_less
631
+ david = developers(:david)
632
+ david.projects = [projects(:action_controller)]
633
+ assert david.save
634
+ assert_equal 1, david.projects.length
635
+ end
636
+
637
+ def test_replace_with_new
638
+ david = developers(:david)
639
+ david.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
640
+ david.save
641
+ assert_equal 2, david.projects.length
642
+ assert !david.projects.include?(projects(:active_record))
643
+ end
644
+
645
+ def test_replace_on_new_object
646
+ new_developer = Developer.new("name" => "Matz")
647
+ new_developer.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
648
+ new_developer.save
649
+ assert_equal 2, new_developer.projects.length
650
+ end
651
+
652
+ def test_consider_type
653
+ developer = Developer.find(:first)
654
+ special_project = SpecialProject.create("name" => "Special Project")
655
+
656
+ other_project = developer.projects.first
657
+ developer.special_projects << special_project
658
+ developer.reload
659
+
660
+ assert developer.projects.include?(special_project)
661
+ assert developer.special_projects.include?(special_project)
662
+ assert !developer.special_projects.include?(other_project)
663
+ end
664
+
665
+ def test_update_attributes_after_push_without_duplicate_join_table_rows
666
+ developer = Developer.new("name" => "Kano")
667
+ project = SpecialProject.create("name" => "Special Project")
668
+ assert developer.save
669
+ developer.projects << project
670
+ developer.update_attribute("name", "Bruza")
671
+ assert_equal 1, Developer.connection.select_value(<<-end_sql).to_i
672
+ SELECT count(*) FROM developers_projects
673
+ WHERE project_id = #{project.id}
674
+ AND developer_id = #{developer.id}
675
+ end_sql
676
+ end
677
+
678
+ def test_updating_attributes_on_non_rich_associations
679
+ welcome = categories(:technology).posts.first
680
+ welcome.title = "Something else"
681
+ assert welcome.save!
682
+ end
683
+
684
+ def test_habtm_respects_select
685
+ categories(:technology).select_testing_posts(true).each do |o|
686
+ assert_respond_to o, :correctness_marker
687
+ end
688
+ assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker
689
+ end
690
+
691
+ def test_updating_attributes_on_rich_associations
692
+ david = projects(:action_controller).developers.first
693
+ david.name = "DHH"
694
+ assert_raise(ActiveRecord::ReadOnlyRecord) { david.save! }
695
+ end
696
+
697
+ def test_updating_attributes_on_rich_associations_with_limited_find_from_reflection
698
+ david = projects(:action_controller).selected_developers.first
699
+ david.name = "DHH"
700
+ assert_nothing_raised { david.save! }
701
+ end
702
+
703
+
704
+ def test_updating_attributes_on_rich_associations_with_limited_find
705
+ david = projects(:action_controller).developers.find(:all, :select => "developers.*").first
706
+ david.name = "DHH"
707
+ assert david.save!
708
+ end
709
+
710
+ def test_join_table_alias
711
+ assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size
712
+ end
713
+
714
+ def test_join_with_group
715
+ group = Developer.columns.inject([]) do |g, c|
716
+ g << "developers.#{c.name}"
717
+ g << "developers_projects_2.#{c.name}"
718
+ end
719
+ Project.columns.each { |c| group << "projects.#{c.name}" }
720
+
721
+ assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => group.join(",")).size
722
+ end
723
+
724
+ def test_find_grouped
725
+ all_posts_from_category1 = Post.find(:all, :conditions => "category_id = 1", :joins => :categories)
726
+ grouped_posts_of_category1 = Post.find(:all, :conditions => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories)
727
+ assert_equal 4, all_posts_from_category1.size
728
+ assert_equal 1, grouped_posts_of_category1.size
729
+ end
730
+
731
+ def test_find_scoped_grouped
732
+ assert_equal 4, categories(:general).posts_gruoped_by_title.size
733
+ assert_equal 1, categories(:technology).posts_gruoped_by_title.size
734
+ end
735
+
736
+ def test_find_scoped_grouped_having
737
+ assert_equal 2, projects(:active_record).well_payed_salary_groups.size
738
+ assert projects(:active_record).well_payed_salary_groups.all? { |g| g.salary > 10000 }
739
+ end
740
+
741
+ def test_get_ids
742
+ assert_equal projects(:active_record, :action_controller).map(&:id).sort, developers(:david).project_ids.sort
743
+ assert_equal [projects(:active_record).id], developers(:jamis).project_ids
744
+ end
745
+
746
+ def test_get_ids_for_loaded_associations
747
+ developer = developers(:david)
748
+ developer.projects(true)
749
+ assert_queries(0) do
750
+ developer.project_ids
751
+ developer.project_ids
752
+ end
753
+ end
754
+
755
+ def test_get_ids_for_unloaded_associations_does_not_load_them
756
+ developer = developers(:david)
757
+ assert !developer.projects.loaded?
758
+ assert_equal projects(:active_record, :action_controller).map(&:id).sort, developer.project_ids.sort
759
+ assert !developer.projects.loaded?
760
+ end
761
+
762
+ def test_assign_ids
763
+ developer = Developer.new("name" => "Joe")
764
+ developer.project_ids = projects(:active_record, :action_controller).map(&:id)
765
+ developer.save
766
+ developer.reload
767
+ assert_equal 2, developer.projects.length
768
+ assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort
769
+ end
770
+
771
+ def test_assign_ids_ignoring_blanks
772
+ developer = Developer.new("name" => "Joe")
773
+ developer.project_ids = [projects(:active_record).id, nil, projects(:action_controller).id, '']
774
+ developer.save
775
+ developer.reload
776
+ assert_equal 2, developer.projects.length
777
+ assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort
778
+ end
779
+
780
+ unless current_adapter?(:IBM_DBAdapter)
781
+ def test_select_limited_ids_list
782
+ # Set timestamps
783
+ Developer.transaction do
784
+ Developer.find(:all, :order => 'id').each_with_index do |record, i|
785
+ record.update_attributes(:created_at => 5.years.ago + (i * 5.minutes))
786
+ end
787
+ end
788
+
789
+ join_base = ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase.new(Project)
790
+ join_dep = ActiveRecord::Associations::ClassMethods::JoinDependency.new(join_base, :developers, nil)
791
+ projects = Project.send(:select_limited_ids_list, {:order => 'developers.created_at'}, join_dep)
792
+ assert !projects.include?("'"), projects
793
+ assert_equal %w(1 2), projects.scan(/\d/).sort
794
+ end
795
+ end
796
+
797
+ def test_scoped_find_on_through_association_doesnt_return_read_only_records
798
+ tag = Post.find(1).tags.find_by_name("General")
799
+
800
+ assert_nothing_raised do
801
+ tag.save!
802
+ end
803
+ end
804
+
805
+ def test_has_many_through_polymorphic_has_manys_works
806
+ assert_equal [10, 20].to_set, pirates(:redbeard).treasure_estimates.map(&:price).to_set
807
+ end
808
+
809
+ def test_symbols_as_keys
810
+ developer = DeveloperWithSymbolsForKeys.new(:name => 'David')
811
+ project = ProjectWithSymbolsForKeys.new(:name => 'Rails Testing')
812
+ project.developers << developer
813
+ project.save!
814
+
815
+ assert_equal 1, project.developers.size
816
+ assert_equal 1, developer.projects.size
817
+ assert_equal developer, project.developers.find(:first)
818
+ assert_equal project, developer.projects.find(:first)
819
+ end
820
+
821
+ def test_self_referential_habtm_without_foreign_key_set_should_raise_exception
822
+ assert_raise(ActiveRecord::HasAndBelongsToManyAssociationForeignKeyNeeded) {
823
+ Member.class_eval do
824
+ has_and_belongs_to_many :friends, :class_name => "Member", :join_table => "member_friends"
825
+ end
826
+ }
827
+ end
828
+
829
+ unless current_adapter?(:IBM_DBAdapter) #refer SQL214n
830
+ def test_dynamic_find_should_respect_association_include
831
+ # SQL error in sort clause if :include is not included
832
+ # due to Unknown column 'authors.id'
833
+ assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title('Welcome to the weblog')
834
+ end
835
+ end
836
+
837
+ def test_counting_on_habtm_association_and_not_array
838
+ david = Developer.find(1)
839
+ # Extra parameter just to make sure we aren't falling back to
840
+ # Array#count in Ruby >=1.8.7, which would raise an ArgumentError
841
+ assert_nothing_raised { david.projects.count(:all, :conditions => '1=1') }
842
+ end
843
+
844
+ def test_count
845
+ david = Developer.find(1)
846
+ assert_equal 2, david.projects.count
847
+ end
848
+
849
+ def test_count_with_counter_sql
850
+ developer = DeveloperWithCounterSQL.create(:name => 'tekin')
851
+ developer.project_ids = [projects(:active_record).id]
852
+ developer.save
853
+ developer.reload
854
+ assert_equal 1, developer.projects.count
855
+ end
856
+
857
+ def test_association_proxy_transaction_method_starts_transaction_in_association_class
858
+ Post.expects(:transaction)
859
+ Category.find(:first).posts.transaction do
860
+ # nothing
861
+ end
862
+ end
863
+
864
+ def test_caching_of_columns
865
+ david = Developer.find(1)
866
+ # clear cache possibly created by other tests
867
+ david.projects.reset_column_information
868
+ assert_queries(0) { david.projects.columns; david.projects.columns }
869
+ # and again to verify that reset_column_information clears the cache correctly
870
+ david.projects.reset_column_information
871
+ assert_queries(0) { david.projects.columns; david.projects.columns }
872
+ end
873
+
874
+ end