activerecord-oracle_enhanced-adapter 1.2.1 → 1.2.2

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 (30) hide show
  1. data/History.txt +34 -0
  2. data/README.rdoc +10 -5
  3. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +1 -1
  4. data/lib/active_record/connection_adapters/oracle_enhanced.rake +4 -0
  5. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +534 -170
  6. data/lib/active_record/connection_adapters/oracle_enhanced_connection.rb +53 -3
  7. data/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb +10 -10
  8. data/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb +3 -3
  9. data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +3 -3
  10. data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +86 -58
  11. data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +105 -68
  12. data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +27 -1
  13. data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +164 -0
  14. data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +122 -0
  15. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +224 -0
  16. data/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb +2 -2
  17. data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +1 -1
  18. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +230 -455
  19. data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +37 -1
  20. data/spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb +1 -1
  21. data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +6 -2
  22. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +21 -4
  23. data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +63 -0
  24. data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +1 -1
  25. data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +1 -3
  26. data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +1 -1
  27. data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +255 -0
  28. data/spec/active_record/connection_adapters/oracle_enhanced_schema_spec.rb +720 -0
  29. data/spec/spec_helper.rb +38 -7
  30. metadata +13 -15
@@ -0,0 +1,720 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe "OracleEnhancedAdapter schema definition" do
4
+ include SchemaSpecHelper
5
+
6
+ before(:all) do
7
+ ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
8
+ @conn = ActiveRecord::Base.connection
9
+ end
10
+
11
+ describe "table and sequence creation with non-default primary key" do
12
+
13
+ before(:all) do
14
+ schema_define do
15
+ create_table :keyboards, :force => true, :id => false do |t|
16
+ t.primary_key :key_number
17
+ t.string :name
18
+ end
19
+ create_table :id_keyboards, :force => true do |t|
20
+ t.string :name
21
+ end
22
+ end
23
+ class ::Keyboard < ActiveRecord::Base
24
+ set_primary_key :key_number
25
+ end
26
+ class ::IdKeyboard < ActiveRecord::Base
27
+ end
28
+ end
29
+
30
+ after(:all) do
31
+ schema_define do
32
+ drop_table :keyboards
33
+ drop_table :id_keyboards
34
+ end
35
+ Object.send(:remove_const, "Keyboard")
36
+ Object.send(:remove_const, "IdKeyboard")
37
+ end
38
+
39
+ it "should create sequence for non-default primary key" do
40
+ ActiveRecord::Base.connection.next_sequence_value(Keyboard.sequence_name).should_not be_nil
41
+ end
42
+
43
+ it "should create sequence for default primary key" do
44
+ ActiveRecord::Base.connection.next_sequence_value(IdKeyboard.sequence_name).should_not be_nil
45
+ end
46
+ end
47
+
48
+ describe "sequence creation parameters" do
49
+
50
+ def create_test_employees_table(sequence_start_value = nil)
51
+ schema_define do
52
+ create_table :test_employees, sequence_start_value ? {:sequence_start_value => sequence_start_value} : {} do |t|
53
+ t.string :first_name
54
+ t.string :last_name
55
+ end
56
+ end
57
+ end
58
+
59
+ def save_default_sequence_start_value
60
+ @saved_sequence_start_value = ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_sequence_start_value
61
+ end
62
+
63
+ def restore_default_sequence_start_value
64
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_sequence_start_value = @saved_sequence_start_value
65
+ end
66
+
67
+ before(:each) do
68
+ save_default_sequence_start_value
69
+ end
70
+ after(:each) do
71
+ restore_default_sequence_start_value
72
+ schema_define do
73
+ drop_table :test_employees
74
+ end
75
+ Object.send(:remove_const, "TestEmployee")
76
+ end
77
+
78
+ it "should use default sequence start value 10000" do
79
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_sequence_start_value.should == 10000
80
+
81
+ create_test_employees_table
82
+ class ::TestEmployee < ActiveRecord::Base; end
83
+
84
+ employee = TestEmployee.create!
85
+ employee.id.should == 10000
86
+ end
87
+
88
+ it "should use specified default sequence start value" do
89
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_sequence_start_value = 1
90
+
91
+ create_test_employees_table
92
+ class ::TestEmployee < ActiveRecord::Base; end
93
+
94
+ employee = TestEmployee.create!
95
+ employee.id.should == 1
96
+ end
97
+
98
+ it "should use sequence start value from table definition" do
99
+ create_test_employees_table(10)
100
+ class ::TestEmployee < ActiveRecord::Base; end
101
+
102
+ employee = TestEmployee.create!
103
+ employee.id.should == 10
104
+ end
105
+
106
+ it "should use sequence start value and other options from table definition" do
107
+ create_test_employees_table("100 NOCACHE INCREMENT BY 10")
108
+ class ::TestEmployee < ActiveRecord::Base; end
109
+
110
+ employee = TestEmployee.create!
111
+ employee.id.should == 100
112
+ employee = TestEmployee.create!
113
+ employee.id.should == 110
114
+ end
115
+
116
+ end
117
+
118
+ describe "create table with primary key trigger" do
119
+ def create_table_with_trigger(options = {})
120
+ options.merge! :primary_key_trigger => true, :force => true
121
+ schema_define do
122
+ create_table :test_employees, options do |t|
123
+ t.string :first_name
124
+ t.string :last_name
125
+ end
126
+ end
127
+ end
128
+
129
+ def create_table_and_separately_trigger(options = {})
130
+ options.merge! :force => true
131
+ schema_define do
132
+ create_table :test_employees, options do |t|
133
+ t.string :first_name
134
+ t.string :last_name
135
+ end
136
+ add_primary_key_trigger :test_employees, options
137
+ end
138
+ end
139
+
140
+ after(:all) do
141
+ seq_name = @sequence_name
142
+ schema_define do
143
+ drop_table :test_employees, (seq_name ? {:sequence_name => seq_name} : {})
144
+ end
145
+ Object.send(:remove_const, "TestEmployee")
146
+ @conn.clear_prefetch_primary_key
147
+ end
148
+
149
+ describe "with default primary key" do
150
+ before(:all) do
151
+ create_table_with_trigger
152
+ class ::TestEmployee < ActiveRecord::Base
153
+ end
154
+ end
155
+
156
+ it "should populate primary key using trigger" do
157
+ lambda do
158
+ @conn.execute "INSERT INTO test_employees (first_name) VALUES ('Raimonds')"
159
+ end.should_not raise_error
160
+ end
161
+
162
+ it "should return new key value using connection insert method" do
163
+ insert_id = @conn.insert("INSERT INTO test_employees (first_name) VALUES ('Raimonds')", nil, "id")
164
+ @conn.select_value("SELECT test_employees_seq.currval FROM dual").should == insert_id
165
+ end
166
+
167
+ it "should create new record for model" do
168
+ e = TestEmployee.create!(:first_name => 'Raimonds')
169
+ @conn.select_value("SELECT test_employees_seq.currval FROM dual").should == e.id
170
+ end
171
+ end
172
+
173
+ describe "with separate creation of primary key trigger" do
174
+ before(:all) do
175
+ create_table_and_separately_trigger
176
+ class ::TestEmployee < ActiveRecord::Base
177
+ end
178
+ end
179
+
180
+ it "should populate primary key using trigger" do
181
+ lambda do
182
+ @conn.execute "INSERT INTO test_employees (first_name) VALUES ('Raimonds')"
183
+ end.should_not raise_error
184
+ end
185
+
186
+ it "should return new key value using connection insert method" do
187
+ insert_id = @conn.insert("INSERT INTO test_employees (first_name) VALUES ('Raimonds')", nil, "id")
188
+ @conn.select_value("SELECT test_employees_seq.currval FROM dual").should == insert_id
189
+ end
190
+
191
+ it "should create new record for model" do
192
+ e = TestEmployee.create!(:first_name => 'Raimonds')
193
+ @conn.select_value("SELECT test_employees_seq.currval FROM dual").should == e.id
194
+ end
195
+ end
196
+
197
+ describe "with non-default primary key and non-default sequence name" do
198
+ before(:all) do
199
+ @primary_key = "employee_id"
200
+ @sequence_name = "test_employees_s"
201
+ create_table_with_trigger(:primary_key => @primary_key, :sequence_name => @sequence_name)
202
+ class ::TestEmployee < ActiveRecord::Base
203
+ set_primary_key "employee_id"
204
+ end
205
+ end
206
+
207
+ it "should populate primary key using trigger" do
208
+ lambda do
209
+ @conn.execute "INSERT INTO test_employees (first_name) VALUES ('Raimonds')"
210
+ end.should_not raise_error
211
+ end
212
+
213
+ it "should return new key value using connection insert method" do
214
+ insert_id = @conn.insert("INSERT INTO test_employees (first_name) VALUES ('Raimonds')", nil, @primary_key)
215
+ @conn.select_value("SELECT #{@sequence_name}.currval FROM dual").should == insert_id
216
+ end
217
+
218
+ it "should create new record for model with autogenerated sequence option" do
219
+ e = TestEmployee.create!(:first_name => 'Raimonds')
220
+ @conn.select_value("SELECT #{@sequence_name}.currval FROM dual").should == e.id
221
+ end
222
+ end
223
+
224
+ describe "with non-default sequence name and non-default trigger name" do
225
+ before(:all) do
226
+ @sequence_name = "test_employees_s"
227
+ create_table_with_trigger(:sequence_name => @sequence_name, :trigger_name => "test_employees_t1")
228
+ class ::TestEmployee < ActiveRecord::Base
229
+ set_sequence_name :autogenerated
230
+ end
231
+ end
232
+
233
+ it "should populate primary key using trigger" do
234
+ lambda do
235
+ @conn.execute "INSERT INTO test_employees (first_name) VALUES ('Raimonds')"
236
+ end.should_not raise_error
237
+ end
238
+
239
+ it "should return new key value using connection insert method" do
240
+ insert_id = @conn.insert("INSERT INTO test_employees (first_name) VALUES ('Raimonds')", nil, "id")
241
+ @conn.select_value("SELECT #{@sequence_name}.currval FROM dual").should == insert_id
242
+ end
243
+
244
+ it "should create new record for model with autogenerated sequence option" do
245
+ e = TestEmployee.create!(:first_name => 'Raimonds')
246
+ @conn.select_value("SELECT #{@sequence_name}.currval FROM dual").should == e.id
247
+ end
248
+ end
249
+
250
+ end
251
+
252
+ describe "table and column comments" do
253
+
254
+ def create_test_employees_table(table_comment=nil, column_comments={})
255
+ schema_define do
256
+ create_table :test_employees, :comment => table_comment do |t|
257
+ t.string :first_name, :comment => column_comments[:first_name]
258
+ t.string :last_name, :comment => column_comments[:last_name]
259
+ end
260
+ end
261
+ end
262
+
263
+ after(:each) do
264
+ schema_define do
265
+ drop_table :test_employees
266
+ end
267
+ Object.send(:remove_const, "TestEmployee")
268
+ ActiveRecord::Base.table_name_prefix = nil
269
+ end
270
+
271
+ it "should create table with table comment" do
272
+ table_comment = "Test Employees"
273
+ create_test_employees_table(table_comment)
274
+ class ::TestEmployee < ActiveRecord::Base; end
275
+
276
+ @conn.table_comment("test_employees").should == table_comment
277
+ TestEmployee.table_comment.should == table_comment
278
+ end
279
+
280
+ it "should create table with columns comment" do
281
+ column_comments = {:first_name => "Given Name", :last_name => "Surname"}
282
+ create_test_employees_table(nil, column_comments)
283
+ class ::TestEmployee < ActiveRecord::Base; end
284
+
285
+ [:first_name, :last_name].each do |attr|
286
+ @conn.column_comment("test_employees", attr.to_s).should == column_comments[attr]
287
+ end
288
+ [:first_name, :last_name].each do |attr|
289
+ TestEmployee.columns_hash[attr.to_s].comment.should == column_comments[attr]
290
+ end
291
+ end
292
+
293
+ it "should create table with table and columns comment and custom table name prefix" do
294
+ ActiveRecord::Base.table_name_prefix = "xxx_"
295
+ table_comment = "Test Employees"
296
+ column_comments = {:first_name => "Given Name", :last_name => "Surname"}
297
+ create_test_employees_table(table_comment, column_comments)
298
+ class ::TestEmployee < ActiveRecord::Base; end
299
+
300
+ @conn.table_comment(TestEmployee.table_name).should == table_comment
301
+ TestEmployee.table_comment.should == table_comment
302
+ [:first_name, :last_name].each do |attr|
303
+ @conn.column_comment(TestEmployee.table_name, attr.to_s).should == column_comments[attr]
304
+ end
305
+ [:first_name, :last_name].each do |attr|
306
+ TestEmployee.columns_hash[attr.to_s].comment.should == column_comments[attr]
307
+ end
308
+ end
309
+
310
+ end
311
+
312
+ describe "create triggers" do
313
+
314
+ before(:all) do
315
+ schema_define do
316
+ create_table :test_employees do |t|
317
+ t.string :first_name
318
+ t.string :last_name
319
+ end
320
+ end
321
+ class ::TestEmployee < ActiveRecord::Base; end
322
+ end
323
+
324
+ after(:all) do
325
+ schema_define do
326
+ drop_table :test_employees
327
+ end
328
+ Object.send(:remove_const, "TestEmployee")
329
+ end
330
+
331
+ it "should create table trigger with :new reference" do
332
+ lambda do
333
+ @conn.execute <<-SQL
334
+ CREATE OR REPLACE TRIGGER test_employees_pkt
335
+ BEFORE INSERT ON test_employees FOR EACH ROW
336
+ BEGIN
337
+ IF inserting THEN
338
+ IF :new.id IS NULL THEN
339
+ SELECT test_employees_seq.NEXTVAL INTO :new.id FROM dual;
340
+ END IF;
341
+ END IF;
342
+ END;
343
+ SQL
344
+ end.should_not raise_error
345
+ end
346
+ end
347
+
348
+ describe "add index" do
349
+
350
+ it "should return default index name if it is not larger than 30 characters" do
351
+ @conn.index_name("employees", :column => "first_name").should == "index_employees_on_first_name"
352
+ end
353
+
354
+ it "should return shortened index name by removing 'index', 'on' and 'and' keywords" do
355
+ @conn.index_name("employees", :column => ["first_name", "email"]).should == "i_employees_first_name_email"
356
+ end
357
+
358
+ it "should return shortened index name by shortening table and column names" do
359
+ @conn.index_name("employees", :column => ["first_name", "last_name"]).should == "i_emp_fir_nam_las_nam"
360
+ end
361
+
362
+ it "should raise error if too large index name cannot be shortened" do
363
+ @conn.index_name("test_employees", :column => ["first_name", "middle_name", "last_name"]).should ==
364
+ 'i'+Digest::SHA1.hexdigest("index_test_employees_on_first_name_and_middle_name_and_last_name")[0,29]
365
+ end
366
+
367
+ end
368
+
369
+ describe "ignore options for LOB columns" do
370
+ after(:each) do
371
+ schema_define do
372
+ drop_table :test_posts
373
+ end
374
+ end
375
+
376
+ it "should ignore :limit option for :text column" do
377
+ lambda do
378
+ schema_define do
379
+ create_table :test_posts, :force => true do |t|
380
+ t.text :body, :limit => 10000
381
+ end
382
+ end
383
+ end.should_not raise_error
384
+ end
385
+
386
+ it "should ignore :limit option for :binary column" do
387
+ lambda do
388
+ schema_define do
389
+ create_table :test_posts, :force => true do |t|
390
+ t.binary :picture, :limit => 10000
391
+ end
392
+ end
393
+ end.should_not raise_error
394
+ end
395
+
396
+ end
397
+
398
+ describe "foreign key constraints" do
399
+ before(:each) do
400
+ schema_define do
401
+ create_table :test_posts, :force => true do |t|
402
+ t.string :title
403
+ end
404
+ create_table :test_comments, :force => true do |t|
405
+ t.string :body, :limit => 4000
406
+ t.references :test_post
407
+ t.integer :post_id
408
+ end
409
+ end
410
+ class ::TestPost < ActiveRecord::Base
411
+ has_many :test_comments
412
+ end
413
+ class ::TestComment < ActiveRecord::Base
414
+ belongs_to :test_post
415
+ end
416
+ end
417
+
418
+ after(:each) do
419
+ Object.send(:remove_const, "TestPost")
420
+ Object.send(:remove_const, "TestComment")
421
+ schema_define do
422
+ drop_table :test_comments rescue nil
423
+ drop_table :test_posts rescue nil
424
+ end
425
+ end
426
+
427
+ it "should add foreign key" do
428
+ schema_define do
429
+ add_foreign_key :test_comments, :test_posts
430
+ end
431
+ lambda do
432
+ TestComment.create(:body => "test", :test_post_id => 1)
433
+ end.should raise_error() {|e| e.message.should =~ /ORA-02291.*\.TEST_COMMENTS_TEST_POST_ID_FK/}
434
+ end
435
+
436
+ it "should add foreign key with name" do
437
+ schema_define do
438
+ add_foreign_key :test_comments, :test_posts, :name => "comments_posts_fk"
439
+ end
440
+ lambda do
441
+ TestComment.create(:body => "test", :test_post_id => 1)
442
+ end.should raise_error() {|e| e.message.should =~ /ORA-02291.*\.COMMENTS_POSTS_FK/}
443
+ end
444
+
445
+ it "should add foreign key with long name which is shortened" do
446
+ schema_define do
447
+ add_foreign_key :test_comments, :test_posts, :name => "test_comments_test_post_id_foreign_key"
448
+ end
449
+ lambda do
450
+ TestComment.create(:body => "test", :test_post_id => 1)
451
+ end.should raise_error() {|e| e.message.should =~ /ORA-02291.*\.TES_COM_TES_POS_ID_FOR_KEY/}
452
+ end
453
+
454
+ it "should add foreign key with very long name which is shortened" do
455
+ schema_define do
456
+ add_foreign_key :test_comments, :test_posts, :name => "long_prefix_test_comments_test_post_id_foreign_key"
457
+ end
458
+ lambda do
459
+ TestComment.create(:body => "test", :test_post_id => 1)
460
+ end.should raise_error() {|e| e.message.should =~
461
+ /ORA-02291.*\.C#{Digest::SHA1.hexdigest("long_prefix_test_comments_test_post_id_foreign_key")[0,29].upcase}/}
462
+ end
463
+
464
+ it "should add foreign key with column" do
465
+ schema_define do
466
+ add_foreign_key :test_comments, :test_posts, :column => "post_id"
467
+ end
468
+ lambda do
469
+ TestComment.create(:body => "test", :post_id => 1)
470
+ end.should raise_error() {|e| e.message.should =~ /ORA-02291.*\.TEST_COMMENTS_POST_ID_FK/}
471
+ end
472
+
473
+ it "should add foreign key with delete dependency" do
474
+ schema_define do
475
+ add_foreign_key :test_comments, :test_posts, :dependent => :delete
476
+ end
477
+ p = TestPost.create(:title => "test")
478
+ c = TestComment.create(:body => "test", :test_post => p)
479
+ TestPost.delete(p.id)
480
+ TestComment.find_by_id(c.id).should be_nil
481
+ end
482
+
483
+ it "should add foreign key with nullify dependency" do
484
+ schema_define do
485
+ add_foreign_key :test_comments, :test_posts, :dependent => :nullify
486
+ end
487
+ p = TestPost.create(:title => "test")
488
+ c = TestComment.create(:body => "test", :test_post => p)
489
+ TestPost.delete(p.id)
490
+ TestComment.find_by_id(c.id).test_post_id.should be_nil
491
+ end
492
+
493
+ it "should remove foreign key by table name" do
494
+ schema_define do
495
+ add_foreign_key :test_comments, :test_posts
496
+ remove_foreign_key :test_comments, :test_posts
497
+ end
498
+ lambda do
499
+ TestComment.create(:body => "test", :test_post_id => 1)
500
+ end.should_not raise_error
501
+ end
502
+
503
+ it "should remove foreign key by constraint name" do
504
+ schema_define do
505
+ add_foreign_key :test_comments, :test_posts, :name => "comments_posts_fk"
506
+ remove_foreign_key :test_comments, :name => "comments_posts_fk"
507
+ end
508
+ lambda do
509
+ TestComment.create(:body => "test", :test_post_id => 1)
510
+ end.should_not raise_error
511
+ end
512
+
513
+ it "should remove foreign key by column name" do
514
+ schema_define do
515
+ add_foreign_key :test_comments, :test_posts
516
+ remove_foreign_key :test_comments, :column => "test_post_id"
517
+ end
518
+ lambda do
519
+ TestComment.create(:body => "test", :test_post_id => 1)
520
+ end.should_not raise_error
521
+ end
522
+
523
+ end
524
+
525
+ describe "foreign key in table definition" do
526
+ before(:each) do
527
+ schema_define do
528
+ create_table :test_posts, :force => true do |t|
529
+ t.string :title
530
+ end
531
+ end
532
+ class ::TestPost < ActiveRecord::Base
533
+ has_many :test_comments
534
+ end
535
+ class ::TestComment < ActiveRecord::Base
536
+ belongs_to :test_post
537
+ end
538
+ end
539
+
540
+ after(:each) do
541
+ Object.send(:remove_const, "TestPost")
542
+ Object.send(:remove_const, "TestComment")
543
+ schema_define do
544
+ drop_table :test_comments rescue nil
545
+ drop_table :test_posts rescue nil
546
+ end
547
+ end
548
+
549
+ it "should add foreign key in create_table" do
550
+ schema_define do
551
+ create_table :test_comments, :force => true do |t|
552
+ t.string :body, :limit => 4000
553
+ t.references :test_post
554
+ t.foreign_key :test_posts
555
+ end
556
+ end
557
+ lambda do
558
+ TestComment.create(:body => "test", :test_post_id => 1)
559
+ end.should raise_error() {|e| e.message.should =~ /ORA-02291/}
560
+ end
561
+
562
+ it "should add foreign key in create_table references" do
563
+ schema_define do
564
+ create_table :test_comments, :force => true do |t|
565
+ t.string :body, :limit => 4000
566
+ t.references :test_post, :foreign_key => true
567
+ end
568
+ end
569
+ lambda do
570
+ TestComment.create(:body => "test", :test_post_id => 1)
571
+ end.should raise_error() {|e| e.message.should =~ /ORA-02291/}
572
+ end
573
+
574
+ it "should add foreign key in change_table" do
575
+ schema_define do
576
+ create_table :test_comments, :force => true do |t|
577
+ t.string :body, :limit => 4000
578
+ t.references :test_post
579
+ end
580
+ change_table :test_comments do |t|
581
+ t.foreign_key :test_posts
582
+ end
583
+ end
584
+ lambda do
585
+ TestComment.create(:body => "test", :test_post_id => 1)
586
+ end.should raise_error() {|e| e.message.should =~ /ORA-02291/}
587
+ end
588
+
589
+ it "should add foreign key in change_table references" do
590
+ schema_define do
591
+ create_table :test_comments, :force => true do |t|
592
+ t.string :body, :limit => 4000
593
+ end
594
+ change_table :test_comments do |t|
595
+ t.references :test_post, :foreign_key => true
596
+ end
597
+ end
598
+ lambda do
599
+ TestComment.create(:body => "test", :test_post_id => 1)
600
+ end.should raise_error() {|e| e.message.should =~ /ORA-02291/}
601
+ end
602
+
603
+ it "should remove foreign key by table name" do
604
+ schema_define do
605
+ create_table :test_comments, :force => true do |t|
606
+ t.string :body, :limit => 4000
607
+ t.references :test_post
608
+ end
609
+ change_table :test_comments do |t|
610
+ t.foreign_key :test_posts
611
+ end
612
+ change_table :test_comments do |t|
613
+ t.remove_foreign_key :test_posts
614
+ end
615
+ end
616
+ lambda do
617
+ TestComment.create(:body => "test", :test_post_id => 1)
618
+ end.should_not raise_error
619
+ end
620
+
621
+ end
622
+
623
+ describe "disable referential integrity" do
624
+ before(:each) do
625
+ schema_define do
626
+ create_table :test_posts, :force => true do |t|
627
+ t.string :title
628
+ end
629
+ create_table :test_comments, :force => true do |t|
630
+ t.string :body, :limit => 4000
631
+ t.references :test_post, :foreign_key => true
632
+ end
633
+ end
634
+ end
635
+
636
+ after(:each) do
637
+ schema_define do
638
+ drop_table :test_comments rescue nil
639
+ drop_table :test_posts rescue nil
640
+ end
641
+ end
642
+
643
+ it "should disable all foreign keys" do
644
+ lambda do
645
+ @conn.execute "INSERT INTO test_comments (id, body, test_post_id) VALUES (1, 'test', 1)"
646
+ end.should raise_error
647
+ @conn.disable_referential_integrity do
648
+ lambda do
649
+ @conn.execute "INSERT INTO test_comments (id, body, test_post_id) VALUES (2, 'test', 2)"
650
+ @conn.execute "INSERT INTO test_posts (id, title) VALUES (2, 'test')"
651
+ end.should_not raise_error
652
+ end
653
+ lambda do
654
+ @conn.execute "INSERT INTO test_comments (id, body, test_post_id) VALUES (3, 'test', 3)"
655
+ end.should raise_error
656
+ end
657
+
658
+ end
659
+
660
+ describe "synonyms" do
661
+ before(:all) do
662
+ @db_link = "db_link"
663
+ @username = @db_link_username = CONNECTION_PARAMS[:username]
664
+ @db_link_password = CONNECTION_PARAMS[:password]
665
+ @db_link_database = CONNECTION_PARAMS[:database]
666
+ @conn.execute "DROP DATABASE LINK #{@db_link}" rescue nil
667
+ @conn.execute "CREATE DATABASE LINK #{@db_link} CONNECT TO #{@db_link_username} IDENTIFIED BY #{@db_link_password} USING '#{@db_link_database}'"
668
+ schema_define do
669
+ create_table :test_posts, :force => true do |t|
670
+ t.string :title
671
+ end
672
+ end
673
+ end
674
+
675
+ after(:all) do
676
+ schema_define do
677
+ drop_table :test_posts
678
+ end
679
+ @conn.execute "DROP DATABASE LINK #{@db_link}" rescue nil
680
+ end
681
+
682
+ before(:each) do
683
+ class ::TestPost < ActiveRecord::Base
684
+ set_table_name "synonym_to_posts"
685
+ end
686
+ end
687
+
688
+ after(:each) do
689
+ Object.send(:remove_const, "TestPost")
690
+ schema_define do
691
+ remove_synonym :synonym_to_posts
692
+ remove_synonym :synonym_to_posts_seq
693
+ end
694
+ end
695
+
696
+ it "should create synonym to table and sequence" do
697
+ schema_name = @username
698
+ schema_define do
699
+ add_synonym :synonym_to_posts, "#{schema_name}.test_posts", :force => true
700
+ add_synonym :synonym_to_posts_seq, "#{schema_name}.test_posts_seq", :force => true
701
+ end
702
+ lambda do
703
+ TestPost.create(:title => "test")
704
+ end.should_not raise_error
705
+ end
706
+
707
+ it "should create synonym to table over database link" do
708
+ db_link = @db_link
709
+ schema_define do
710
+ add_synonym :synonym_to_posts, "test_posts@#{db_link}", :force => true
711
+ add_synonym :synonym_to_posts_seq, "test_posts_seq@#{db_link}", :force => true
712
+ end
713
+ lambda do
714
+ TestPost.create(:title => "test")
715
+ end.should_not raise_error
716
+ end
717
+
718
+ end
719
+
720
+ end