activerecord-oracle_enhanced-adapter 1.4.1 → 1.4.2.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/History.md +16 -1
- data/README.md +60 -35
- data/Rakefile +14 -1
- data/VERSION +1 -1
- data/activerecord-oracle_enhanced-adapter.gemspec +2 -2
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +27 -9
- data/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb +13 -1
- data/lib/active_record/connection_adapters/oracle_enhanced_column.rb +7 -2
- data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +31 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +6 -1
- data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +17 -5
- data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +2 -1
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +29 -11
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +9 -4
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +31 -7
- data/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb +5 -1
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +34 -5
- data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +22 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +1 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +52 -6
- data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +20 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +6 -2
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +79 -21
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +203 -35
- data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +17 -1
- data/spec/spec_helper.rb +3 -1
- metadata +74 -51
@@ -7,6 +7,8 @@ if ActiveRecord::Base.method_defined?(:changed?)
|
|
7
7
|
before(:all) do
|
8
8
|
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
9
9
|
@conn = ActiveRecord::Base.connection
|
10
|
+
@conn.execute "DROP TABLE test_employees" rescue nil
|
11
|
+
@conn.execute "DROP SEQUENCE test_employees_seq" rescue nil
|
10
12
|
@conn.execute <<-SQL
|
11
13
|
CREATE TABLE test_employees (
|
12
14
|
id NUMBER PRIMARY KEY,
|
@@ -116,6 +118,24 @@ if ActiveRecord::Base.method_defined?(:changed?)
|
|
116
118
|
@employee.should_not be_changed
|
117
119
|
end
|
118
120
|
|
121
|
+
it "should not update unchanged CLOBs" do
|
122
|
+
@employee = TestEmployee.create!(
|
123
|
+
:comments => "initial"
|
124
|
+
)
|
125
|
+
@employee.save!.should be_true
|
126
|
+
@employee.reload
|
127
|
+
@employee.comments.should == 'initial'
|
128
|
+
|
129
|
+
oci_conn = @conn.instance_variable_get('@connection')
|
130
|
+
class << oci_conn
|
131
|
+
def write_lob(lob, value, is_binary = false); raise "don't do this'"; end
|
132
|
+
end
|
133
|
+
@employee.save!.should_not raise_exception(RuntimeError, "don't do this'")
|
134
|
+
class << oci_conn
|
135
|
+
remove_method :write_lob
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
119
139
|
end
|
120
140
|
|
121
141
|
end
|
@@ -107,8 +107,12 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
|
|
107
107
|
|
108
108
|
before(:each) do
|
109
109
|
class ::TestEmployee < ActiveRecord::Base
|
110
|
-
|
111
|
-
|
110
|
+
if self.respond_to?(:primary_key=)
|
111
|
+
self.primary_key = :employee_id
|
112
|
+
else
|
113
|
+
set_primary_key :employee_id
|
114
|
+
end
|
115
|
+
|
112
116
|
validates_presence_of :first_name, :last_name, :hire_date
|
113
117
|
|
114
118
|
# should return ID of new record
|
@@ -34,7 +34,7 @@ describe "OracleEnhancedAdapter schema dump" do
|
|
34
34
|
rescue
|
35
35
|
nil
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
describe "tables" do
|
39
39
|
after(:each) do
|
40
40
|
drop_test_posts_table
|
@@ -161,7 +161,7 @@ describe "OracleEnhancedAdapter schema dump" do
|
|
161
161
|
end
|
162
162
|
end
|
163
163
|
end
|
164
|
-
|
164
|
+
|
165
165
|
after(:each) do
|
166
166
|
schema_define do
|
167
167
|
remove_foreign_key :test_comments, :test_posts rescue nil
|
@@ -228,15 +228,15 @@ describe "OracleEnhancedAdapter schema dump" do
|
|
228
228
|
schema_define do
|
229
229
|
add_column :test_posts, :baz_id, :integer
|
230
230
|
add_column :test_posts, :fooz_id, :integer
|
231
|
-
|
231
|
+
|
232
232
|
execute <<-SQL
|
233
|
-
ALTER TABLE TEST_POSTS
|
233
|
+
ALTER TABLE TEST_POSTS
|
234
234
|
ADD CONSTRAINT UK_FOOZ_BAZ UNIQUE (BAZ_ID,FOOZ_ID)
|
235
235
|
SQL
|
236
|
-
|
236
|
+
|
237
237
|
add_column :test_comments, :baz_id, :integer
|
238
238
|
add_column :test_comments, :fooz_id, :integer
|
239
|
-
|
239
|
+
|
240
240
|
add_foreign_key :test_comments, :test_posts, :columns => ["baz_id", "fooz_id"], :name => 'comments_posts_baz_fooz_fk'
|
241
241
|
end
|
242
242
|
standard_dump.should =~ /add_foreign_key "test_comments", "test_posts", :columns => \["baz_id", "fooz_id"\], :name => "comments_posts_baz_fooz_fk"/
|
@@ -300,7 +300,7 @@ describe "OracleEnhancedAdapter schema dump" do
|
|
300
300
|
after(:each) do
|
301
301
|
drop_test_posts_table
|
302
302
|
end
|
303
|
-
|
303
|
+
|
304
304
|
it "should include temporary options" do
|
305
305
|
create_test_posts_table(:temporary => true)
|
306
306
|
standard_dump.should =~ /create_table "test_posts", :temporary => true/
|
@@ -347,34 +347,92 @@ describe "OracleEnhancedAdapter schema dump" do
|
|
347
347
|
|
348
348
|
describe 'virtual columns' do
|
349
349
|
before(:all) do
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
350
|
+
if @oracle11g
|
351
|
+
schema_define do
|
352
|
+
create_table :test_names, :force => true do |t|
|
353
|
+
t.string :first_name
|
354
|
+
t.string :last_name
|
355
|
+
t.virtual :full_name, :as => "first_name || ', ' || last_name"
|
356
|
+
t.virtual :short_name, :as => "COALESCE(first_name, last_name)", :type => :string, :limit => 300
|
357
|
+
t.virtual :abbrev_name, :as => "SUBSTR(first_name,1,50) || ' ' || SUBSTR(last_name,1,1) || '.'", :type => "VARCHAR(100)"
|
358
|
+
t.column :full_name_length, :virtual, :as => "length(first_name || ', ' || last_name)", :type => :integer
|
359
|
+
t.virtual :field_with_leading_space, :as => "' ' || first_name || ' '", :limit => 300, :type => :string
|
360
|
+
end
|
356
361
|
end
|
362
|
+
else
|
363
|
+
pending "Not supported in this database version"
|
357
364
|
end
|
358
365
|
end
|
366
|
+
|
359
367
|
before(:each) do
|
360
|
-
|
361
|
-
|
368
|
+
if @oracle11g
|
369
|
+
class ::TestName < ActiveRecord::Base
|
370
|
+
if self.respond_to?(:table_name=)
|
371
|
+
self.table_name = "test_names"
|
372
|
+
else
|
373
|
+
set_table_name "test_names"
|
374
|
+
end
|
375
|
+
end
|
362
376
|
end
|
363
377
|
end
|
364
378
|
|
365
379
|
after(:all) do
|
366
|
-
|
367
|
-
|
380
|
+
if @oracle11g
|
381
|
+
schema_define do
|
382
|
+
drop_table :test_names
|
383
|
+
end
|
368
384
|
end
|
369
385
|
end
|
370
386
|
|
371
387
|
it 'should dump correctly' do
|
372
|
-
|
373
|
-
standard_dump.should =~ /t
|
388
|
+
standard_dump.should =~ /t\.virtual "full_name",(\s*):limit => 512,(\s*):as => "\\"FIRST_NAME\\"\|\|', '\|\|\\"LAST_NAME\\"",(\s*):type => :string/
|
389
|
+
standard_dump.should =~ /t\.virtual "short_name",(\s*):limit => 300,(\s*):as =>(.*),(\s*):type => :string/
|
390
|
+
standard_dump.should =~ /t\.virtual "full_name_length",(\s*):precision => 38,(\s*):scale => 0,(\s*):as =>(.*),(\s*):type => :integer/
|
391
|
+
standard_dump.should =~ /t\.virtual "abbrev_name",(\s*):limit => 100,(\s*):as =>(.*),(\s*):type => :string/
|
392
|
+
standard_dump.should =~ /t\.virtual "field_with_leading_space",(\s*):limit => 300,(\s*):as => "' '\|\|\\"FIRST_NAME\\"\|\|' '",(\s*):type => :string/
|
374
393
|
end
|
375
394
|
|
376
|
-
|
395
|
+
context 'with column cache' do
|
396
|
+
before(:all) do
|
397
|
+
@old_cache = ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns
|
398
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = true
|
399
|
+
end
|
400
|
+
after(:all) do
|
401
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = @old_cache
|
402
|
+
end
|
403
|
+
it 'should not change column defaults after several dumps' do
|
404
|
+
col = TestName.columns.detect{|c| c.name == 'full_name'}
|
405
|
+
col.should_not be_nil
|
406
|
+
col.virtual_column_data_default.should_not =~ /:as/
|
377
407
|
|
408
|
+
standard_dump
|
409
|
+
col.virtual_column_data_default.should_not =~ /:as/
|
378
410
|
|
379
|
-
|
411
|
+
standard_dump
|
412
|
+
col.virtual_column_data_default.should_not =~ /:as/
|
413
|
+
end
|
414
|
+
end
|
380
415
|
|
416
|
+
context "with index on virtual column" do
|
417
|
+
before(:all) do
|
418
|
+
if @oracle11g
|
419
|
+
schema_define do
|
420
|
+
add_index 'test_names', 'field_with_leading_space', :name => "index_on_virtual_col"
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|
424
|
+
after(:all) do
|
425
|
+
if @oracle11g
|
426
|
+
schema_define do
|
427
|
+
remove_index 'test_names', :name => 'index_on_virtual_col'
|
428
|
+
end
|
429
|
+
end
|
430
|
+
end
|
431
|
+
it 'should dump correctly' do
|
432
|
+
standard_dump.should_not =~ /add_index "test_names".+FIRST_NAME.+$/
|
433
|
+
standard_dump.should =~ /add_index "test_names".+field_with_leading_space.+$/
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
end
|
@@ -22,7 +22,11 @@ describe "OracleEnhancedAdapter schema definition" do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
class ::Keyboard < ActiveRecord::Base
|
25
|
-
|
25
|
+
if self.respond_to?(:primary_key=)
|
26
|
+
self.primary_key = :key_number
|
27
|
+
else
|
28
|
+
set_primary_key :key_number
|
29
|
+
end
|
26
30
|
end
|
27
31
|
class ::IdKeyboard < ActiveRecord::Base
|
28
32
|
end
|
@@ -207,7 +211,7 @@ describe "OracleEnhancedAdapter schema definition" do
|
|
207
211
|
insert_id = @conn.insert("INSERT INTO test_employees (first_name) VALUES ('Raimonds')", nil, "id")
|
208
212
|
@conn.select_value("SELECT test_employees_seq.currval FROM dual").should == insert_id
|
209
213
|
end
|
210
|
-
|
214
|
+
|
211
215
|
it "should create new record for model" do
|
212
216
|
e = TestEmployee.create!(:first_name => 'Raimonds')
|
213
217
|
@conn.select_value("SELECT test_employees_seq.currval FROM dual").should == e.id
|
@@ -222,7 +226,11 @@ describe "OracleEnhancedAdapter schema definition" do
|
|
222
226
|
@sequence_name = "test_employees_s"
|
223
227
|
create_table_with_trigger(:primary_key => @primary_key, :sequence_name => @sequence_name)
|
224
228
|
class ::TestEmployee < ActiveRecord::Base
|
225
|
-
|
229
|
+
if self.respond_to?(:primary_key=)
|
230
|
+
self.primary_key = "employee_id"
|
231
|
+
else
|
232
|
+
set_primary_key "employee_id"
|
233
|
+
end
|
226
234
|
end
|
227
235
|
end
|
228
236
|
|
@@ -254,7 +262,11 @@ describe "OracleEnhancedAdapter schema definition" do
|
|
254
262
|
@sequence_name = "test_employees_s"
|
255
263
|
create_table_with_trigger(:sequence_name => @sequence_name, :trigger_name => "test_employees_t1")
|
256
264
|
class ::TestEmployee < ActiveRecord::Base
|
257
|
-
|
265
|
+
if self.respond_to?(:sequence_name=)
|
266
|
+
self.sequence_name = :autogenerated
|
267
|
+
else
|
268
|
+
set_sequence_name :autogenerated
|
269
|
+
end
|
258
270
|
end
|
259
271
|
end
|
260
272
|
|
@@ -542,7 +554,7 @@ end
|
|
542
554
|
belongs_to :test_post
|
543
555
|
end
|
544
556
|
end
|
545
|
-
|
557
|
+
|
546
558
|
after(:each) do
|
547
559
|
Object.send(:remove_const, "TestPost")
|
548
560
|
Object.send(:remove_const, "TestComment")
|
@@ -618,26 +630,26 @@ end
|
|
618
630
|
TestPost.delete(p.id)
|
619
631
|
TestComment.find_by_id(c.id).test_post_id.should be_nil
|
620
632
|
end
|
621
|
-
|
633
|
+
|
622
634
|
it "should add a composite foreign key" do
|
623
635
|
schema_define do
|
624
636
|
add_column :test_posts, :baz_id, :integer
|
625
637
|
add_column :test_posts, :fooz_id, :integer
|
626
|
-
|
638
|
+
|
627
639
|
execute <<-SQL
|
628
|
-
ALTER TABLE TEST_POSTS
|
640
|
+
ALTER TABLE TEST_POSTS
|
629
641
|
ADD CONSTRAINT UK_FOOZ_BAZ UNIQUE (BAZ_ID,FOOZ_ID)
|
630
642
|
SQL
|
631
|
-
|
643
|
+
|
632
644
|
add_column :test_comments, :baz_id, :integer
|
633
645
|
add_column :test_comments, :fooz_id, :integer
|
634
|
-
|
646
|
+
|
635
647
|
add_foreign_key :test_comments, :test_posts, :columns => ["baz_id", "fooz_id"]
|
636
648
|
end
|
637
|
-
|
649
|
+
|
638
650
|
lambda do
|
639
651
|
TestComment.create(:body => "test", :fooz_id => 1, :baz_id => 1)
|
640
|
-
end.should raise_error() {|e| e.message.should =~
|
652
|
+
end.should raise_error() {|e| e.message.should =~
|
641
653
|
/ORA-02291.*\.TES_COM_BAZ_ID_FOO_ID_FK/}
|
642
654
|
end
|
643
655
|
|
@@ -645,18 +657,18 @@ end
|
|
645
657
|
schema_define do
|
646
658
|
add_column :test_posts, :baz_id, :integer
|
647
659
|
add_column :test_posts, :fooz_id, :integer
|
648
|
-
|
660
|
+
|
649
661
|
execute <<-SQL
|
650
|
-
ALTER TABLE TEST_POSTS
|
662
|
+
ALTER TABLE TEST_POSTS
|
651
663
|
ADD CONSTRAINT UK_FOOZ_BAZ UNIQUE (BAZ_ID,FOOZ_ID)
|
652
664
|
SQL
|
653
|
-
|
665
|
+
|
654
666
|
add_column :test_comments, :baz_id, :integer
|
655
667
|
add_column :test_comments, :fooz_id, :integer
|
656
|
-
|
668
|
+
|
657
669
|
add_foreign_key :test_comments, :test_posts, :columns => ["baz_id", "fooz_id"], :name => 'comments_posts_baz_fooz_fk'
|
658
670
|
end
|
659
|
-
|
671
|
+
|
660
672
|
lambda do
|
661
673
|
TestComment.create(:body => "test", :baz_id => 1, :fooz_id => 1)
|
662
674
|
end.should raise_error() {|e| e.message.should =~ /ORA-02291.*\.COMMENTS_POSTS_BAZ_FOOZ_FK/}
|
@@ -708,7 +720,7 @@ end
|
|
708
720
|
belongs_to :test_post
|
709
721
|
end
|
710
722
|
end
|
711
|
-
|
723
|
+
|
712
724
|
after(:each) do
|
713
725
|
Object.send(:remove_const, "TestPost")
|
714
726
|
Object.send(:remove_const, "TestComment")
|
@@ -862,7 +874,11 @@ end
|
|
862
874
|
|
863
875
|
before(:each) do
|
864
876
|
class ::TestPost < ActiveRecord::Base
|
865
|
-
|
877
|
+
if self.respond_to?(:table_name=)
|
878
|
+
self.table_name = "synonym_to_posts"
|
879
|
+
else
|
880
|
+
set_table_name "synonym_to_posts"
|
881
|
+
end
|
866
882
|
end
|
867
883
|
end
|
868
884
|
|
@@ -918,6 +934,7 @@ end
|
|
918
934
|
schema_define do
|
919
935
|
create_table :test_posts, :force => true do |t|
|
920
936
|
t.string :title, :null => false
|
937
|
+
t.string :content
|
921
938
|
end
|
922
939
|
end
|
923
940
|
class ::TestPost < ActiveRecord::Base; end
|
@@ -979,46 +996,197 @@ end
|
|
979
996
|
TestPost.columns_hash['title'].should be_nil
|
980
997
|
end
|
981
998
|
|
999
|
+
it "should remove column when using change_table" do
|
1000
|
+
schema_define do
|
1001
|
+
change_table :test_posts do |t|
|
1002
|
+
t.remove :title
|
1003
|
+
end
|
1004
|
+
end
|
1005
|
+
TestPost.reset_column_information
|
1006
|
+
TestPost.columns_hash['title'].should be_nil
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
it "should remove multiple columns when using change_table" do
|
1010
|
+
schema_define do
|
1011
|
+
change_table :test_posts do |t|
|
1012
|
+
t.remove :title, :content
|
1013
|
+
end
|
1014
|
+
end
|
1015
|
+
TestPost.reset_column_information
|
1016
|
+
TestPost.columns_hash['title'].should be_nil
|
1017
|
+
TestPost.columns_hash['content'].should be_nil
|
1018
|
+
end
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
describe 'virtual columns in create_table' do
|
1022
|
+
before(:each) do
|
1023
|
+
pending "Not supported in this database version" unless @oracle11g
|
1024
|
+
end
|
1025
|
+
|
1026
|
+
it 'should create virtual column with old syntax' do
|
1027
|
+
schema_define do
|
1028
|
+
create_table :test_fractions, :force => true do |t|
|
1029
|
+
t.integer :field1
|
1030
|
+
t.virtual :field2, :default => 'field1 + 1'
|
1031
|
+
end
|
1032
|
+
end
|
1033
|
+
class ::TestFraction < ActiveRecord::Base
|
1034
|
+
if self.respond_to?(:table_name=)
|
1035
|
+
self.table_name = "test_fractions"
|
1036
|
+
else
|
1037
|
+
set_table_name "test_fractions"
|
1038
|
+
end
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
TestFraction.reset_column_information
|
1042
|
+
tf = TestFraction.columns.detect { |c| c.virtual? }
|
1043
|
+
tf.should_not be nil
|
1044
|
+
tf.name.should == "field2"
|
1045
|
+
tf.virtual?.should be true
|
1046
|
+
lambda do
|
1047
|
+
tf = TestFraction.new(:field1=>10)
|
1048
|
+
tf.field2.should be nil # not whatever is in DATA_DEFAULT column
|
1049
|
+
tf.save!
|
1050
|
+
tf.reload
|
1051
|
+
end.should_not raise_error
|
1052
|
+
tf.field2.to_i.should == 11
|
1053
|
+
|
1054
|
+
schema_define do
|
1055
|
+
drop_table :test_fractions
|
1056
|
+
end
|
1057
|
+
end
|
1058
|
+
|
1059
|
+
it 'should raise error if column expression is not provided' do
|
1060
|
+
lambda {
|
1061
|
+
schema_define do
|
1062
|
+
create_table :test_fractions do |t|
|
1063
|
+
t.integer :field1
|
1064
|
+
t.virtual :field2
|
1065
|
+
end
|
1066
|
+
end
|
1067
|
+
}.should raise_error
|
1068
|
+
end
|
982
1069
|
end
|
983
1070
|
|
984
1071
|
describe 'virtual columns' do
|
985
|
-
before(:
|
986
|
-
|
1072
|
+
before(:each) do
|
1073
|
+
pending "Not supported in this database version" unless @oracle11g
|
1074
|
+
expr = "( numerator/NULLIF(denominator,0) )*100"
|
987
1075
|
schema_define do
|
988
|
-
expr = "( numerator/NULLIF(denominator,0) )*100"
|
989
1076
|
create_table :test_fractions, :force => true do |t|
|
990
1077
|
t.integer :numerator, :default=>0
|
991
1078
|
t.integer :denominator, :default=>0
|
992
|
-
t.virtual :percent, :
|
1079
|
+
t.virtual :percent, :as => expr
|
993
1080
|
end
|
994
1081
|
end
|
995
|
-
end
|
996
|
-
before(:each) do
|
997
1082
|
class ::TestFraction < ActiveRecord::Base
|
998
|
-
|
1083
|
+
if self.respond_to?(:table_name=)
|
1084
|
+
self.table_name = "test_fractions"
|
1085
|
+
else
|
1086
|
+
set_table_name "test_fractions"
|
1087
|
+
end
|
999
1088
|
end
|
1089
|
+
TestFraction.reset_column_information
|
1000
1090
|
end
|
1001
1091
|
|
1002
|
-
after(:
|
1003
|
-
|
1004
|
-
|
1092
|
+
after(:each) do
|
1093
|
+
if @oracle11g
|
1094
|
+
schema_define do
|
1095
|
+
drop_table :test_fractions
|
1096
|
+
end
|
1005
1097
|
end
|
1006
1098
|
end
|
1007
1099
|
|
1008
1100
|
it 'should include virtual columns and not try to update them' do
|
1009
|
-
pending "Not supported in this database version" unless @oracle11g
|
1010
1101
|
tf = TestFraction.columns.detect { |c| c.virtual? }
|
1011
1102
|
tf.should_not be nil
|
1012
1103
|
tf.name.should == "percent"
|
1013
1104
|
tf.virtual?.should be true
|
1014
1105
|
lambda do
|
1015
1106
|
tf = TestFraction.new(:numerator=>20, :denominator=>100)
|
1016
|
-
tf.percent.should
|
1107
|
+
tf.percent.should be nil # not whatever is in DATA_DEFAULT column
|
1017
1108
|
tf.save!
|
1018
1109
|
tf.reload
|
1019
1110
|
end.should_not raise_error
|
1020
1111
|
tf.percent.to_i.should == 20
|
1021
1112
|
end
|
1113
|
+
|
1114
|
+
it 'should add virtual column' do
|
1115
|
+
schema_define do
|
1116
|
+
add_column :test_fractions, :rem, :virtual, :as => 'remainder(numerator, NULLIF(denominator,0))'
|
1117
|
+
end
|
1118
|
+
TestFraction.reset_column_information
|
1119
|
+
tf = TestFraction.columns.detect { |c| c.name == 'rem' }
|
1120
|
+
tf.should_not be nil
|
1121
|
+
tf.virtual?.should be true
|
1122
|
+
lambda do
|
1123
|
+
tf = TestFraction.new(:numerator=>7, :denominator=>5)
|
1124
|
+
tf.rem.should be nil
|
1125
|
+
tf.save!
|
1126
|
+
tf.reload
|
1127
|
+
end.should_not raise_error
|
1128
|
+
tf.rem.to_i.should == 2
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
it 'should add virtual column with explicit type' do
|
1132
|
+
schema_define do
|
1133
|
+
add_column :test_fractions, :expression, :virtual, :as => "TO_CHAR(numerator) || '/' || TO_CHAR(denominator)", :type => :string, :limit => 100
|
1134
|
+
end
|
1135
|
+
TestFraction.reset_column_information
|
1136
|
+
tf = TestFraction.columns.detect { |c| c.name == 'expression' }
|
1137
|
+
tf.should_not be nil
|
1138
|
+
tf.virtual?.should be true
|
1139
|
+
tf.type.should be :string
|
1140
|
+
tf.limit.should be 100
|
1141
|
+
lambda do
|
1142
|
+
tf = TestFraction.new(:numerator=>7, :denominator=>5)
|
1143
|
+
tf.expression.should be nil
|
1144
|
+
tf.save!
|
1145
|
+
tf.reload
|
1146
|
+
end.should_not raise_error
|
1147
|
+
tf.expression.should == '7/5'
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
it 'should change virtual column definition' do
|
1151
|
+
schema_define do
|
1152
|
+
change_column :test_fractions, :percent, :virtual,
|
1153
|
+
:as => "ROUND((numerator/NULLIF(denominator,0))*100, 2)", :type => :decimal, :precision => 15, :scale => 2
|
1154
|
+
end
|
1155
|
+
TestFraction.reset_column_information
|
1156
|
+
tf = TestFraction.columns.detect { |c| c.name == 'percent' }
|
1157
|
+
tf.should_not be nil
|
1158
|
+
tf.virtual?.should be true
|
1159
|
+
tf.type.should be :decimal
|
1160
|
+
tf.precision.should be 15
|
1161
|
+
tf.scale.should be 2
|
1162
|
+
lambda do
|
1163
|
+
tf = TestFraction.new(:numerator=>11, :denominator=>17)
|
1164
|
+
tf.percent.should be nil
|
1165
|
+
tf.save!
|
1166
|
+
tf.reload
|
1167
|
+
end.should_not raise_error
|
1168
|
+
tf.percent.should == '64.71'.to_d
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
it 'should change virtual column type' do
|
1172
|
+
schema_define do
|
1173
|
+
change_column :test_fractions, :percent, :virtual, :type => :decimal, :precision => 12, :scale => 5
|
1174
|
+
end
|
1175
|
+
TestFraction.reset_column_information
|
1176
|
+
tf = TestFraction.columns.detect { |c| c.name == 'percent' }
|
1177
|
+
tf.should_not be nil
|
1178
|
+
tf.virtual?.should be true
|
1179
|
+
tf.type.should be :decimal
|
1180
|
+
tf.precision.should be 12
|
1181
|
+
tf.scale.should be 5
|
1182
|
+
lambda do
|
1183
|
+
tf = TestFraction.new(:numerator=>11, :denominator=>17)
|
1184
|
+
tf.percent.should be nil
|
1185
|
+
tf.save!
|
1186
|
+
tf.reload
|
1187
|
+
end.should_not raise_error
|
1188
|
+
tf.percent.should == '64.70588'.to_d
|
1189
|
+
end
|
1022
1190
|
end
|
1023
1191
|
|
1024
1192
|
describe "miscellaneous options" do
|
@@ -1040,7 +1208,7 @@ end
|
|
1040
1208
|
end
|
1041
1209
|
@conn.instance_eval{ remove_instance_variable :@would_execute_sql }
|
1042
1210
|
end
|
1043
|
-
|
1211
|
+
|
1044
1212
|
it "should support the :options option to create_table" do
|
1045
1213
|
schema_define do
|
1046
1214
|
create_table :test_posts, :options=>'NOLOGGING', :force => true do |t|
|
@@ -1049,7 +1217,7 @@ end
|
|
1049
1217
|
end
|
1050
1218
|
@would_execute_sql.should =~ /CREATE +TABLE .* \(.*\) NOLOGGING/
|
1051
1219
|
end
|
1052
|
-
|
1220
|
+
|
1053
1221
|
it "should support the :tablespace option to create_table" do
|
1054
1222
|
schema_define do
|
1055
1223
|
create_table :test_posts, :tablespace=>'bogus', :force => true do |t|
|
@@ -1085,14 +1253,14 @@ end
|
|
1085
1253
|
@would_execute_sql.should =~ /CREATE +TABLE .*\(.*\)\s+ORGANIZATION INDEX INITRANS 4 COMPRESS 1 TABLESPACE bogus/
|
1086
1254
|
end
|
1087
1255
|
end
|
1088
|
-
|
1256
|
+
|
1089
1257
|
it "should support the :options option to add_index" do
|
1090
1258
|
schema_define do
|
1091
1259
|
add_index :keyboards, :name, :options=>'NOLOGGING'
|
1092
1260
|
end
|
1093
1261
|
@would_execute_sql.should =~ /CREATE +INDEX .* ON .* \(.*\) NOLOGGING/
|
1094
1262
|
end
|
1095
|
-
|
1263
|
+
|
1096
1264
|
it "should support the :tablespace option to add_index" do
|
1097
1265
|
schema_define do
|
1098
1266
|
add_index :keyboards, :name, :tablespace=>'bogus'
|