ibm_db 2.5.6-x86-mswin32-60

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